Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
7400e2a377 |
159 changed files with 4928 additions and 12330 deletions
143
.github/workflows/deploy.yml
vendored
143
.github/workflows/deploy.yml
vendored
|
@ -32,76 +32,75 @@ jobs:
|
||||||
git status
|
git status
|
||||||
false
|
false
|
||||||
fi
|
fi
|
||||||
# deploy:
|
deploy:
|
||||||
# if: "github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'Deploy')"
|
if: "github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'Deploy')"
|
||||||
# runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
# name: Deploy
|
name: Deploy
|
||||||
# steps:
|
steps:
|
||||||
# - uses: actions/checkout@v2.3.4
|
- uses: actions/checkout@v2.3.4
|
||||||
# - name: Notify deployment starting
|
- name: Notify deployment starting
|
||||||
# run: |
|
run: |
|
||||||
# git show --no-patch | curl \
|
git show --no-patch | curl \
|
||||||
# --fail-with-body \
|
--fail-with-body \
|
||||||
# -u "${{ secrets.NTFY_CREDS }}" \
|
-u "${{ secrets.NTFY_CREDS }}" \
|
||||||
# -H "X-Title: Deployment to nki-personal-do started" \
|
-H "X-Title: Deployment to nki-personal-do started" \
|
||||||
# -H "X-Priority: 1" \
|
-H "X-Priority: 1" \
|
||||||
# -H "X-Tags: cloud" \
|
-H "X-Tags: cloud" \
|
||||||
# -H "Actions: view, Open Job on GitHub, ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
|
-H "Actions: view, Open Job on GitHub, ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
|
||||||
# -d "Commit info:
|
-d "Commit info:
|
||||||
# " \
|
" \
|
||||||
# -d @- \
|
-d @- \
|
||||||
# https://ntfy.nkagami.me/nki-personal-do
|
https://ntfy.nkagami.me/nki-personal-do
|
||||||
# - name: Add SSH key
|
- name: Add SSH key
|
||||||
# env:
|
env:
|
||||||
# SSH_AUTH_SOCK: /tmp/ssh_agent.sock
|
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
|
||||||
# run: |
|
run: |
|
||||||
# mkdir -p /home/runner/.ssh
|
mkdir -p /home/runner/.ssh
|
||||||
# echo "${{ secrets.NIX_SECRETS_SSH_KEY }}" > /home/runner/.ssh/nix_secrets_key
|
echo "${{ secrets.NIX_SECRETS_SSH_KEY }}" > /home/runner/.ssh/nix_secrets_key
|
||||||
# echo "${{ secrets.NIX_DEPLOY_SSH_KEY }}" > /home/runner/.ssh/nix_deploy_key
|
echo "${{ secrets.NIX_DEPLOY_SSH_KEY }}" > /home/runner/.ssh/nix_deploy_key
|
||||||
# chmod 600 /home/runner/.ssh/*
|
chmod 600 /home/runner/.ssh/*
|
||||||
# ssh-agent -a $SSH_AUTH_SOCK > /dev/null
|
ssh-agent -a $SSH_AUTH_SOCK > /dev/null
|
||||||
# ssh-add /home/runner/.ssh/*
|
ssh-add /home/runner/.ssh/*
|
||||||
# ssh-keyscan ${{ secrets.INSTANCE_IP }} >> /home/runner/.ssh/known_hosts
|
ssh-keyscan ${{ secrets.INSTANCE_IP }} >> /home/runner/.ssh/known_hosts
|
||||||
# ssh-keyscan git.dtth.ch >> /home/runner/.ssh/known_hosts
|
- uses: cachix/install-nix-action@v20
|
||||||
# - uses: cachix/install-nix-action@v20
|
with:
|
||||||
# with:
|
extra_nix_config: |
|
||||||
# extra_nix_config: |
|
# Enable flakes
|
||||||
# # Enable flakes
|
experimental-features = nix-command flakes
|
||||||
# experimental-features = nix-command flakes
|
# Deploy tokens
|
||||||
# # Deploy tokens
|
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||||
# access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
# Import my substituters
|
||||||
# # Import my substituters
|
extra-substituters = https://natsukagami.cachix.org
|
||||||
# extra-substituters = https://natsukagami.cachix.org
|
extra-trusted-public-keys = natsukagami.cachix.org-1:3U6GV8i8gWEaXRUuXd2S4ASfYgdl2QFPWg4BKPbmYiQ=
|
||||||
# extra-trusted-public-keys = natsukagami.cachix.org-1:3U6GV8i8gWEaXRUuXd2S4ASfYgdl2QFPWg4BKPbmYiQ=
|
- name: Deploy with deploy-rs
|
||||||
# - name: Deploy with deploy-rs
|
env:
|
||||||
# env:
|
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
|
||||||
# SSH_AUTH_SOCK: /tmp/ssh_agent.sock
|
run: |
|
||||||
# run: |
|
nix run .#deploy-rs -- . --hostname ${{ secrets.INSTANCE_IP }} -s -- -L
|
||||||
# nix run .#deploy-rs -- . --hostname ${{ secrets.INSTANCE_IP }} -s -- -L
|
- name: Notify deployment succeeding
|
||||||
# - name: Notify deployment succeeding
|
run: |
|
||||||
# run: |
|
git show --no-patch | curl \
|
||||||
# git show --no-patch | curl \
|
--fail-with-body \
|
||||||
# --fail-with-body \
|
-u "${{ secrets.NTFY_CREDS }}" \
|
||||||
# -u "${{ secrets.NTFY_CREDS }}" \
|
-H "X-Title: Deployment to nki-personal-do succeeded" \
|
||||||
# -H "X-Title: Deployment to nki-personal-do succeeded" \
|
-H "X-Tags: tada,cloud" \
|
||||||
# -H "X-Tags: tada,cloud" \
|
-H "Actions: view, Open Job on GitHub, ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
|
||||||
# -H "Actions: view, Open Job on GitHub, ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
|
-d "Commit info:
|
||||||
# -d "Commit info:
|
" \
|
||||||
# " \
|
-d @- \
|
||||||
# -d @- \
|
https://ntfy.nkagami.me/nki-personal-do
|
||||||
# https://ntfy.nkagami.me/nki-personal-do
|
- name: Notify deployment failing
|
||||||
# - name: Notify deployment failing
|
if: ${{ failure() }}
|
||||||
# if: ${{ failure() }}
|
run: |
|
||||||
# run: |
|
git show --no-patch | curl \
|
||||||
# git show --no-patch | curl \
|
--fail-with-body \
|
||||||
# --fail-with-body \
|
-u "${{ secrets.NTFY_CREDS }}" \
|
||||||
# -u "${{ secrets.NTFY_CREDS }}" \
|
-H "X-Title: Deployment to nki-personal-do failed" \
|
||||||
# -H "X-Title: Deployment to nki-personal-do failed" \
|
-H "X-Priority: 4" \
|
||||||
# -H "X-Priority: 4" \
|
-H "X-Tags: warning,cloud" \
|
||||||
# -H "X-Tags: warning,cloud" \
|
-H "Actions: view, Open Job on GitHub, ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
|
||||||
# -H "Actions: view, Open Job on GitHub, ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
|
-d "Commit info:
|
||||||
# -d "Commit info:
|
" \
|
||||||
# " \
|
-d @- \
|
||||||
# -d @- \
|
https://ntfy.nkagami.me/nki-personal-do
|
||||||
# https://ntfy.nkagami.me/nki-personal-do
|
|
||||||
|
|
||||||
|
|
15
.sops.yaml
15
.sops.yaml
|
@ -4,8 +4,6 @@ keys:
|
||||||
- &nki_pc age1tt0peqg8zdfh74m5sdgwsczcqh036nhgmwvkqnvywll88uvmm9xs433rhm
|
- &nki_pc age1tt0peqg8zdfh74m5sdgwsczcqh036nhgmwvkqnvywll88uvmm9xs433rhm
|
||||||
- &nkagami_main age1n8tnmmgredzltzwkspag7aufhrn6034ny8ysjeulhkwdnf7vqqaqec4mg5
|
- &nkagami_main age1n8tnmmgredzltzwkspag7aufhrn6034ny8ysjeulhkwdnf7vqqaqec4mg5
|
||||||
- &nkagami_do age1z2h24mjt80fryqupajkh3kg5r4sjgw65uqy489xeqxhqj8u2a9fsm3ff36
|
- &nkagami_do age1z2h24mjt80fryqupajkh3kg5r4sjgw65uqy489xeqxhqj8u2a9fsm3ff36
|
||||||
- &nki_yoga age1vhjhmxura35apu5zdwg5ur5r40xay45ld9szh07dy0ph9chgsu7shfm4h9
|
|
||||||
- &nki_framework age188tgu3psvywk6shq85mk2q0jdjwd0tcswzwlwu5pa5n3pndx75dq090z59
|
|
||||||
creation_rules:
|
creation_rules:
|
||||||
- path_regex: kagami-air-m1/secrets\.yaml$
|
- path_regex: kagami-air-m1/secrets\.yaml$
|
||||||
key_groups:
|
key_groups:
|
||||||
|
@ -18,20 +16,9 @@ creation_rules:
|
||||||
- *nki_pc
|
- *nki_pc
|
||||||
- *nkagami_main
|
- *nkagami_main
|
||||||
- *nkagami_do
|
- *nkagami_do
|
||||||
- *nki_framework
|
- path_regex: nki-home/secrets/secrets\.yaml$
|
||||||
- path_regex: nki-home/secrets\.yaml$
|
|
||||||
key_groups:
|
key_groups:
|
||||||
- age:
|
- age:
|
||||||
- *nki_pc
|
- *nki_pc
|
||||||
- *nkagami_main
|
- *nkagami_main
|
||||||
- *nkagami_do
|
- *nkagami_do
|
||||||
- path_regex: nki-yoga-g8/secrets\.yaml$
|
|
||||||
key_groups:
|
|
||||||
- age:
|
|
||||||
- *nki_yoga
|
|
||||||
- age1axvjllyv2gutngwmp3pvp4xtq2gqneldaq2c4nrzmaye0uwmk9lqsealdv # The machine itself
|
|
||||||
- path_regex: nki-framework/secrets\.yaml$
|
|
||||||
key_groups:
|
|
||||||
- age:
|
|
||||||
- *nki_framework
|
|
||||||
- age1vgh6kvee8lvxylm7z86fpl3xzjyjs4u3zdfkyf064rjvxk9fpumsew7n27 # The machine itself
|
|
||||||
|
|
13
cachix.nix
13
cachix.nix
|
@ -1,13 +0,0 @@
|
||||||
# WARN: this file will get overwritten by $ cachix use <name>
|
|
||||||
{ pkgs, lib, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
folder = ./cachix;
|
|
||||||
toImport = name: value: folder + ("/" + name);
|
|
||||||
filterCaches = key: value: value == "regular" && lib.hasSuffix ".nix" key;
|
|
||||||
imports = lib.mapAttrsToList toImport (lib.filterAttrs filterCaches (builtins.readDir folder));
|
|
||||||
in
|
|
||||||
{
|
|
||||||
inherit imports;
|
|
||||||
nix.settings.substituters = [ "https://cache.nixos.org/" ];
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
{
|
|
||||||
nix = {
|
|
||||||
settings = {
|
|
||||||
substituters = [
|
|
||||||
"https://natsukagami.cachix.org"
|
|
||||||
];
|
|
||||||
trusted-public-keys = [
|
|
||||||
"natsukagami.cachix.org-1:3U6GV8i8gWEaXRUuXd2S4ASfYgdl2QFPWg4BKPbmYiQ="
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
29
common.nix
29
common.nix
|
@ -1,18 +1,7 @@
|
||||||
let
|
let
|
||||||
# Default shell
|
# Default shell
|
||||||
defaultShell =
|
defaultShell = { lib, pkgs, config, ... }: with lib; {
|
||||||
{
|
environment.shells = with pkgs; [ bash fish ];
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib;
|
|
||||||
{
|
|
||||||
environment.shells = with pkgs; [
|
|
||||||
bash
|
|
||||||
fish
|
|
||||||
];
|
|
||||||
users.users = mkMerge [
|
users.users = mkMerge [
|
||||||
{ nki.shell = pkgs.bash; }
|
{ nki.shell = pkgs.bash; }
|
||||||
# (mkIf (builtins.hasAttr "natsukagami" config.users.users) { natsukagami.shell = pkgs.fish; })
|
# (mkIf (builtins.hasAttr "natsukagami" config.users.users) { natsukagami.shell = pkgs.fish; })
|
||||||
|
@ -20,18 +9,10 @@ let
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
# Common stuff
|
# Common stuff
|
||||||
{
|
{ lib, pkgs, config, ... }:
|
||||||
lib,
|
with lib; {
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib;
|
|
||||||
{
|
|
||||||
imports = [
|
imports = [
|
||||||
# defaultShell
|
defaultShell
|
||||||
./modules/services/nix-cache
|
|
||||||
./modules/services/nix-build-farm
|
|
||||||
];
|
];
|
||||||
|
|
||||||
## Packages
|
## Packages
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
{
|
{
|
||||||
homebrew.enable = true;
|
homebrew.enable = true;
|
||||||
homebrew.brewPrefix = if pkgs.stdenv.isAarch64 then "/opt/homebrew/bin" else "/usr/local/bin";
|
homebrew.brewPrefix =
|
||||||
|
if pkgs.stdenv.isAarch64 then "/opt/homebrew/bin"
|
||||||
|
else "/usr/local/bin";
|
||||||
homebrew.onActivation.cleanup = "zap";
|
homebrew.onActivation.cleanup = "zap";
|
||||||
homebrew.onActivation.upgrade = true;
|
homebrew.onActivation.upgrade = true;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ config, pkgs, lib, ... }:
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
|
@ -12,10 +7,8 @@
|
||||||
];
|
];
|
||||||
# List packages installed in system profile. To search by name, run:
|
# List packages installed in system profile. To search by name, run:
|
||||||
# $ nix-env -qaP | grep wget
|
# $ nix-env -qaP | grep wget
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages =
|
||||||
podman
|
with pkgs; [ podman qemu ];
|
||||||
qemu
|
|
||||||
];
|
|
||||||
|
|
||||||
environment.shells = with pkgs; [ fish ];
|
environment.shells = with pkgs; [ fish ];
|
||||||
|
|
||||||
|
|
1231
flake.lock
generated
1231
flake.lock
generated
File diff suppressed because it is too large
Load diff
293
flake.nix
293
flake.nix
|
@ -2,58 +2,42 @@
|
||||||
description = "nki's systems";
|
description = "nki's systems";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11";
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.05";
|
||||||
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
||||||
nixos-hardware.url = "github:nixos/nixos-hardware";
|
|
||||||
darwin.url = "github:lnl7/nix-darwin/master";
|
darwin.url = "github:lnl7/nix-darwin/master";
|
||||||
darwin.inputs.nixpkgs.follows = "nixpkgs-unstable";
|
darwin.inputs.nixpkgs.follows = "nixpkgs-unstable";
|
||||||
home-manager.url = "github:nix-community/home-manager/release-24.11";
|
home-manager.url = "github:nix-community/home-manager/release-23.05";
|
||||||
home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
home-manager-unstable.url = "github:nix-community/home-manager";
|
|
||||||
home-manager-unstable.inputs.nixpkgs.follows = "nixpkgs-unstable";
|
|
||||||
sops-nix.url = "github:Mic92/sops-nix";
|
sops-nix.url = "github:Mic92/sops-nix";
|
||||||
sops-nix.inputs.nixpkgs.follows = "nixpkgs-unstable";
|
sops-nix.inputs.nixpkgs.follows = "nixpkgs-unstable";
|
||||||
sops-nix.inputs.nixpkgs-stable.follows = "nixpkgs";
|
sops-nix.inputs.nixpkgs-stable.follows = "nixpkgs";
|
||||||
deploy-rs.url = "github:Serokell/deploy-rs";
|
deploy-rs.url = "github:Serokell/deploy-rs";
|
||||||
|
nur.url = "github:nix-community/NUR";
|
||||||
# --- Secure boot
|
|
||||||
lanzaboote = {
|
|
||||||
url = "github:nix-community/lanzaboote/v0.4.2";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
|
|
||||||
# --- Build tools
|
# --- Build tools
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
flake-utils.url = github:numtide/flake-utils;
|
||||||
crane.url = "github:ipetkov/crane";
|
crane.url = github:ipetkov/crane;
|
||||||
rust-overlay = {
|
arion.url = github:hercules-ci/arion;
|
||||||
url = "github:oxalica/rust-overlay";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
arion.url = "github:hercules-ci/arion/v0.2.2.0";
|
|
||||||
lix-module = {
|
|
||||||
url = "https://git.lix.systems/lix-project/nixos-module/archive/2.92.0.tar.gz";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
|
|
||||||
# ---
|
# ---
|
||||||
# Imported apps
|
# Imported apps
|
||||||
|
rnix-lsp.url = "github:nix-community/rnix-lsp";
|
||||||
youmubot.url = "github:natsukagami/youmubot";
|
youmubot.url = "github:natsukagami/youmubot";
|
||||||
mpd-mpris = {
|
swayfx = {
|
||||||
url = "github:natsukagami/mpd-mpris";
|
url = github:WillPower3309/swayfx;
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
mpd-mpris = {
|
||||||
|
url = github:natsukagami/mpd-mpris/nix;
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
dtth-phanpy.url = "git+ssh://gitea@git.dtth.ch/nki-dtth/phanpy?ref=dtth-fork";
|
|
||||||
conduit.url = "gitlab:famedly/conduit/v0.9.0";
|
|
||||||
nix-gaming.url = "github:fufexan/nix-gaming";
|
|
||||||
zen-browser.url = "github:youwen5/zen-browser-flake";
|
|
||||||
niri.url = "github:sodiboo/niri-flake";
|
|
||||||
|
|
||||||
# --- Sources
|
# --- Sources
|
||||||
kakoune.url = "github:mawww/kakoune";
|
kakoune.url = github:mawww/kakoune;
|
||||||
kakoune.flake = false;
|
kakoune.flake = false;
|
||||||
kak-lsp.url = "github:kakoune-lsp/kakoune-lsp/v18.1.3";
|
kak-lsp.url = github:kak-lsp/kak-lsp;
|
||||||
kak-lsp.flake = false;
|
kak-lsp.flake = false;
|
||||||
nixos-m1.url = "github:tpwrules/nixos-apple-silicon";
|
nixos-m1.url = github:tpwrules/nixos-apple-silicon;
|
||||||
nixos-m1.inputs.nixpkgs.follows = "nixpkgs";
|
nixos-m1.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
|
||||||
# ---
|
# ---
|
||||||
|
@ -61,170 +45,60 @@
|
||||||
secrets.url = "git+ssh://git@github.com/natsukagami/nix-deploy-secrets";
|
secrets.url = "git+ssh://git@github.com/natsukagami/nix-deploy-secrets";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs =
|
outputs = { self, darwin, nixpkgs, nixpkgs-unstable, home-manager, deploy-rs, sops-nix, nur, ... }@inputs:
|
||||||
{
|
|
||||||
self,
|
|
||||||
darwin,
|
|
||||||
nixpkgs,
|
|
||||||
nixpkgs-unstable,
|
|
||||||
home-manager,
|
|
||||||
deploy-rs,
|
|
||||||
sops-nix,
|
|
||||||
...
|
|
||||||
}@inputs:
|
|
||||||
let
|
let
|
||||||
overlays = import ./overlay.nix inputs;
|
overlays = import ./overlay.nix inputs;
|
||||||
lib = nixpkgs.lib;
|
lib = nixpkgs.lib;
|
||||||
|
|
||||||
applyOverlays =
|
applyOverlays = { ... }: {
|
||||||
{ ... }:
|
nixpkgs.overlays = lib.mkBefore overlays;
|
||||||
{
|
|
||||||
nixpkgs.overlays = lib.mkAfter overlays;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
nixpkgsAsRegistry_ =
|
nixpkgsAsRegistry_ = stable: { lib, ... }: {
|
||||||
stable:
|
|
||||||
{ lib, ... }:
|
|
||||||
{
|
|
||||||
imports = [ applyOverlays ];
|
imports = [ applyOverlays ];
|
||||||
nix.registry.current-system.flake = self;
|
nix.registry.current-system.flake = self;
|
||||||
|
nix.registry.nixpkgs.flake = stable;
|
||||||
nix.registry.nixpkgs-unstable.flake = nixpkgs-unstable;
|
nix.registry.nixpkgs-unstable.flake = nixpkgs-unstable;
|
||||||
nixpkgs.config.allowUnfree = true;
|
nixpkgs.config.allowUnfree = true;
|
||||||
nix.nixPath = lib.mkDefault [
|
nix.nixPath = [
|
||||||
|
"nixpkgs=${nixpkgs}"
|
||||||
"nixpkgs-unstable=${nixpkgs-unstable}"
|
"nixpkgs-unstable=${nixpkgs-unstable}"
|
||||||
|
"/nix/var/nix/profiles/per-user/root/channels"
|
||||||
|
];
|
||||||
|
# Binary Cache for Haskell.nix
|
||||||
|
nix.settings.trusted-public-keys = [
|
||||||
|
"hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ="
|
||||||
|
];
|
||||||
|
nix.settings.substituters = [
|
||||||
|
"https://cache.iog.io"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
nixpkgsAsRegistry = nixpkgsAsRegistry_ nixpkgs;
|
||||||
osuStable =
|
|
||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
nix.settings = {
|
|
||||||
substituters = [ "https://nix-gaming.cachix.org" ];
|
|
||||||
trusted-public-keys = [ "nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4=" ];
|
|
||||||
};
|
|
||||||
environment.systemPackages = [ inputs.nix-gaming.packages.${pkgs.hostPlatform.system}.osu-stable ];
|
|
||||||
programs.gamemode = {
|
|
||||||
enable = true;
|
|
||||||
enableRenice = true;
|
|
||||||
settings = {
|
|
||||||
general = {
|
|
||||||
renice = 10;
|
|
||||||
};
|
|
||||||
|
|
||||||
custom = {
|
|
||||||
start = "${pkgs.libnotify}/bin/notify-send 'GameMode started'";
|
|
||||||
end = "${pkgs.libnotify}/bin/notify-send 'GameMode ended'";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Common Nix modules
|
# Common Nix modules
|
||||||
common-nix =
|
common-nix = stable: { ... }: {
|
||||||
stable:
|
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
imports = [
|
imports = [
|
||||||
(nixpkgsAsRegistry_ stable)
|
(nixpkgsAsRegistry_ stable)
|
||||||
./common.nix
|
./common.nix
|
||||||
sops-nix.nixosModules.sops
|
sops-nix.nixosModules.sops
|
||||||
inputs.lix-module.nixosModules.default
|
|
||||||
];
|
];
|
||||||
config.nix.settings.extra-deprecated-features = [ "url-literals" ]; # So lix won't complain
|
|
||||||
};
|
};
|
||||||
common-nixos =
|
common-nixos = stable: { ... }: {
|
||||||
stable:
|
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
imports = [
|
imports = [
|
||||||
./modules/my-tinc
|
./modules/my-tinc
|
||||||
./modules/common/linux
|
./modules/common/linux
|
||||||
(common-nix stable)
|
(common-nix stable)
|
||||||
inputs.secrets.nixosModules.common
|
inputs.secrets.nixosModules.common
|
||||||
inputs.nix-gaming.nixosModules.pipewireLowLatency
|
|
||||||
inputs.niri.nixosModules.niri
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
mkPersonalSystem =
|
|
||||||
nixpkgs-module: system:
|
|
||||||
{
|
|
||||||
configuration,
|
|
||||||
homeManagerUsers ? { },
|
|
||||||
extraModules ? [ ],
|
|
||||||
includeCommonModules ? true,
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
home-manager-module =
|
|
||||||
if nixpkgs-module == inputs.nixpkgs then
|
|
||||||
inputs.home-manager
|
|
||||||
else if nixpkgs-module == inputs.nixpkgs-unstable then
|
|
||||||
inputs.home-manager-unstable
|
|
||||||
else
|
|
||||||
builtins.abort "Unknown nixpkgs module, use `nixpkgs` or `nixpkgs-unstable`";
|
|
||||||
in
|
|
||||||
nixpkgs-module.lib.nixosSystem {
|
|
||||||
inherit system;
|
|
||||||
modules =
|
|
||||||
(
|
|
||||||
if includeCommonModules then
|
|
||||||
[
|
|
||||||
(common-nixos nixpkgs-module)
|
|
||||||
]
|
|
||||||
else
|
|
||||||
[ ]
|
|
||||||
)
|
|
||||||
++ [
|
|
||||||
configuration
|
|
||||||
# Home Manager
|
|
||||||
home-manager-module.nixosModules.home-manager
|
|
||||||
{
|
|
||||||
home-manager.useGlobalPkgs = true;
|
|
||||||
home-manager.useUserPackages = true;
|
|
||||||
home-manager.users = homeManagerUsers;
|
|
||||||
}
|
|
||||||
]
|
|
||||||
++ extraModules;
|
|
||||||
};
|
|
||||||
|
|
||||||
kakoune-unwrapped-from-pkgs =
|
|
||||||
pkgs:
|
|
||||||
pkgs.kakoune-unwrapped.overrideAttrs (attrs: {
|
|
||||||
version = "r${builtins.substring 0 6 inputs.kakoune.rev}";
|
|
||||||
src = inputs.kakoune;
|
|
||||||
patches = [
|
|
||||||
# patches in the original package was already applied
|
|
||||||
];
|
|
||||||
});
|
|
||||||
nki-kakoune-from-pkgs =
|
|
||||||
pkgs:
|
|
||||||
pkgs.callPackage ./packages/common/nki-kakoune {
|
|
||||||
kakoune-unwrapped = kakoune-unwrapped-from-pkgs pkgs;
|
|
||||||
};
|
|
||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
overlays = {
|
overlays.default = lib.composeManyExtensions overlays;
|
||||||
default = lib.composeManyExtensions overlays;
|
|
||||||
kakoune = final: prev: {
|
|
||||||
kakoune-unwrapped = kakoune-unwrapped-from-pkgs prev;
|
|
||||||
nki-kakoune = final.callPackage ./packages/common/nki-kakoune { };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
packages.x86_64-linux.deploy-rs = deploy-rs.packages.x86_64-linux.default;
|
packages.x86_64-linux.deploy-rs = deploy-rs.packages.x86_64-linux.default;
|
||||||
apps.x86_64-linux.deploy-rs = deploy-rs.apps.x86_64-linux.default;
|
apps.x86_64-linux.deploy-rs = deploy-rs.apps.x86_64-linux.default;
|
||||||
|
|
||||||
packages.x86_64-linux.nki-kakoune = nki-kakoune-from-pkgs (
|
|
||||||
import nixpkgs-unstable { system = "x86_64-linux"; }
|
|
||||||
);
|
|
||||||
packages.aarch64-linux.nki-kakoune = nki-kakoune-from-pkgs (
|
|
||||||
import nixpkgs-unstable { system = "aarch64-linux"; }
|
|
||||||
);
|
|
||||||
packages.aarch64-darwin.nki-kakoune = nki-kakoune-from-pkgs (
|
|
||||||
import nixpkgs-unstable { system = "aarch64-darwin"; }
|
|
||||||
);
|
|
||||||
|
|
||||||
# MacBook configuration: nix-darwin + home-manager
|
# MacBook configuration: nix-darwin + home-manager
|
||||||
darwinConfigurations."nki-macbook" = darwin.lib.darwinSystem rec {
|
darwinConfigurations."nki-macbook" = darwin.lib.darwinSystem rec {
|
||||||
system = "aarch64-darwin";
|
system = "aarch64-darwin";
|
||||||
|
@ -241,68 +115,67 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
# Home configuration
|
# Home configuration
|
||||||
nixosConfigurations."kagamiPC" = mkPersonalSystem nixpkgs-unstable "x86_64-linux" {
|
nixosConfigurations."nki-home" = nixpkgs.lib.nixosSystem rec {
|
||||||
configuration = ./nki-home/configuration.nix;
|
system = "x86_64-linux";
|
||||||
homeManagerUsers.nki = import ./home/kagami-pc-home.nix;
|
modules = [
|
||||||
extraModules = [ osuStable ];
|
(common-nixos nixpkgs)
|
||||||
};
|
./nki-home/configuration.nix
|
||||||
# yoga g8 configuration
|
inputs.home-manager.nixosModules.home-manager
|
||||||
nixosConfigurations."nki-yoga-g8" = mkPersonalSystem nixpkgs "x86_64-linux" {
|
|
||||||
configuration = ./nki-yoga-g8/configuration.nix;
|
|
||||||
homeManagerUsers.nki = import ./home/nki-x1c1.nix;
|
|
||||||
extraModules = [
|
|
||||||
inputs.lanzaboote.nixosModules.lanzaboote
|
|
||||||
(
|
|
||||||
{ ... }:
|
|
||||||
{
|
{
|
||||||
# Sets up secure boot
|
home-manager.useGlobalPkgs = true;
|
||||||
boot.loader.systemd-boot.enable = lib.mkForce false;
|
home-manager.useUserPackages = true;
|
||||||
boot.lanzaboote = {
|
home-manager.users.nki = { ... }: {
|
||||||
enable = true;
|
imports = [
|
||||||
pkiBundle = "/etc/secureboot";
|
./home/kagami-pc-home.nix
|
||||||
};
|
|
||||||
}
|
|
||||||
)
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
# framework configuration
|
|
||||||
nixosConfigurations."nki-framework" = mkPersonalSystem nixpkgs-unstable "x86_64-linux" {
|
|
||||||
configuration = ./nki-framework/configuration.nix;
|
|
||||||
homeManagerUsers.nki = import ./home/nki-framework.nix;
|
|
||||||
extraModules = [
|
|
||||||
inputs.lanzaboote.nixosModules.lanzaboote
|
|
||||||
inputs.nixos-hardware.nixosModules.framework-13-7040-amd
|
|
||||||
(
|
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
# Sets up secure boot
|
|
||||||
boot.loader.systemd-boot.enable = lib.mkForce false;
|
|
||||||
boot.lanzaboote = {
|
|
||||||
enable = true;
|
|
||||||
pkiBundle = "/etc/secureboot";
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
)
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
# x1c1 configuration
|
||||||
|
# nixosConfigurations."nki-x1c1" = nixpkgs.lib.nixosSystem rec {
|
||||||
|
# system = "x86_64-linux";
|
||||||
|
# modules = [
|
||||||
|
# (common-nixos nixpkgs)
|
||||||
|
# ./nki-x1c1/configuration.nix
|
||||||
|
# home-manager.nixosModules.home-manager
|
||||||
|
# {
|
||||||
|
# home-manager.useGlobalPkgs = true;
|
||||||
|
# home-manager.useUserPackages = true;
|
||||||
|
# home-manager.users.nki = import ./home/nki-x1c1.nix;
|
||||||
|
# }
|
||||||
|
# ];
|
||||||
|
# };
|
||||||
# macbook nixos
|
# macbook nixos
|
||||||
nixosConfigurations."kagami-air-m1" = mkPersonalSystem nixpkgs "aarch64-linux" {
|
nixosConfigurations."kagami-air-m1" = inputs.nixpkgs.lib.nixosSystem rec {
|
||||||
configuration = ./kagami-air-m1/configuration.nix;
|
system = "aarch64-linux";
|
||||||
homeManagerUsers.nki = import ./home/macbook-nixos.nix;
|
modules = [
|
||||||
extraModules = [ inputs.nixos-m1.nixosModules.apple-silicon-support ];
|
(common-nixos inputs.nixpkgs)
|
||||||
|
inputs.nixos-m1.nixosModules.apple-silicon-support
|
||||||
|
./kagami-air-m1/configuration.nix
|
||||||
|
inputs.home-manager.nixosModules.home-manager
|
||||||
|
{
|
||||||
|
home-manager.useGlobalPkgs = true;
|
||||||
|
home-manager.useUserPackages = true;
|
||||||
|
home-manager.users.nki = import ./home/macbook-nixos.nix;
|
||||||
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
# DigitalOcean node
|
# DigitalOcean node
|
||||||
nixosConfigurations."nki-personal-do" = mkPersonalSystem nixpkgs "x86_64-linux" {
|
nixosConfigurations."nki-personal-do" = nixpkgs.lib.nixosSystem rec {
|
||||||
configuration = ./nki-personal-do/configuration.nix;
|
system = "x86_64-linux";
|
||||||
extraModules = [
|
modules = [
|
||||||
|
(common-nixos nixpkgs)
|
||||||
inputs.arion.nixosModules.arion
|
inputs.arion.nixosModules.arion
|
||||||
|
./modules/my-tinc
|
||||||
inputs.youmubot.nixosModules.default
|
inputs.youmubot.nixosModules.default
|
||||||
|
./nki-personal-do/configuration.nix
|
||||||
inputs.secrets.nixosModules.nki-personal-do
|
inputs.secrets.nixosModules.nki-personal-do
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
deploy.nodes."nki-personal-do" = {
|
deploy.nodes."nki-personal-do" = {
|
||||||
hostname = "nki.personal";
|
hostname = "nki-personal-do";
|
||||||
sshUser = "root";
|
sshUser = "root";
|
||||||
profiles.system = {
|
profiles.system = {
|
||||||
user = "root";
|
user = "root";
|
||||||
|
@ -312,8 +185,8 @@
|
||||||
|
|
||||||
# This is highly advised, and will prevent many possible mistakes
|
# This is highly advised, and will prevent many possible mistakes
|
||||||
checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib;
|
checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib;
|
||||||
}
|
|
||||||
// (inputs.flake-utils.lib.eachDefaultSystem (system: {
|
} // (inputs.flake-utils.lib.eachDefaultSystem (system: {
|
||||||
formatter = nixpkgs.legacyPackages.${system}.nixfmt-rfc-style;
|
formatter = nixpkgs.legacyPackages.${system}.nixpkgs-fmt;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,70 +1,50 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
with lib; {
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib;
|
|
||||||
let
|
|
||||||
kwallet =
|
|
||||||
{ pkgs, lib, ... }:
|
|
||||||
{
|
|
||||||
home.packages = with pkgs; [
|
|
||||||
kdePackages.kwallet
|
|
||||||
kdePackages.ksshaskpass
|
|
||||||
];
|
|
||||||
home.sessionVariables = {
|
|
||||||
# https://wiki.archlinux.org/title/KDE_Wallet#Using_the_KDE_Wallet_to_store_ssh_key_passphrases
|
|
||||||
SSH_ASKPASS = lib.getExe pkgs.kdePackages.ksshaskpass;
|
|
||||||
SSH_ASKPASS_REQUIRE = "prefer";
|
|
||||||
};
|
|
||||||
# Enable this for sway
|
|
||||||
wayland.windowManager.sway.config.startup = [
|
|
||||||
{ command = "${pkgs.kdePackages.kwallet-pam}/libexec/pam_kwallet_init"; }
|
|
||||||
];
|
|
||||||
# Automatic dbus activation
|
|
||||||
xdg.dataFile."dbus-1/services/org.freedesktop.secrets.service".text = ''
|
|
||||||
[D-BUS Service]
|
|
||||||
Name=org.freedesktop.secrets
|
|
||||||
Exec=${pkgs.kdePackages.kwallet}/bin/kwalletd6
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
imports = [
|
imports = [
|
||||||
./modules/monitors.nix
|
|
||||||
./modules/linux/graphical
|
./modules/linux/graphical
|
||||||
./modules/X11/xfce4-notifyd.nix
|
./modules/X11/xfce4-notifyd.nix
|
||||||
kwallet
|
./modules/programs/discord.nix
|
||||||
];
|
];
|
||||||
config = (
|
config = (mkIf pkgs.stdenv.isLinux {
|
||||||
mkIf pkgs.stdenv.isLinux {
|
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
psmisc # killall and friends
|
psmisc # killall and friends
|
||||||
file # Query file type
|
file # Query file type
|
||||||
zip
|
|
||||||
python3
|
|
||||||
|
|
||||||
pinentry-gnome3 # until pinentry-qt introduces caching
|
pinentry-gnome
|
||||||
|
] ++ (
|
||||||
|
if pkgs.stdenv.isx86_64
|
||||||
|
then [
|
||||||
|
vivaldi
|
||||||
|
mpv # for anki
|
||||||
|
pkgs.unstable.anki-bin
|
||||||
|
|
||||||
|
tdesktop
|
||||||
|
whatsapp-for-linux
|
||||||
|
]
|
||||||
|
else [ ]
|
||||||
|
);
|
||||||
|
|
||||||
|
## Gnome-keyring
|
||||||
|
services.gnome-keyring = {
|
||||||
|
enable = true;
|
||||||
|
components = [ "pkcs11" "secrets" "ssh" ];
|
||||||
|
};
|
||||||
|
# services.gpg-agent.enable = true;
|
||||||
|
# services.gpg-agent.pinentryFlavor = "curses";
|
||||||
|
# services.gpg-agent.enableSshSupport = true;
|
||||||
|
|
||||||
|
# Git "safe-directory"
|
||||||
|
programs.git.extraConfig.safe.directory = [
|
||||||
|
"${config.home.homeDirectory}/.config/nixpkgs"
|
||||||
];
|
];
|
||||||
|
|
||||||
systemd.user.startServices = "sd-switch";
|
systemd.user.startServices = "sd-switch";
|
||||||
|
|
||||||
# Audio stuff!
|
|
||||||
# services.easyeffects.enable = true;
|
|
||||||
|
|
||||||
# Bluetooth controls
|
# Bluetooth controls
|
||||||
# services.mpris-proxy.enable = true;
|
services.mpris-proxy.enable = true;
|
||||||
|
|
||||||
# Owncloud
|
# Owncloud
|
||||||
services.owncloud-client.enable = true;
|
services.owncloud-client.enable = true;
|
||||||
services.owncloud-client.package = pkgs.owncloud-client.overrideAttrs (attrs: {
|
|
||||||
buildInputs = attrs.buildInputs ++ [ pkgs.qt6.qtwayland ];
|
|
||||||
});
|
});
|
||||||
systemd.user.services.owncloud-client.Unit.After = [ "graphical-session.target" ];
|
}
|
||||||
|
|
||||||
# UDisks automounter
|
|
||||||
services.udiskie.enable = true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,48 +1,72 @@
|
||||||
{
|
{ config, pkgs, lib, ... }:
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
|
let
|
||||||
|
texlab = pkgs.unstable.texlab;
|
||||||
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./kakoune.nix
|
./kakoune/kak.nix
|
||||||
./fish/fish.nix
|
./fish/fish.nix
|
||||||
./modules/programs/my-broot.nix
|
./modules/programs/my-broot.nix
|
||||||
./modules/programs/my-waybar.nix
|
|
||||||
./modules/programs/my-sway
|
./modules/programs/my-sway
|
||||||
./modules/programs/my-niri.nix
|
|
||||||
./modules/programs/my-kitty
|
./modules/programs/my-kitty
|
||||||
./modules/programs/openconnect-epfl.nix
|
./modules/programs/openconnect-epfl.nix
|
||||||
./common-linux.nix
|
./common-linux.nix
|
||||||
|
|
||||||
|
# PATH Overrides
|
||||||
|
({ config, lib, ... }: {
|
||||||
|
home.sessionPath = lib.mkBefore [
|
||||||
|
"${config.home.homeDirectory}/.bin/overrides"
|
||||||
|
];
|
||||||
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
# Let Home Manager install and manage itself.
|
# Let Home Manager install and manage itself.
|
||||||
programs.home-manager.enable = true;
|
programs.home-manager.enable = true;
|
||||||
|
|
||||||
# Temporarily disable the manuals
|
# Enable the manual so we don't have to load it
|
||||||
manual.html.enable = false;
|
manual.html.enable = true;
|
||||||
# manual.manpage.enable = false;
|
|
||||||
|
|
||||||
# Packages that are not in programs section
|
# Packages that are not in programs section
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
|
# Build Tools
|
||||||
|
## C++
|
||||||
|
autoconf
|
||||||
|
automake
|
||||||
|
## SQL
|
||||||
|
flyway
|
||||||
|
## Go
|
||||||
|
go # to be configured later
|
||||||
|
## Rust
|
||||||
|
rust-analyzer
|
||||||
|
## JavaScript
|
||||||
|
yarn
|
||||||
|
## Nix
|
||||||
|
cachix
|
||||||
|
rnix-lsp
|
||||||
|
## Latex
|
||||||
|
tectonic
|
||||||
|
texlab
|
||||||
|
## Typst
|
||||||
|
typst
|
||||||
|
## Python
|
||||||
|
python3
|
||||||
|
|
||||||
|
# Fonts
|
||||||
|
fantasque-sans-mono
|
||||||
|
## Get the nerd font symbols
|
||||||
|
(nerdfonts.override { fonts = [ "NerdFontsSymbolsOnly" ]; })
|
||||||
|
|
||||||
# CLI tools
|
# CLI tools
|
||||||
fd
|
fd
|
||||||
sd
|
|
||||||
ripgrep
|
ripgrep
|
||||||
|
fossil
|
||||||
openssh
|
openssh
|
||||||
tea # gitea CLI (gh-like)
|
tea # gitea CLI (gh-like)
|
||||||
glab # gitlab CLI
|
## File Manager
|
||||||
fx # JSON viewer
|
nnn
|
||||||
glow # Markdown viewer
|
|
||||||
nix-output-monitor # Nice nix output formatting
|
|
||||||
unstable.scala-next
|
|
||||||
## PDF Processors
|
## PDF Processors
|
||||||
poppler_utils
|
poppler_utils
|
||||||
# TeX
|
|
||||||
texlive.combined.scheme-full
|
|
||||||
inkscape # for TeX svg
|
|
||||||
## htop replacement
|
## htop replacement
|
||||||
htop-vim
|
htop-vim
|
||||||
## Bitwarden
|
## Bitwarden
|
||||||
|
@ -52,10 +76,14 @@
|
||||||
unzip
|
unzip
|
||||||
zstd
|
zstd
|
||||||
atool
|
atool
|
||||||
|
|
||||||
|
## To do tunneling with cloudflare
|
||||||
|
pkgs.cloudflared
|
||||||
|
|
||||||
|
# Databases
|
||||||
|
postgresql
|
||||||
|
mariadb
|
||||||
];
|
];
|
||||||
home.file.".latexmkrc".text = ''
|
|
||||||
$pdf_previewer = '${lib.getExe' pkgs.xdg-utils "xdg-open"}';
|
|
||||||
'';
|
|
||||||
|
|
||||||
home.sessionVariables = {
|
home.sessionVariables = {
|
||||||
# Bat theme
|
# Bat theme
|
||||||
|
@ -84,9 +112,9 @@
|
||||||
direnv.nix-direnv.enable = true;
|
direnv.nix-direnv.enable = true;
|
||||||
direnv.config.global.load_dotenv = true;
|
direnv.config.global.load_dotenv = true;
|
||||||
|
|
||||||
eza = {
|
exa = {
|
||||||
enable = true;
|
enable = true;
|
||||||
enableFishIntegration = true;
|
enableAliases = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
fzf = {
|
fzf = {
|
||||||
|
@ -118,8 +146,6 @@
|
||||||
.envrc
|
.envrc
|
||||||
.kakrc
|
.kakrc
|
||||||
''}";
|
''}";
|
||||||
safe.directory = "*";
|
|
||||||
merge.conflictstyle = "zdiff3";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
{
|
{
|
||||||
allowUnfree = true;
|
allowUnfree = true;
|
||||||
|
packageOverrides = pkgs: {
|
||||||
|
nur = import (builtins.fetchTarball "https://github.com/nix-community/NUR/archive/master.tar.gz") {
|
||||||
|
inherit pkgs;
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,48 +1,9 @@
|
||||||
{
|
{ config, pkgs, lib, ... }:
|
||||||
config,
|
|
||||||
options,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
|
||||||
bootDesktop = pkgs.writeScript "boot-desktop" ''
|
|
||||||
#!/usr/bin/env fish
|
|
||||||
|
|
||||||
set -a PATH ${pkgs.gum}/bin
|
|
||||||
|
|
||||||
set -x GUM_CHOOSE_HEADER "Select the Desktop to boot into:"
|
|
||||||
set CHOICES
|
|
||||||
|
|
||||||
if which sway &>/dev/null
|
|
||||||
set -a CHOICES "sway"
|
|
||||||
end
|
|
||||||
if which niri-session &>/dev/null
|
|
||||||
set -a CHOICES "Niri"
|
|
||||||
end
|
|
||||||
if which startplasma-wayland &>/dev/null
|
|
||||||
set -a CHOICES "KDE Plasma"
|
|
||||||
end
|
|
||||||
set -a CHOICES "None: continue to shell"
|
|
||||||
|
|
||||||
switch (gum choose $CHOICES)
|
|
||||||
case "sway"
|
|
||||||
systemctl --user unset-environment NIXOS_OZONE_WL
|
|
||||||
exec sway
|
|
||||||
case "Niri"
|
|
||||||
exec niri-session
|
|
||||||
case "KDE Plasma"
|
|
||||||
exec ${pkgs.kdePackages.plasma-workspace}/libexec/plasma-dbus-run-session-if-needed startplasma-wayland
|
|
||||||
case '*'
|
|
||||||
exec fish -i
|
|
||||||
end
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./tide
|
./tide/nix-shell.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
options.programs.fish.everywhereAbbrs = mkOption {
|
options.programs.fish.everywhereAbbrs = mkOption {
|
||||||
|
@ -62,28 +23,22 @@ in
|
||||||
config.programs.fish = {
|
config.programs.fish = {
|
||||||
enable = true;
|
enable = true;
|
||||||
functions = {
|
functions = {
|
||||||
rebuild = {
|
|
||||||
body = ''
|
|
||||||
pls nixos-rebuild --flake ~/.config/nixpkgs -L --log-format internal-json -v $argv \
|
|
||||||
&| ${pkgs.nix-output-monitor}/bin/nom --json
|
|
||||||
'';
|
|
||||||
wraps = "nixos-rebuild";
|
|
||||||
};
|
|
||||||
# Simplify nix usage!
|
# Simplify nix usage!
|
||||||
nx = {
|
nx = {
|
||||||
body = ''
|
body = ''
|
||||||
argparse -s 'h/help' 'impure' 'u/unstable' 'g/git' -- $argv
|
set impure
|
||||||
if set -q _flag_help || test (count $argv) -eq 0
|
if test $argv[1] = "--impure"
|
||||||
echo "nx [--impure] [-u/--unstable/-g/--git] {package} [args...]"
|
set impure "--impure"
|
||||||
return 1
|
set argv $argv[2..]
|
||||||
|
end
|
||||||
|
if test (count $argv) -gt 0
|
||||||
|
nix run $impure nixpkgs#$argv[1] -- $argv[2..]
|
||||||
else
|
else
|
||||||
set -q _flag_impure && set impure "--impure"
|
echo "nx [--impure] {package} [args...]"
|
||||||
set nixpkgs "nixpkgs"
|
return 1
|
||||||
set -q _flag_unstable && set nixpkgs "nixpkgs-unstable"
|
|
||||||
set -q _flag_git && set nixpkgs "github:nixOS/nixpkgs/nixpkgs-unstable"
|
|
||||||
nix run $impure $nixpkgs"#"$argv[1] -- $argv[2..]
|
|
||||||
end
|
end
|
||||||
'';
|
'';
|
||||||
|
wraps = "nix run";
|
||||||
description = "Runs an app from the nixpkgs store.";
|
description = "Runs an app from the nixpkgs store.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -91,35 +46,25 @@ in
|
||||||
description = "Spawns a shell from the given nixpkgs packages";
|
description = "Spawns a shell from the given nixpkgs packages";
|
||||||
wraps = "nix shell";
|
wraps = "nix shell";
|
||||||
body = ''
|
body = ''
|
||||||
function help
|
set impure
|
||||||
echo "nsh [--impure] [--impure] [-u/--unstable/-g/--git] {package}* [-c command args...]"
|
if test $argv[1] = "--impure"
|
||||||
|
set impure "--impure"
|
||||||
|
set argv $argv[2..]
|
||||||
end
|
end
|
||||||
argparse -s 'h/help' 'impure' 'u/unstable' 'g/git' -- $argv
|
if test (count $argv) -gt 0
|
||||||
if set -q _flag_help || test (count $argv) -eq 0
|
|
||||||
help
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
set packages $argv
|
|
||||||
set minusc (contains -i -- "-c" $argv)
|
set minusc (contains -i -- "-c" $argv)
|
||||||
if test -n "$minusc"
|
if test -z $minusc
|
||||||
if test $minusc -eq 1
|
nix shell $impure nixpkgs#$argv -c fish
|
||||||
help
|
else if test $minusc -eq (count $argv)
|
||||||
|
echo "nsh [--impure] {packages} [-c command args...]"
|
||||||
return 1
|
return 1
|
||||||
end
|
|
||||||
set packages $argv[..(math $minusc - 1)]
|
|
||||||
set argv $argv[(math $minusc + 1)..]
|
|
||||||
else
|
else
|
||||||
set argv "fish" "-i"
|
nix shell $impure nixpkgs#$argv[..(math $minusc - 1)] $argv[$minusc..]
|
||||||
end
|
end
|
||||||
if test (count $packages) -eq 0
|
else
|
||||||
help
|
echo "nsh [--impure] {packages} [-c command args...]"
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
set -q _flag_impure && set impure "--impure"
|
|
||||||
set nixpkgs "nixpkgs"
|
|
||||||
set -q _flag_unstable && set nixpkgs "nixpkgs-unstable"
|
|
||||||
set -q _flag_git && set nixpkgs "github:nixOS/nixpkgs/nixpkgs-unstable"
|
|
||||||
nix shell $impure $nixpkgs"#"$packages --command $argv
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
# Grep stuff
|
# Grep stuff
|
||||||
|
@ -136,49 +81,23 @@ in
|
||||||
description = "Search with ripgrep and put results into the editor";
|
description = "Search with ripgrep and put results into the editor";
|
||||||
};
|
};
|
||||||
echo-today = "date +%F";
|
echo-today = "date +%F";
|
||||||
newfile = "mkdir -p (dirname $argv[-1]) && touch $argv";
|
|
||||||
|
|
||||||
# pls
|
|
||||||
pls = {
|
|
||||||
wraps = "sudo";
|
|
||||||
body = ''
|
|
||||||
set -l cmd "`"(string join " " -- $argv)"`"
|
|
||||||
echo "I-It's not like I'm gonna run "$cmd" for you or a-anything! Baka >:C" >&2
|
|
||||||
# Send a notification on password prompt
|
|
||||||
if command sudo -vn 2>/dev/null
|
|
||||||
# nothing to do, user already authenticated
|
|
||||||
else
|
|
||||||
# throw a notification
|
|
||||||
set notif_id (kitten notify -P \
|
|
||||||
-p ${./haruka.png} \
|
|
||||||
-a "pls" \
|
|
||||||
-u critical \
|
|
||||||
"A-a command requires your p-password" \
|
|
||||||
(printf "I-I need your p-password to r-run the following c-command:\n\n%s" $cmd))
|
|
||||||
command sudo -v -p "P-password please: "
|
|
||||||
kitten notify -i $notif_id ""
|
|
||||||
end
|
|
||||||
command sudo $argv
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
tide = {
|
tide = {
|
||||||
enable = true;
|
nix-shell.enable = true;
|
||||||
leftItems = options.programs.fish.tide.leftItems.default;
|
|
||||||
rightItems = options.programs.fish.tide.rightItems.default;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
shellAliases = {
|
shellAliases = {
|
||||||
cat = "bat --theme=GitHub ";
|
cat = "bat --theme=GitHub ";
|
||||||
catp = "bat --theme=GitHub -p ";
|
catp = "bat --theme=GitHub -p ";
|
||||||
l = "exa -l --color=always ";
|
l = "exa -l --color=always ";
|
||||||
e = "$EDITOR";
|
|
||||||
"cp+" = "rsync -avzP";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
everywhereAbbrs = {
|
everywhereAbbrs = {
|
||||||
lsports = if pkgs.stdenv.isDarwin then "lsof -i -P | grep LISTEN" else "ss -tulp";
|
lsports =
|
||||||
|
if pkgs.stdenv.isDarwin
|
||||||
|
then "lsof -i -P | grep LISTEN"
|
||||||
|
else "ss -tulp";
|
||||||
};
|
};
|
||||||
|
|
||||||
shellInit = ''
|
shellInit = ''
|
||||||
|
@ -186,17 +105,9 @@ in
|
||||||
if test -e /opt/homebrew/bin/brew
|
if test -e /opt/homebrew/bin/brew
|
||||||
/opt/homebrew/bin/brew shellenv | source
|
/opt/homebrew/bin/brew shellenv | source
|
||||||
end
|
end
|
||||||
|
|
||||||
# Override PATH
|
|
||||||
set --export --prepend PATH ~/.bin/overrides ~/.local/bin
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
interactiveShellInit = ''
|
interactiveShellInit = ''
|
||||||
# Sway!
|
|
||||||
if status --is-login; and test -z $DISPLAY; and test (tty) = "/dev/tty1"
|
|
||||||
exec ${bootDesktop}
|
|
||||||
end
|
|
||||||
|
|
||||||
function fish_greeting
|
function fish_greeting
|
||||||
${pkgs.timg}/bin/timg ${./arona.jpg}
|
${pkgs.timg}/bin/timg ${./arona.jpg}
|
||||||
printf (env LANG=ja_JP.UTF-8 date +"ご主人様、お帰りなさい!\n今日は%A、%Y年%m月%d日ですねー!今の時間って、%H時%M分です〜 \n言って言ってご主人様、コンピュターちゃんと何がするつもりでしょーか?〜エヘヘっ\n")
|
printf (env LANG=ja_JP.UTF-8 date +"ご主人様、お帰りなさい!\n今日は%A、%Y年%m月%d日ですねー!今の時間って、%H時%M分です〜 \n言って言ってご主人様、コンピュターちゃんと何がするつもりでしょーか?〜エヘヘっ\n")
|
||||||
|
@ -208,6 +119,13 @@ in
|
||||||
echo (__original_fish_title) - fish
|
echo (__original_fish_title) - fish
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Set up an editor alias
|
||||||
|
if test -n "$EDITOR"
|
||||||
|
alias e="$EDITOR"
|
||||||
|
else
|
||||||
|
alias e="kak"
|
||||||
|
end
|
||||||
|
|
||||||
# Source iTerm2 integration
|
# Source iTerm2 integration
|
||||||
if test -e ~/.iterm2_shell_integration.fish; and test $__CFBundleIdentifier = "com.googlecode.iterm2"
|
if test -e ~/.iterm2_shell_integration.fish; and test $__CFBundleIdentifier = "com.googlecode.iterm2"
|
||||||
source ~/.iterm2_shell_integration.fish
|
source ~/.iterm2_shell_integration.fish
|
||||||
|
@ -230,11 +148,11 @@ in
|
||||||
bind -M default gl end-of-line
|
bind -M default gl end-of-line
|
||||||
|
|
||||||
# Everywhere abbrs
|
# Everywhere abbrs
|
||||||
${concatStringsSep "\n" (
|
${
|
||||||
mapAttrsToList (
|
concatStringsSep "\n"
|
||||||
k: v: "abbr --add --position anywhere -- ${k} ${escapeShellArg v}"
|
(mapAttrsToList (k: v: "abbr --add --position anywhere -- ${k} ${escapeShellArg v}")
|
||||||
) config.programs.fish.everywhereAbbrs
|
config.programs.fish.everywhereAbbrs)
|
||||||
)}
|
}
|
||||||
|
|
||||||
# Replace today with actual today
|
# Replace today with actual today
|
||||||
abbr --add --position anywhere today -f echo-today
|
abbr --add --position anywhere today -f echo-today
|
||||||
|
@ -256,8 +174,23 @@ in
|
||||||
set -q PERL_LOCAL_LIB_ROOT; or set -x PERL_LOCAL_LIB_ROOT ${config.home.homeDirectory}/perl5;
|
set -q PERL_LOCAL_LIB_ROOT; or set -x PERL_LOCAL_LIB_ROOT ${config.home.homeDirectory}/perl5;
|
||||||
set -x PERL_MB_OPT --install_base\ \"${config.home.homeDirectory}/perl5\";
|
set -x PERL_MB_OPT --install_base\ \"${config.home.homeDirectory}/perl5\";
|
||||||
set -x PERL_MM_OPT INSTALL_BASE=${config.home.homeDirectory}/perl5;
|
set -x PERL_MM_OPT INSTALL_BASE=${config.home.homeDirectory}/perl5;
|
||||||
|
|
||||||
|
# Sway!
|
||||||
|
if status --is-login; and which sway >/dev/null; and test -z $DISPLAY; and test (tty) = "/dev/tty1"
|
||||||
|
read -P "Press enter to start sway..."; and exec sway
|
||||||
|
end
|
||||||
'';
|
'';
|
||||||
plugins = [
|
plugins = [
|
||||||
|
{
|
||||||
|
name = "tide";
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "IlanCosman";
|
||||||
|
repo = "tide";
|
||||||
|
rev = "447945d2cff8f70d5c791dd4eec8b322d37798dd";
|
||||||
|
# sha256 = lib.fakeSha256;
|
||||||
|
sha256 = "sha256-1c2E3UC3r9hPfijAQoZ/+4yXieFxC4+hkk7wUyr30NM=";
|
||||||
|
};
|
||||||
|
}
|
||||||
{
|
{
|
||||||
name = "fzf";
|
name = "fzf";
|
||||||
src = pkgs.fetchFromGitHub {
|
src = pkgs.fetchFromGitHub {
|
||||||
|
@ -286,8 +219,8 @@ in
|
||||||
target = ".config/fish/conf.d/change_cmd.fish";
|
target = ".config/fish/conf.d/change_cmd.fish";
|
||||||
};
|
};
|
||||||
"fish/pls.fish" = {
|
"fish/pls.fish" = {
|
||||||
source = ./pls_extra.fish;
|
source = ./. + "/pls.fish";
|
||||||
target = ".config/fish/conf.d/pls_extra.fish";
|
target = ".config/fish/conf.d/pls.fish";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 30 KiB |
155
home/fish/pls.fish
Normal file
155
home/fish/pls.fish
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
alias sue="pls -e"
|
||||||
|
|
||||||
|
function pls
|
||||||
|
set -l cmd "`"(string join " " -- $argv)"`"
|
||||||
|
echo "I-It's not like I'm gonna run "$cmd" for you or a-anything! Baka >:C" >&2
|
||||||
|
# Send a notification on password prompt
|
||||||
|
if command sudo -vn 2>/dev/null
|
||||||
|
# nothing to do, user already authenticated
|
||||||
|
else
|
||||||
|
# throw a notification
|
||||||
|
# notify-send -t 3000 -u critical -i ~/Downloads/harukablush.jpg -h "STRING:command:"$cmd "A-a command requires your p-password" (printf "I-I need your p-password to r-run the following c-command: %s" $cmd)
|
||||||
|
end
|
||||||
|
command sudo $argv
|
||||||
|
end
|
||||||
|
|
||||||
|
function sudo
|
||||||
|
echo "Not polite enough."
|
||||||
|
end
|
||||||
|
|
||||||
|
function __fish_prepend_pls -d "Prepend 'pls ' to the beginning of the current commandline"
|
||||||
|
# If there is no commandline, insert the last item from history
|
||||||
|
# and *then* toggle
|
||||||
|
if not commandline | string length -q
|
||||||
|
commandline -r "$history[1]"
|
||||||
|
end
|
||||||
|
|
||||||
|
set -l cmd (commandline -po)
|
||||||
|
set -l cursor (commandline -C)
|
||||||
|
|
||||||
|
if test "$cmd[1]" = e
|
||||||
|
commandline -C 0
|
||||||
|
commandline -i "su"
|
||||||
|
commandline -C (math $cursor + 2)
|
||||||
|
else if test "$cmd[1]" = sue
|
||||||
|
commandline -r (string sub --start=3 (commandline -p))
|
||||||
|
commandline -C -- (math $cursor - 2)
|
||||||
|
else if test "$cmd[1]" != pls
|
||||||
|
commandline -C 0
|
||||||
|
commandline -i "pls "
|
||||||
|
commandline -C (math $cursor + 4)
|
||||||
|
else
|
||||||
|
commandline -r (string sub --start=5 (commandline -p))
|
||||||
|
commandline -C -- (math $cursor - 4)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
bind --preset -e -M insert \es
|
||||||
|
bind -M insert \es __fish_prepend_pls
|
||||||
|
|
||||||
|
function __fish_man_page
|
||||||
|
# Get all commandline tokens not starting with "-"
|
||||||
|
set -l args (commandline -po | string match -rv '^-')
|
||||||
|
|
||||||
|
# If commandline is empty, exit.
|
||||||
|
if not set -q args[1]
|
||||||
|
printf \a
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
#Skip `pls` and display then manpage of following command
|
||||||
|
while set -q args[2]
|
||||||
|
and string match -qr -- '^(pls|.*=.*)$' $args[1]
|
||||||
|
set -e args[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
# If there are at least two tokens not starting with "-", the second one might be a subcommand.
|
||||||
|
# Try "man first-second" and fall back to "man first" if that doesn't work out.
|
||||||
|
set -l maincmd (basename $args[1])
|
||||||
|
if set -q args[2]
|
||||||
|
# HACK: If stderr is not attached to a terminal `less` (the default pager)
|
||||||
|
# wouldn't use the alternate screen.
|
||||||
|
# But since we don't know what pager it is, and because `man` is totally underspecified,
|
||||||
|
# the best we can do is to *try* the man page, and assume that `man` will return false if it fails.
|
||||||
|
# See #7863.
|
||||||
|
if man "$maincmd-$args[2]" &>/dev/null
|
||||||
|
man "$maincmd-$args[2]"
|
||||||
|
else if man "$maincmd" &>/dev/null
|
||||||
|
man "$maincmd"
|
||||||
|
else
|
||||||
|
printf \a
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if man "$maincmd" &>/dev/null
|
||||||
|
man "$maincmd"
|
||||||
|
else
|
||||||
|
printf \a
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
commandline -f repaint
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Completion for pls
|
||||||
|
#
|
||||||
|
|
||||||
|
function __fish_pls_print_remaining_args
|
||||||
|
set -l tokens (commandline -opc) (commandline -ct)
|
||||||
|
set -e tokens[1]
|
||||||
|
# These are all the options mentioned in the man page for Todd Miller's "pls.ws" pls (in that order).
|
||||||
|
# If any other implementation has different options, this should be harmless, since they shouldn't be used anyway.
|
||||||
|
set -l opts A/askpass b/background C/close-from= E/preserve-env='?'
|
||||||
|
# Note that "-h" is both "--host" (which takes an option) and "--help" (which doesn't).
|
||||||
|
# But `-h` as `--help` only counts when it's the only argument (`pls -h`),
|
||||||
|
# so any argument completion after that should take it as "--host".
|
||||||
|
set -a opts e/edit g/group= H/set-home h/host= 1-help
|
||||||
|
set -a opts i/login K/remove-timestamp k/reset-timestamp l/list n/non-interactive
|
||||||
|
set -a opts P/preserve-groups p/prompt= S/stdin s/shell U/other-user=
|
||||||
|
set -a opts u/user= T/command-timeout= V/version v/validate
|
||||||
|
argparse -s $opts -- $tokens 2>/dev/null
|
||||||
|
# The remaining argv is the subcommand with all its options, which is what
|
||||||
|
# we want.
|
||||||
|
if test -n "$argv"
|
||||||
|
and not string match -qr '^-' $argv[1]
|
||||||
|
string join0 -- $argv
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function __fish_pls_no_subcommand
|
||||||
|
not __fish_pls_print_remaining_args >/dev/null
|
||||||
|
end
|
||||||
|
|
||||||
|
function __fish_complete_pls_subcommand
|
||||||
|
set -l args (__fish_pls_print_remaining_args | string split0)
|
||||||
|
set -lx -a PATH /usr/local/sbin /sbin /usr/sbin
|
||||||
|
__fish_complete_subcommand --commandline $args
|
||||||
|
end
|
||||||
|
|
||||||
|
# All these options should be valid for GNU and OSX pls
|
||||||
|
complete -c pls -n __fish_no_arguments -s h -d "Display help and exit"
|
||||||
|
complete -c pls -n __fish_no_arguments -s V -d "Display version information and exit"
|
||||||
|
complete -c pls -n __fish_pls_no_subcommand -s A -d "Ask for password via the askpass or \$SSH_ASKPASS program"
|
||||||
|
complete -c pls -n __fish_pls_no_subcommand -s C -d "Close all file descriptors greater or equal to the given number" -xa "0 1 2 255"
|
||||||
|
complete -c pls -n __fish_pls_no_subcommand -s E -d "Preserve environment"
|
||||||
|
complete -c pls -n __fish_pls_no_subcommand -s H -d "Set home"
|
||||||
|
complete -c pls -n __fish_pls_no_subcommand -s K -d "Remove the credential timestamp entirely"
|
||||||
|
complete -c pls -n __fish_pls_no_subcommand -s P -d "Preserve group vector"
|
||||||
|
complete -c pls -n __fish_pls_no_subcommand -s S -d "Read password from stdin"
|
||||||
|
complete -c pls -n __fish_pls_no_subcommand -s b -d "Run command in the background"
|
||||||
|
complete -c pls -n __fish_pls_no_subcommand -s e -rF -d Edit
|
||||||
|
complete -c pls -n __fish_pls_no_subcommand -s g -a "(__fish_complete_groups)" -x -d "Run command as group"
|
||||||
|
complete -c pls -n __fish_pls_no_subcommand -s i -d "Run a login shell"
|
||||||
|
complete -c pls -n __fish_pls_no_subcommand -s k -d "Reset or ignore the credential timestamp"
|
||||||
|
complete -c pls -n __fish_pls_no_subcommand -s l -d "List the allowed and forbidden commands for the given user"
|
||||||
|
complete -c pls -n __fish_pls_no_subcommand -s n -d "Do not prompt for a password - if one is needed, fail"
|
||||||
|
complete -c pls -n __fish_pls_no_subcommand -s p -d "Specify a custom password prompt"
|
||||||
|
complete -c pls -n __fish_pls_no_subcommand -s s -d "Run the given command in a shell"
|
||||||
|
complete -c pls -n __fish_pls_no_subcommand -s u -a "(__fish_complete_users)" -x -d "Run command as user"
|
||||||
|
complete -c pls -n __fish_pls_no_subcommand -s v -n __fish_no_arguments -d "Validate the credentials, extending timeout"
|
||||||
|
|
||||||
|
# Complete the command we are executed under pls
|
||||||
|
complete -c pls -x -n 'not __fish_seen_argument -s e' -a "(__fish_complete_pls_subcommand)"
|
|
@ -1,47 +0,0 @@
|
||||||
alias sue="pls -e"
|
|
||||||
|
|
||||||
function sudo
|
|
||||||
echo "Not polite enough."
|
|
||||||
end
|
|
||||||
|
|
||||||
bind --preset -M visual \es 'fish_commandline_prepend pls'
|
|
||||||
bind -M insert \es 'fish_commandline_prepend pls'
|
|
||||||
|
|
||||||
function __fish_man_page
|
|
||||||
# Get all commandline tokens not starting with "-", up to and including the cursor's
|
|
||||||
set -l args (string match -rv '^-|^$' -- (commandline -cpx && commandline -t))
|
|
||||||
|
|
||||||
# If commandline is empty, exit.
|
|
||||||
if not set -q args[1]
|
|
||||||
printf \a
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
# Skip leading commands and display the manpage of following command
|
|
||||||
while set -q args[2]
|
|
||||||
and string match -qr -- '^(and|begin|builtin|caffeinate|command|doas|entr|env|exec|if|mosh|nice|not|or|pipenv|prime-run|setsid|sudo|pls|systemd-nspawn|time|watch|while|xargs|.*=.*)$' $args[1]
|
|
||||||
set -e args[1]
|
|
||||||
end
|
|
||||||
|
|
||||||
# If there are at least two tokens not starting with "-", the second one might be a subcommand.
|
|
||||||
# Try "man first-second" and fall back to "man first" if that doesn't work out.
|
|
||||||
set -l maincmd (path basename $args[1])
|
|
||||||
# HACK: If stderr is not attached to a terminal `less` (the default pager)
|
|
||||||
# wouldn't use the alternate screen.
|
|
||||||
# But since we don't know what pager it is, and because `man` is totally underspecified,
|
|
||||||
# the best we can do is to *try* the man page, and assume that `man` will return false if it fails.
|
|
||||||
# See #7863.
|
|
||||||
if set -q args[2]
|
|
||||||
and not string match -q -- '*/*' $args[2]
|
|
||||||
and man "$maincmd-$args[2]" &>/dev/null
|
|
||||||
man "$maincmd-$args[2]"
|
|
||||||
else
|
|
||||||
if man "$maincmd" &>/dev/null
|
|
||||||
man "$maincmd"
|
|
||||||
else
|
|
||||||
printf \a
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
commandline -f repaint
|
|
||||||
end
|
|
|
@ -1,107 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
let
|
|
||||||
cfg = config.programs.fish.tide;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.programs.fish.tide = {
|
|
||||||
enable = mkEnableOption "Enable tide integrations for fish";
|
|
||||||
items = mkOption {
|
|
||||||
type = types.attrsOf types.str;
|
|
||||||
description = "Additional item definitions to create";
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
rightItems = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
description = "The list of right-items, note that `time` is not included here and will always appear last";
|
|
||||||
default = [
|
|
||||||
"status"
|
|
||||||
"cmd_duration"
|
|
||||||
"jobs"
|
|
||||||
"direnv"
|
|
||||||
"node"
|
|
||||||
"python"
|
|
||||||
"rustc"
|
|
||||||
"java"
|
|
||||||
"php"
|
|
||||||
"pulumi"
|
|
||||||
"ruby"
|
|
||||||
"go"
|
|
||||||
"gcloud"
|
|
||||||
"kubectl"
|
|
||||||
"distrobox"
|
|
||||||
"toolbox"
|
|
||||||
"terraform"
|
|
||||||
"aws"
|
|
||||||
"crystal"
|
|
||||||
"elixir"
|
|
||||||
"nix_shell"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
leftItems = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
description = "The list of left-items. Note that `newline` and `character` is not included here and will always appear last";
|
|
||||||
default = [
|
|
||||||
"os"
|
|
||||||
"context"
|
|
||||||
"pwd"
|
|
||||||
"git"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config.programs.fish =
|
|
||||||
let
|
|
||||||
tideItems = attrsets.mapAttrs' (
|
|
||||||
name: def: {
|
|
||||||
name = "_tide_item_${name}";
|
|
||||||
value = def;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
in
|
|
||||||
mkIf cfg.enable {
|
|
||||||
functions = tideItems (
|
|
||||||
{
|
|
||||||
nix_shell = ''
|
|
||||||
# In a Nix Shell
|
|
||||||
if set -qx DIRENV_FILE && test -f $DIRENV_FILE && rg -q "^use flake" $DIRENV_FILE
|
|
||||||
set -U tide_nix_shell_color "FFA500"
|
|
||||||
set -U tide_nix_shell_bg_color normal
|
|
||||||
_tide_print_item nix_shell "❄"
|
|
||||||
end
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
// cfg.items
|
|
||||||
);
|
|
||||||
plugins = [
|
|
||||||
{
|
|
||||||
name = "tide";
|
|
||||||
src = pkgs.fetchFromGitHub {
|
|
||||||
owner = "IlanCosman";
|
|
||||||
repo = "tide";
|
|
||||||
rev = "v6.0.1";
|
|
||||||
# sha256 = lib.fakeSha256;
|
|
||||||
sha256 = "sha256-oLD7gYFCIeIzBeAW1j62z5FnzWAp3xSfxxe7kBtTLgA=";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
config.xdg.configFile."fish/tide/init.fish" = {
|
|
||||||
text = ''
|
|
||||||
# Configure tide items
|
|
||||||
set -U tide_left_prompt_items ${
|
|
||||||
concatMapStringsSep " " escapeShellArg cfg.leftItems
|
|
||||||
} newline character
|
|
||||||
set -U tide_right_prompt_items ${concatMapStringsSep " " escapeShellArg cfg.rightItems} time
|
|
||||||
'';
|
|
||||||
|
|
||||||
onChange = "fish ~/.config/fish/tide/init.fish";
|
|
||||||
};
|
|
||||||
}
|
|
22
home/fish/tide/nix-shell.nix
Normal file
22
home/fish/tide/nix-shell.nix
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.programs.fish.tide.nix-shell;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.programs.fish.tide.nix-shell = {
|
||||||
|
enable = mkEnableOption "An indicator of having a `nix shell` environment";
|
||||||
|
};
|
||||||
|
|
||||||
|
config.programs.fish = mkIf cfg.enable {
|
||||||
|
functions._tide_item_nix_shell = ''
|
||||||
|
# In a Nix Shell
|
||||||
|
if string match -q "/nix/store/*" $PATH
|
||||||
|
set -U tide_nix_shell_color (set -q DIRENV_DIR && echo "FFA500" || echo "blue")
|
||||||
|
set -U tide_nix_shell_bg_color normal
|
||||||
|
_tide_print_item nix_shell "❄"
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,16 +1,11 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
# Common configuration
|
# Common configuration
|
||||||
./common.nix
|
./common.nix
|
||||||
# osu!
|
# osu!
|
||||||
./osu
|
./osu.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
# Home Manager needs a bit of information about you and the
|
# Home Manager needs a bit of information about you and the
|
||||||
|
@ -19,58 +14,66 @@
|
||||||
home.homeDirectory = "/home/nki";
|
home.homeDirectory = "/home/nki";
|
||||||
|
|
||||||
# More packages
|
# More packages
|
||||||
home.packages = (
|
home.packages = (with pkgs; [
|
||||||
with pkgs;
|
# CLI stuff
|
||||||
[
|
zip
|
||||||
# Gaming stuff
|
# TeX
|
||||||
wineWowPackages.full
|
texlive.combined.scheme-full
|
||||||
# wine-lol
|
inkscape # for TeX svg
|
||||||
winetricks
|
|
||||||
lutris
|
# Java & sbt
|
||||||
steam
|
openjdk11
|
||||||
|
sbt
|
||||||
|
|
||||||
# Manage tlmc
|
# Manage tlmc
|
||||||
flacon
|
flacon
|
||||||
ttaenc
|
ttaenc
|
||||||
picard
|
picard
|
||||||
]
|
]);
|
||||||
);
|
|
||||||
|
|
||||||
# Enable X11 configuration
|
# Enable X11 configuration
|
||||||
linux.graphical.type = "wayland";
|
linux.graphical.type = "wayland";
|
||||||
linux.graphical.wallpaper = ./images/pixiv_18776904.png;
|
linux.graphical.wallpaper = ./images/pixiv_18776904.png;
|
||||||
linux.graphical.defaults.webBrowser.package = pkgs.zen-browser-bin;
|
|
||||||
linux.graphical.defaults.webBrowser.desktopFile = "zen.desktop";
|
|
||||||
programs.my-niri.enable = true;
|
|
||||||
programs.my-niri.enableLaptop = false;
|
|
||||||
programs.my-sway.enable = true;
|
programs.my-sway.enable = true;
|
||||||
programs.my-sway.fontSize = 15.0;
|
programs.my-sway.fontSize = 15.0;
|
||||||
programs.my-sway.enableLaptop = false;
|
programs.my-sway.enableLaptopBars = false;
|
||||||
programs.my-waybar.fontSize = 15.0;
|
programs.my-sway.enableMpd = true;
|
||||||
programs.my-waybar.enableMpd = true;
|
|
||||||
# Keyboard options
|
# Keyboard options
|
||||||
wayland.windowManager.sway.config.input."type:keyboard".xkb_layout = "jp";
|
wayland.windowManager.sway.config.input."type:keyboard".xkb_layout = "jp";
|
||||||
wayland.windowManager.sway.config.input."type:pointer".accel_profile = "flat";
|
wayland.windowManager.sway.config.input."type:pointer".accel_profile = "flat";
|
||||||
# 144hz adaptive refresh ON!
|
# 144hz adaptive refresh ON!
|
||||||
|
wayland.windowManager.sway.config.output =
|
||||||
|
let
|
||||||
|
scale = 1.5;
|
||||||
|
top_x = builtins.ceil (3840 / scale);
|
||||||
|
top_y = builtins.ceil (((2160 / scale) - 1080) / 2);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
"AOC U28G2G6B PPYP2JA000013" = {
|
||||||
|
mode = "3840x2160@60Hz";
|
||||||
|
scale = toString scale;
|
||||||
|
adaptive_sync = "on";
|
||||||
|
# render_bit_depth = "10";
|
||||||
|
position = "0 0";
|
||||||
|
};
|
||||||
|
"AOC 24G2W1G4 ATNN21A005410" = {
|
||||||
|
mode = "1920x1080@144Hz";
|
||||||
|
adaptive_sync = "on";
|
||||||
|
position = "${toString top_x} ${toString top_y}";
|
||||||
|
};
|
||||||
|
|
||||||
|
"ViewSonic Corporation XG2402 SERIES V4K182501054" = {
|
||||||
|
mode = "1920x1080@144Hz";
|
||||||
|
adaptive_sync = "on";
|
||||||
|
};
|
||||||
|
};
|
||||||
nki.programs.kitty.enable = true;
|
nki.programs.kitty.enable = true;
|
||||||
nki.programs.kitty.fontSize = 14;
|
nki.programs.kitty.fontSize = 14;
|
||||||
programs.my-waybar.makeBars =
|
programs.my-sway.waybar.makeBars = barWith: [
|
||||||
with config.common.monitors;
|
|
||||||
barWith: [
|
|
||||||
# For primary
|
# For primary
|
||||||
(barWith {
|
(barWith { extraSettings = { output = [ "AOC U28G2G6B PPYP2JA000013" ]; }; })
|
||||||
extraSettings = {
|
|
||||||
output = [ home_4k.meta.connection ];
|
|
||||||
};
|
|
||||||
})
|
|
||||||
# For secondary, hide mpd
|
# For secondary, hide mpd
|
||||||
(barWith {
|
(barWith { showMedia = false; showConnectivity = false; extraSettings = { output = [ "AOC 24G2W1G4 ATNN21A005410" ]; }; })
|
||||||
showMedia = false;
|
|
||||||
showConnectivity = false;
|
|
||||||
extraSettings = {
|
|
||||||
output = [ home_1440.meta.connection ];
|
|
||||||
};
|
|
||||||
})
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# Yellow light!
|
# Yellow light!
|
||||||
|
@ -92,28 +95,10 @@
|
||||||
# ncmpcpp
|
# ncmpcpp
|
||||||
programs.ncmpcpp.enable = true;
|
programs.ncmpcpp.enable = true;
|
||||||
programs.ncmpcpp.bindings = [
|
programs.ncmpcpp.bindings = [
|
||||||
{
|
{ key = "j"; command = "scroll_down"; }
|
||||||
key = "j";
|
{ key = "k"; command = "scroll_up"; }
|
||||||
command = "scroll_down";
|
{ key = "J"; command = [ "select_item" "scroll_down" ]; }
|
||||||
}
|
{ key = "K"; command = [ "select_item" "scroll_up" ]; }
|
||||||
{
|
|
||||||
key = "k";
|
|
||||||
command = "scroll_up";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
key = "J";
|
|
||||||
command = [
|
|
||||||
"select_item"
|
|
||||||
"scroll_down"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
key = "K";
|
|
||||||
command = [
|
|
||||||
"select_item"
|
|
||||||
"scroll_up"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
programs.ncmpcpp.settings = {
|
programs.ncmpcpp.settings = {
|
||||||
# General
|
# General
|
||||||
|
@ -171,3 +156,4 @@
|
||||||
# changes in each release.
|
# changes in each release.
|
||||||
home.stateVersion = "21.05";
|
home.stateVersion = "21.05";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
184
home/kakoune.nix
184
home/kakoune.nix
|
@ -1,184 +0,0 @@
|
||||||
{ pkgs, lib, ... }:
|
|
||||||
let
|
|
||||||
|
|
||||||
in
|
|
||||||
{
|
|
||||||
imports = [ ./modules/programs/my-kakoune ];
|
|
||||||
|
|
||||||
home.packages = with pkgs; [
|
|
||||||
# ctags for peneira
|
|
||||||
universal-ctags
|
|
||||||
# tree-sitter for kak
|
|
||||||
kak-tree-sitter
|
|
||||||
];
|
|
||||||
|
|
||||||
# xdg.configFile."kak-tree-sitter/config.toml".source = ./kak-tree-sitter.toml;
|
|
||||||
|
|
||||||
# Enable the kakoune package.
|
|
||||||
programs.my-kakoune.enable = true;
|
|
||||||
programs.my-kakoune.enable-fish-session = true;
|
|
||||||
programs.my-kakoune.tree-sitter.extraAliases = {
|
|
||||||
# Scala stuff
|
|
||||||
method = "function";
|
|
||||||
module = "namespace";
|
|
||||||
function_call = "function";
|
|
||||||
method_call = "method";
|
|
||||||
|
|
||||||
boolean = "constant_builtin_boolean";
|
|
||||||
number = "constant_numeric";
|
|
||||||
float = "constant_numeric_float";
|
|
||||||
|
|
||||||
type_qualifier = "keyword_special";
|
|
||||||
storageclass = "keyword_storage_modifier";
|
|
||||||
conditional = "keyword_conditional";
|
|
||||||
include = "keyword_control_import";
|
|
||||||
};
|
|
||||||
programs.my-kakoune.tree-sitter.languages =
|
|
||||||
let
|
|
||||||
tree-sitter-go = pkgs.fetchFromGitHub {
|
|
||||||
owner = "tree-sitter";
|
|
||||||
repo = "tree-sitter-go";
|
|
||||||
rev = "v0.20.0";
|
|
||||||
hash = "sha256-G7d8CHCyKDAb9j6ijRfHk/HlgPqSI+uvkuRIRRvjkHI=";
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
scala =
|
|
||||||
let
|
|
||||||
src = pkgs.fetchFromGitHub {
|
|
||||||
owner = "tree-sitter";
|
|
||||||
repo = "tree-sitter-scala";
|
|
||||||
rev = "70afdd5632d57dd63a960972ab25945e353a52f6";
|
|
||||||
hash = "sha256-bi0Lqo/Zs2Uaz1efuKAARpEDg5Hm59oUe7eSXgL1Wow=";
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
grammar.src = src;
|
|
||||||
queries.src = src;
|
|
||||||
queries.path = "queries/scala";
|
|
||||||
};
|
|
||||||
haskell =
|
|
||||||
let
|
|
||||||
src = pkgs.fetchFromGitHub {
|
|
||||||
owner = "tree-sitter";
|
|
||||||
repo = "tree-sitter-haskell";
|
|
||||||
rev = "ba0bfb0e5d8e9e31c160d287878c6f26add3ec08";
|
|
||||||
hash = "sha256-ZSOF0CLOn82GwU3xgvFefmh/AD2j5zz8I0t5YPwfan0=";
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
grammar.src = src;
|
|
||||||
grammar.compile.args = [
|
|
||||||
"-c"
|
|
||||||
"-fpic"
|
|
||||||
"../parser.c"
|
|
||||||
"../scanner.c"
|
|
||||||
"../unicode.h"
|
|
||||||
"-I"
|
|
||||||
".."
|
|
||||||
];
|
|
||||||
queries.src = src;
|
|
||||||
queries.path = "queries";
|
|
||||||
};
|
|
||||||
yaml = {
|
|
||||||
grammar.src = pkgs.fetchFromGitHub {
|
|
||||||
owner = "ikatyang";
|
|
||||||
repo = "tree-sitter-yaml";
|
|
||||||
rev = "0e36bed171768908f331ff7dff9d956bae016efb";
|
|
||||||
hash = "sha256-bpiT3FraOZhJaoiFWAoVJX1O+plnIi8aXOW2LwyU23M=";
|
|
||||||
};
|
|
||||||
grammar.compile.args = [
|
|
||||||
"-c"
|
|
||||||
"-fpic"
|
|
||||||
"../scanner.cc"
|
|
||||||
"../parser.c"
|
|
||||||
"-I"
|
|
||||||
".."
|
|
||||||
];
|
|
||||||
grammar.link.args = [
|
|
||||||
"-shared"
|
|
||||||
"-fpic"
|
|
||||||
"scanner.o"
|
|
||||||
"parser.o"
|
|
||||||
];
|
|
||||||
grammar.link.flags = [
|
|
||||||
"-O3"
|
|
||||||
"-lstdc++"
|
|
||||||
];
|
|
||||||
|
|
||||||
queries.src = pkgs.fetchFromGitHub {
|
|
||||||
owner = "helix-editor";
|
|
||||||
repo = "helix";
|
|
||||||
rev = "dbd248fdfa680373d94fbc10094a160aafa0f7a7";
|
|
||||||
hash = "sha256-wk8qVUDFXhAOi1Ibc6iBMzDCXb6t+YiWZcTd0IJybqc=";
|
|
||||||
};
|
|
||||||
queries.path = "runtime/queries/yaml";
|
|
||||||
};
|
|
||||||
|
|
||||||
templ =
|
|
||||||
let
|
|
||||||
src = pkgs.fetchFromGitHub {
|
|
||||||
owner = "vrischmann";
|
|
||||||
repo = "tree-sitter-templ";
|
|
||||||
rev = "4519e3ec9ca92754ca25659bb1fd410d5e0f8d88";
|
|
||||||
hash = "sha256-ic5SlqDEZoYakrJFe0H9GdzravqovlL5sTaHjyhe74M=";
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
grammar.src = src;
|
|
||||||
queries.src = pkgs.runCommandLocal "templ-tree-sitter-queries" { } ''
|
|
||||||
mkdir -p $out/queries
|
|
||||||
# copy most stuff from tree-sitter-templ
|
|
||||||
install -m644 ${src}/queries/templ/* $out/queries
|
|
||||||
# override inherited files
|
|
||||||
cat ${tree-sitter-go}/queries/highlights.scm ${src}/queries/templ/highlights.scm > $out/queries/highlights.scm
|
|
||||||
'';
|
|
||||||
queries.path = "queries";
|
|
||||||
};
|
|
||||||
|
|
||||||
go = {
|
|
||||||
grammar.src = tree-sitter-go;
|
|
||||||
grammar.compile.args = [
|
|
||||||
"-c"
|
|
||||||
"-fpic"
|
|
||||||
"../parser.c"
|
|
||||||
"-I"
|
|
||||||
".."
|
|
||||||
];
|
|
||||||
grammar.link.args = [
|
|
||||||
"-shared"
|
|
||||||
"-fpic"
|
|
||||||
"parser.o"
|
|
||||||
];
|
|
||||||
queries.src = tree-sitter-go;
|
|
||||||
queries.path = "queries";
|
|
||||||
};
|
|
||||||
|
|
||||||
hylo =
|
|
||||||
let
|
|
||||||
src = pkgs.fetchFromGitHub {
|
|
||||||
owner = "natsukagami";
|
|
||||||
repo = "tree-sitter-hylo";
|
|
||||||
rev = "494cbdff0d13cbc67348316af2efa0286dbddf6f";
|
|
||||||
hash = "sha256-R5UeoglCTl0do3VDJ/liCTeqbxU9slvmVKNRA/el2VY=";
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
grammar.src = src;
|
|
||||||
grammar.compile.args = [
|
|
||||||
"-c"
|
|
||||||
"-fpic"
|
|
||||||
"../parser.c"
|
|
||||||
"-I"
|
|
||||||
".."
|
|
||||||
];
|
|
||||||
grammar.link.args = [
|
|
||||||
"-shared"
|
|
||||||
"-fpic"
|
|
||||||
"parser.o"
|
|
||||||
];
|
|
||||||
queries.src = src;
|
|
||||||
queries.path = "queries";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
391
home/kakoune/kak.nix
Normal file
391
home/kakoune/kak.nix
Normal file
|
@ -0,0 +1,391 @@
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
kakounePkg =
|
||||||
|
pkgs.kakoune.override {
|
||||||
|
kakoune = with lib; pkgs.stdenv.mkDerivation rec {
|
||||||
|
pname = "kakoune-unwrapped";
|
||||||
|
version = "r${builtins.substring 0 6 pkgs.sources.kakoune.rev}";
|
||||||
|
src = pkgs.sources.kakoune;
|
||||||
|
makeFlags = [ "debug=no" "PREFIX=${placeholder "out"}" ];
|
||||||
|
|
||||||
|
preConfigure = ''
|
||||||
|
export version="v${version}";
|
||||||
|
'';
|
||||||
|
|
||||||
|
enableParallelBuilding = true;
|
||||||
|
|
||||||
|
doInstallCheck = true;
|
||||||
|
installCheckPhase = ''
|
||||||
|
$out/bin/kak -ui json -e "kill 0"
|
||||||
|
'';
|
||||||
|
|
||||||
|
postInstall = ''
|
||||||
|
# make share/kak/autoload a directory
|
||||||
|
cd "$out/share/kak"
|
||||||
|
autoload_target=$(readlink autoload)
|
||||||
|
rm autoload
|
||||||
|
mkdir autoload
|
||||||
|
ln -s --relative "$autoload_target" autoload
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
kak-lsp = pkgs.libs.crane.buildPackage {
|
||||||
|
src = pkgs.sources.kak-lsp;
|
||||||
|
buildInputs = (with pkgs;
|
||||||
|
lib.optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [ Security SystemConfiguration CoreServices ])
|
||||||
|
) ++ (with pkgs; [ libiconv ]);
|
||||||
|
};
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [ ../modules/programs/my-kakoune ./kaktex.nix ];
|
||||||
|
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
# ctags for peneira
|
||||||
|
universal-ctags
|
||||||
|
# tree-sitter for kak
|
||||||
|
kak-tree-sitter
|
||||||
|
];
|
||||||
|
|
||||||
|
# xdg.configFile."kak-tree-sitter/config.toml".source = ./kak-tree-sitter.toml;
|
||||||
|
|
||||||
|
# Enable the kakoune package.
|
||||||
|
programs.my-kakoune.enable = true;
|
||||||
|
programs.my-kakoune.enable-fish-session = true;
|
||||||
|
programs.kak-lsp.enable = true;
|
||||||
|
programs.kak-lsp.package = kak-lsp;
|
||||||
|
programs.kak-lsp.semanticTokens.additionalFaces = [
|
||||||
|
# Typst
|
||||||
|
{ face = "header"; token = "heading"; }
|
||||||
|
{ face = "ts_markup_link_url"; token = "link"; }
|
||||||
|
{ face = "ts_markup_link_uri"; token = "ref"; }
|
||||||
|
{ face = "ts_markup_link_label"; token = "label"; }
|
||||||
|
{ face = "ts_property"; token = "pol"; }
|
||||||
|
{ face = "ts_markup_list_checked"; token = "marker"; }
|
||||||
|
{ face = "ts_constant_builtin_boolean"; token = "bool"; }
|
||||||
|
{ face = "ts_keyword_control"; token = "delim"; }
|
||||||
|
{ face = "ts_number"; token = "text"; modifiers = [ "math" ]; }
|
||||||
|
{ face = "ts_markup_bold"; token = "text"; modifiers = [ "strong" ]; }
|
||||||
|
{ face = "ts_markup_italic"; token = "text"; modifiers = [ "emph" ]; }
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.kak-lsp.languages.typescript = {
|
||||||
|
args = [ "--stdio" ];
|
||||||
|
command = "typescript-language-server";
|
||||||
|
filetypes = [ "typescript" ];
|
||||||
|
roots = [ "package.json" ];
|
||||||
|
};
|
||||||
|
programs.kak-lsp.languages.scala = {
|
||||||
|
command = "metals";
|
||||||
|
filetypes = [ "scala" ];
|
||||||
|
roots = [ "build.sbt" ];
|
||||||
|
settings_section = "metals";
|
||||||
|
settings.metals = {
|
||||||
|
enableSemanticHighlighting = true;
|
||||||
|
showInferredType = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
programs.kak-lsp.languages.latex = {
|
||||||
|
command = "texlab";
|
||||||
|
filetypes = [ "latex" ];
|
||||||
|
roots = [ ".git" "main.tex" "all.tex" ];
|
||||||
|
settings_section = "texlab";
|
||||||
|
settings.texlab = {
|
||||||
|
build.executable = "latexmk";
|
||||||
|
build.args = [ "-pdf" "-shell-escape" "-interaction=nonstopmode" "-synctex=1" "%f" ];
|
||||||
|
|
||||||
|
build.forwardSearchAfter = true;
|
||||||
|
build.onSave = true;
|
||||||
|
|
||||||
|
forwardSearch =
|
||||||
|
(if pkgs.stdenv.isDarwin then {
|
||||||
|
executable = "/Applications/Skim.app/Contents/SharedSupport/displayline";
|
||||||
|
args = [ "-r" "-g" "%l" "%p" "%f" ];
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
executable = "${pkgs.zathura}/bin/zathura";
|
||||||
|
args = [ "--synctex-forward" "%l:1:%f" "%p" "-x" "/home/nki/.bin/kaktex jump %{input} %{line}" ];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
programs.kak-lsp.languages.typst = {
|
||||||
|
command = "${pkgs.typst-lsp}/bin/typst-lsp";
|
||||||
|
filetypes = [ "typst" ];
|
||||||
|
roots = [ ".git" "main.typ" ];
|
||||||
|
settings_section = "typst-lsp";
|
||||||
|
settings.typst-lsp = { };
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.my-kakoune.tree-sitter.extraAliases = {
|
||||||
|
# Scala stuff
|
||||||
|
method = "function";
|
||||||
|
module = "namespace";
|
||||||
|
function_call = "function";
|
||||||
|
method_call = "method";
|
||||||
|
|
||||||
|
boolean = "constant_builtin_boolean";
|
||||||
|
number = "constant_numeric";
|
||||||
|
float = "constant_numeric_float";
|
||||||
|
|
||||||
|
type_qualifier = "keyword_special";
|
||||||
|
storageclass = "keyword_storage_modifier";
|
||||||
|
conditional = "keyword_conditional";
|
||||||
|
include = "keyword_control_import";
|
||||||
|
};
|
||||||
|
programs.my-kakoune.tree-sitter.languages = {
|
||||||
|
scala =
|
||||||
|
let
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "tree-sitter";
|
||||||
|
repo = "tree-sitter-scala";
|
||||||
|
rev = "8062487fb3b7f3ce1bb7ce1fd1c84bed60c75203";
|
||||||
|
sha256 =
|
||||||
|
if pkgs.stdenv.isDarwin
|
||||||
|
then "sha256-Ff8vRw7UswvPRGQS6nlSxqz46pX4eLNckuSbqa1yvtA="
|
||||||
|
else "sha256-G83H3RJddeIdLT6JssIDD5KXVnZE6vk1chl3RpQjdCI=";
|
||||||
|
leaveDotGit = true;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
grammar.src = src;
|
||||||
|
queries.src = src;
|
||||||
|
queries.path = "queries/scala";
|
||||||
|
};
|
||||||
|
haskell =
|
||||||
|
let
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "tree-sitter";
|
||||||
|
repo = "tree-sitter-haskell";
|
||||||
|
rev = "ba0bfb0e5d8e9e31c160d287878c6f26add3ec08";
|
||||||
|
sha256 =
|
||||||
|
if pkgs.stdenv.isDarwin
|
||||||
|
then "sha256-lW3E4gSZV/m2RfofUqeiCu8KDz06YEvXbYKs8smXFi4="
|
||||||
|
else "sha256-nocX9L8vD655nzky4PQulygWAjKGC1rh3SYDr7t4wBQ=";
|
||||||
|
leaveDotGit = true;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
grammar.src = src;
|
||||||
|
grammar.compile.args = [ "-c" "-fpic" "../parser.c" "../scanner.c" "../unicode.h" "-I" ".." ];
|
||||||
|
queries.src = src;
|
||||||
|
queries.path = "queries";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.my-kakoune.package = kakounePkg;
|
||||||
|
programs.my-kakoune.rc =
|
||||||
|
builtins.readFile ./kakrc + ''
|
||||||
|
|
||||||
|
# Source any settings in the current working directory,
|
||||||
|
# recursive upwards
|
||||||
|
evaluate-commands %sh{
|
||||||
|
${pkgs.writeScript "source-pwd" (builtins.readFile ./source-pwd)}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
programs.my-kakoune.extraFaces = {
|
||||||
|
Default = "%opt{white},%opt{background}";
|
||||||
|
BufferPadding = "%opt{background},%opt{background}";
|
||||||
|
MenuForeground = "blue,white+bF";
|
||||||
|
MenuBackground = "bright-blue,white+F";
|
||||||
|
Information = "bright-blue,white";
|
||||||
|
# Markdown help color scheme
|
||||||
|
InfoDefault = "Information";
|
||||||
|
InfoBlock = "@block";
|
||||||
|
InfoBlockQuote = "+i@block";
|
||||||
|
InfoBullet = "@bullet";
|
||||||
|
InfoHeader = "@header";
|
||||||
|
InfoLink = "@link";
|
||||||
|
InfoLinkMono = "+b@mono";
|
||||||
|
InfoMono = "@mono";
|
||||||
|
InfoRule = "+b@Information";
|
||||||
|
InfoDiagnosticError = "@DiagnosticError";
|
||||||
|
InfoDiagnosticHint = "@DiagnosticHint";
|
||||||
|
InfoDiagnosticInformation = "@Information";
|
||||||
|
InfoDiagnosticWarning = "@DiagnosticWarning";
|
||||||
|
# Extra faces
|
||||||
|
macro = "+b@function";
|
||||||
|
method = "+i@function";
|
||||||
|
format_specifier = "+i@string";
|
||||||
|
mutable_variable = "+u@variable";
|
||||||
|
class = "+b@variable";
|
||||||
|
};
|
||||||
|
programs.my-kakoune.autoload = [
|
||||||
|
# My own scripts
|
||||||
|
{
|
||||||
|
name = "latex.kak";
|
||||||
|
src = ./autoload/latex.kak;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "markdown.kak";
|
||||||
|
src = ./autoload/markdown.kak;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Plugins
|
||||||
|
{
|
||||||
|
name = "luar";
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "gustavo-hms";
|
||||||
|
repo = "luar";
|
||||||
|
rev = "2f430316f8fc4d35db6c93165e2e77dc9f3d0450";
|
||||||
|
sha256 = "sha256-vHn/V3sfzaxaxF8OpA5jPEuPstOVwOiQrogdSGtT6X4=";
|
||||||
|
};
|
||||||
|
activationScript = ''
|
||||||
|
# Enable luar
|
||||||
|
require-module luar
|
||||||
|
# Use luajit
|
||||||
|
set-option global luar_interpreter ${pkgs.luajit}/bin/luajit
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "peneira";
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "natsukagami";
|
||||||
|
repo = "peneira";
|
||||||
|
rev = "743b9971472853a752475e7c070ce99089c6840c";
|
||||||
|
sha256 = "sha256-E4ndbF9YC1p0KrvSuGgwmG1Y2IGTuGKJo/AuMixhzlM=";
|
||||||
|
};
|
||||||
|
activationScript = ''
|
||||||
|
require-module peneira
|
||||||
|
|
||||||
|
# Change selection color
|
||||||
|
set-face global PeneiraSelected @PrimarySelection
|
||||||
|
|
||||||
|
# Buffers list
|
||||||
|
define-command -hidden peneira-buffers %{
|
||||||
|
peneira 'buffers: ' %{ printf '%s\n' $kak_quoted_buflist } %{
|
||||||
|
buffer %arg{1}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Grep in the current location
|
||||||
|
define-command peneira-grep %{
|
||||||
|
peneira 'line: ' "rg -n ." %{
|
||||||
|
lua %arg{1} %{
|
||||||
|
local file, line = arg[1]:match("([^:]+):(%d+):")
|
||||||
|
kak.edit(file, line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# A peneira menu
|
||||||
|
declare-user-mode fuzzy-match-menu
|
||||||
|
|
||||||
|
map -docstring "Switch to buffer" global fuzzy-match-menu b ": peneira-buffers<ret>"
|
||||||
|
map -docstring "Symbols" global fuzzy-match-menu s ": peneira-symbols<ret>"
|
||||||
|
map -docstring "Lines" global fuzzy-match-menu l ": peneira-lines<ret>"
|
||||||
|
map -docstring "Lines in the current directory" global fuzzy-match-menu g ": peneira-grep<ret>"
|
||||||
|
map -docstring "Files in project" global fuzzy-match-menu f ": peneira-files<ret>"
|
||||||
|
map -docstring "Files in currently opening file's directory" global fuzzy-match-menu F ": peneira-local-files<ret>"
|
||||||
|
|
||||||
|
# Bind menu to user mode
|
||||||
|
map -docstring "Fuzzy matching" global user f ": enter-user-mode fuzzy-match-menu<ret>"
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "kakoune-focus";
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "caksoylar";
|
||||||
|
repo = "kakoune-focus";
|
||||||
|
rev = "949c0557cd4c476822acfa026ca3c50f3d38a3c0";
|
||||||
|
sha256 = "sha256-ZV7jlLJQyL420YG++iC9rq1SMjo3WO5hR9KVvJNUiCs=";
|
||||||
|
};
|
||||||
|
activationScript = ''
|
||||||
|
map global user <space> ': focus-toggle<ret>' -docstring "toggle selections focus"
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "kakoune-inc-dec";
|
||||||
|
src = pkgs.fetchFromGitLab {
|
||||||
|
owner = "Screwtapello";
|
||||||
|
repo = "kakoune-inc-dec";
|
||||||
|
rev = "7bfe9c51";
|
||||||
|
sha256 = "0f33wqxqbfygxypf348jf1fiscac161wf2xvnh8zwdd3rq5yybl0";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "racket.kak";
|
||||||
|
src = (builtins.fetchTree {
|
||||||
|
type = "git";
|
||||||
|
url = "https://bitbucket.org/KJ_Duncan/kakoune-racket.kak.git";
|
||||||
|
rev = "e397042009b46916ff089d79166ec0e8ca813a18";
|
||||||
|
narHash = "sha256-IcxFmvG0jqpMCG/dT9crVRgPgMGKkic6xwrnW5z4+bc=";
|
||||||
|
}) + "/rc";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "kakoune-discord";
|
||||||
|
src = (builtins.getFlake "github:natsukagami/kakoune-discord/03f95e40d6efd8fd3de7bca31653d43de2dcfc5f").packages.${pkgs.system}.kakoune-discord-rc + "/rc";
|
||||||
|
}
|
||||||
|
rec {
|
||||||
|
name = "kakoune-mirror";
|
||||||
|
src = pkgs.fetchFromGitHub
|
||||||
|
{
|
||||||
|
owner = "Delapouite";
|
||||||
|
repo = "kakoune-mirror";
|
||||||
|
rev = "5710635f440bcca914d55ff2ec1bfcba9efe0f15";
|
||||||
|
sha256 = "sha256-uslx4zZhvjUylrPWvTOugsKYKKpF0EEz1drc1Ckrpjk=";
|
||||||
|
} + "/mirror.kak";
|
||||||
|
wrapAsModule = true;
|
||||||
|
activationScript = ''
|
||||||
|
require-module ${name}
|
||||||
|
|
||||||
|
# Bind <a-w> to ${name}
|
||||||
|
map global normal <a-w> ': enter-user-mode -lock mirror<ret>'
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "unicode-math";
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "natsukagami";
|
||||||
|
repo = "kakoune-unicode-math";
|
||||||
|
rev = "08dff25da2b86ee0b0777091992bc7fb28c3cb1d";
|
||||||
|
# sha256 = lib.fakeSha256;
|
||||||
|
sha256 = "sha256-j0L1ARex1i2ma8sGLYwgkfAbh0jWKh/6QGHFaxPXIKc=";
|
||||||
|
fetchSubmodules = true;
|
||||||
|
};
|
||||||
|
activationScript = ''
|
||||||
|
require-module unicode-math
|
||||||
|
|
||||||
|
# Bind <c-s> to the menu
|
||||||
|
map global insert <c-s> '<a-;>: insert-unicode '
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "kakoune-buffers";
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "Delapouite";
|
||||||
|
repo = "kakoune-buffers";
|
||||||
|
rev = "6b2081f5b7d58c72de319a5cba7bf628b6802881";
|
||||||
|
sha256 = "sha256-jOSrzGcLJjLK1GiTSsl2jLmQMPbPxjycR0pwF5t/eV0=";
|
||||||
|
};
|
||||||
|
activationScript = ''
|
||||||
|
# Suggested hook
|
||||||
|
|
||||||
|
hook global WinDisplay .* info-buffers
|
||||||
|
|
||||||
|
# Suggested mappings
|
||||||
|
|
||||||
|
map global user b ':enter-buffers-mode<ret>' -docstring 'buffers…'
|
||||||
|
map global normal ^ ':enter-buffers-mode<ret>' -docstring 'buffers…'
|
||||||
|
map global user B ':enter-user-mode -lock buffers<ret>' -docstring 'buffers (lock)…'
|
||||||
|
|
||||||
|
# Suggested aliases
|
||||||
|
|
||||||
|
alias global bd delete-buffer
|
||||||
|
alias global bf buffer-first
|
||||||
|
alias global bl buffer-last
|
||||||
|
alias global bo buffer-only
|
||||||
|
alias global bo! buffer-only-force
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
];
|
||||||
|
programs.my-kakoune.themes = {
|
||||||
|
catppuccin-latte = builtins.fetchurl {
|
||||||
|
url = "https://raw.githubusercontent.com/catppuccin/kakoune/f6d43770609433c45046632f1bb68d1395305dbb/colors/catppuccin_latte.kak";
|
||||||
|
sha256 = "sha256:0ycvxs8hmsvd0zrpxiby16wzmapvmz6p34b6j343pc1girw6fi4i";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -1,32 +1,31 @@
|
||||||
# ## Set some color overrides
|
# Enable kak-tree-sitter
|
||||||
# set global kts_yellow "rgb:e2b75e"
|
eval %sh{ kak-tree-sitter --kakoune -d }
|
||||||
# set global kts_teal "rgb:008080"
|
|
||||||
# set global kts_mauve "rgb:c264ff"
|
|
||||||
# set global kts_sky "rgb:6aa622"
|
|
||||||
# Color scheme
|
# Color scheme
|
||||||
colorscheme catppuccin-latte
|
colorscheme catppuccin-latte
|
||||||
set-face global module "%opt{sapphire}"
|
set global background default
|
||||||
set global base "default"
|
|
||||||
|
|
||||||
# Set indentation guides
|
|
||||||
add-highlighter global/indent-guides show-whitespaces -tab " " -spc " " -lf " " -nbsp " "
|
|
||||||
set-face global Whitespace default,default
|
|
||||||
set-face global WhitespaceIndent +d@comment
|
|
||||||
|
|
||||||
# Assistant
|
# Assistant
|
||||||
set global ui_options terminal_assistant=cat
|
set global ui_options terminal_assistant=cat
|
||||||
|
|
||||||
# Enable line numbers
|
# Enable line numbers
|
||||||
hook global WinCreate .* %{
|
addhl global/ number-lines
|
||||||
addhl window/number-lines number-lines
|
|
||||||
}
|
|
||||||
|
|
||||||
set global grepcmd "rg --line-number --no-column --no-heading --color=never "
|
set global grepcmd "rg --line-number --no-column --no-heading --color=never "
|
||||||
|
|
||||||
# Kitty-specific options
|
# Floating terminal
|
||||||
hook -group windowing global KakBegin .* %{
|
# define-command floating-terminal -params 1 -docstring "Open a floating terminal running the given command" %{
|
||||||
set global kitty_window_type os-window
|
# evaluate-commands -save-regs 'a' %{
|
||||||
}
|
# set-register a %arg{@}
|
||||||
|
# evaluate-commands %sh{
|
||||||
|
# alacritty \
|
||||||
|
# --class=alacritty,floating \
|
||||||
|
# -o window.dimensions.lines=24 \
|
||||||
|
# -o window.dimensions.columns=120 \
|
||||||
|
# -e sh -c "$kak_quoted_reg_a" < /dev/null > /dev/null 2>&1 &
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# map global user t -docstring "Open a side terminal on the current directory" ' :iterm-terminal-horizontal fish<ret>'
|
||||||
|
|
||||||
# Comment line and block
|
# Comment line and block
|
||||||
map global normal <#> ': comment-line<ret>'
|
map global normal <#> ': comment-line<ret>'
|
||||||
|
@ -39,9 +38,9 @@ map global goto f -docstring "current grep-jump match" '<esc>: grep-jump<ret>'
|
||||||
hook global RegisterModified '"' %{ nop %sh{
|
hook global RegisterModified '"' %{ nop %sh{
|
||||||
printf "%s" "$kak_main_reg_dquote" | pbcopy >/dev/null 2>/dev/null &
|
printf "%s" "$kak_main_reg_dquote" | pbcopy >/dev/null 2>/dev/null &
|
||||||
}}
|
}}
|
||||||
map global user P -docstring "Paste before cursor from clipboard" '! pbpaste -n | cat<ret>'
|
map global user P -docstring "Paste before cursor from clipboard" '! pbpaste<ret>'
|
||||||
map global user p -docstring "Paste after cursor from clipboard" '<a-!> pbpaste -n | cat<ret>'
|
map global user p -docstring "Paste after cursor from clipboard" '<a-!> pbpaste<ret>'
|
||||||
map global user R -docstring "Replace selection with text from clipboard" '<a-d>! pbpaste -n | cat<ret>'
|
map global user R -docstring "Replace selection with text from clipboard" '<a-d>! pbpaste<ret>'
|
||||||
define-command -params 0 -docstring "Copy line down" copyline %{
|
define-command -params 0 -docstring "Copy line down" copyline %{
|
||||||
execute-keys -draft 'xy'%val{count}'P'
|
execute-keys -draft 'xy'%val{count}'P'
|
||||||
}
|
}
|
||||||
|
@ -59,13 +58,11 @@ map global normal D ": delete-current-brackets<ret>"
|
||||||
|
|
||||||
# Tab sizes
|
# Tab sizes
|
||||||
hook global InsertChar \t %{ exec -draft -itersel h@ }
|
hook global InsertChar \t %{ exec -draft -itersel h@ }
|
||||||
|
set global tabstop 4
|
||||||
|
set global indentwidth 4
|
||||||
|
hook global WinSetOption filetype=(c|cpp|haskell|nix|yaml) %{
|
||||||
set global tabstop 2
|
set global tabstop 2
|
||||||
set global indentwidth 2
|
set global indentwidth 2
|
||||||
|
|
||||||
# Language-specific tabstop with override
|
|
||||||
hook global WinSetOption filetype=(rust) %{
|
|
||||||
set window tabstop 4
|
|
||||||
set window indentwidth 4
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Ctrl + a in insert mode = esc
|
# Ctrl + a in insert mode = esc
|
||||||
|
@ -88,14 +85,47 @@ hook global InsertCompletionHide .* %{
|
||||||
unmap window insert <s-tab> <c-p>
|
unmap window insert <s-tab> <c-p>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Enable LSP
|
||||||
|
try %{
|
||||||
|
eval %sh{test -z "$WE_STARTED_KAK" && kak-lsp --kakoune -s $kak_session}
|
||||||
|
}
|
||||||
|
hook global WinSetOption filetype=(racket|rust|python|go|javascript|typescript|c|cpp|tex|latex|fsharp|ocaml|haskell|nix|scala|typst) %{
|
||||||
|
lsp-enable-window
|
||||||
|
map window lsp N -docstring "Display the next message request" ": lsp-show-message-request-next<ret>"
|
||||||
|
map window normal <c-l> ": enter-user-mode lsp<ret>"
|
||||||
|
map window normal <c-h> ": lsp-hover<ret>"
|
||||||
|
map window normal <c-s-h> ": lsp-hover-buffer<ret>"
|
||||||
|
# lsp-auto-hover-insert-mode-enable
|
||||||
|
set window lsp_hover_anchor true
|
||||||
|
|
||||||
|
}
|
||||||
|
hook global WinSetOption filetype=(racket|rust|python|go|javascript|typescript|c|cpp|tex|latex|haskell|nix) %{
|
||||||
|
# Format the document if possible
|
||||||
|
hook window BufWritePre .* %{ lsp-formatting-sync }
|
||||||
|
}
|
||||||
|
|
||||||
|
hook global WinSetOption filetype=(rust) %{
|
||||||
|
# Enable inlay hints
|
||||||
|
lsp-inlay-hints-enable window
|
||||||
|
}
|
||||||
|
|
||||||
|
hook global WinSetOption filetype=(rust|go|fsharp|typst) %{
|
||||||
|
hook window -group semantic-tokens BufReload .* lsp-semantic-tokens
|
||||||
|
hook window -group semantic-tokens NormalIdle .* lsp-semantic-tokens
|
||||||
|
hook window -group semantic-tokens InsertIdle .* lsp-semantic-tokens
|
||||||
|
hook -once -always window WinSetOption filetype=.* %{
|
||||||
|
remove-hooks window semantic-tokens
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# <a-a> in Insert mode moves to end of line.
|
# <a-a> in Insert mode moves to end of line.
|
||||||
map global insert <a-a> '<esc>A'
|
map global insert <a-a> '<esc>A'
|
||||||
|
|
||||||
hook global WinSetOption filetype=(fsharp) %{
|
hook global WinSetOption filetype=(fsharp) %{
|
||||||
set-option window comment_line "//"
|
set-option window comment_line "//"
|
||||||
# Set up formatting
|
# Set up formatting
|
||||||
# set-option window formatcmd "~/.dotnet/tools/fantomas --stdin --stdout"
|
set-option window formatcmd "~/.dotnet/tools/fantomas --stdin --stdout"
|
||||||
# hook window -group fsharp-format BufWritePre .* %{ format }
|
hook window -group fsharp-format BufWritePre .* %{ format }
|
||||||
}
|
}
|
||||||
|
|
||||||
hook global WinSetOption filetype=(ocaml) %{
|
hook global WinSetOption filetype=(ocaml) %{
|
||||||
|
@ -112,6 +142,14 @@ hook global WinSetOption filetype=(rust) %{
|
||||||
set-option buffer makecmd "cargo check"
|
set-option buffer makecmd "cargo check"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hook global WinSetOption filetype=(scala) %{
|
||||||
|
# Format the document if possible
|
||||||
|
hook -group scala-fmt window BufWritePre .* %{ lsp-formatting-sync }
|
||||||
|
|
||||||
|
set window tabstop 2
|
||||||
|
set window indentwidth 2
|
||||||
|
}
|
||||||
|
|
||||||
hook global WinSetOption filetype=(typst) %{
|
hook global WinSetOption filetype=(typst) %{
|
||||||
set-option window comment_line "//"
|
set-option window comment_line "//"
|
||||||
set-option window comment_block_begin "/*"
|
set-option window comment_block_begin "/*"
|
||||||
|
@ -126,6 +164,15 @@ hook global WinSetOption filetype=(typst) %{
|
||||||
hook -once -always window WinSetOption filetype=.* %{ remove-hooks window markdown-.+ }
|
hook -once -always window WinSetOption filetype=.* %{ remove-hooks window markdown-.+ }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
define-command -params 0 -docstring "Set up build" scala-build-connect %{
|
||||||
|
lsp-execute-command 'build-connect' '"[]"'
|
||||||
|
}
|
||||||
|
|
||||||
|
define-command -params 0 -docstring "Import build" scala-build-import %{
|
||||||
|
lsp-execute-command 'build-import' '"[]"'
|
||||||
|
}
|
||||||
|
|
||||||
def -hidden insert-c-n %{
|
def -hidden insert-c-n %{
|
||||||
try %{
|
try %{
|
||||||
lsp-snippets-select-next-placeholders
|
lsp-snippets-select-next-placeholders
|
||||||
|
@ -149,7 +196,7 @@ hook global BufCreate .*[.]md %{
|
||||||
add-highlighter buffer/ wrap
|
add-highlighter buffer/ wrap
|
||||||
}
|
}
|
||||||
|
|
||||||
hook global BufCreate .*[.](sc|sbt|mill) %{
|
hook global BufCreate .*[.]sc %{
|
||||||
set-option buffer filetype scala
|
set-option buffer filetype scala
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,19 +205,12 @@ hook global BufCreate .*[.]typ %{
|
||||||
add-highlighter buffer/ wrap
|
add-highlighter buffer/ wrap
|
||||||
}
|
}
|
||||||
|
|
||||||
hook global BufCreate .*[.]templ %{
|
|
||||||
set-option buffer filetype templ
|
|
||||||
set-option buffer comment_line "//"
|
|
||||||
}
|
|
||||||
|
|
||||||
hook global BufCreate .*[.]hylo %{
|
|
||||||
set-option buffer filetype hylo
|
|
||||||
set-option buffer comment_line "//"
|
|
||||||
}
|
|
||||||
|
|
||||||
hook global BufOpenFile .* %{
|
hook global BufOpenFile .* %{
|
||||||
modeline-parse
|
modeline-parse
|
||||||
}
|
}
|
||||||
|
|
||||||
map global normal <a-[> ':inc-dec-modify-numbers + %val{count}<ret>'
|
map global normal <a-[> ':inc-dec-modify-numbers + %val{count}<ret>'
|
||||||
map global normal <a-]> ':inc-dec-modify-numbers - %val{count}<ret>'
|
map global normal <a-]> ':inc-dec-modify-numbers - %val{count}<ret>'
|
||||||
|
|
||||||
|
# Discord integration
|
||||||
|
discord-presence-enable
|
|
@ -1,11 +1,13 @@
|
||||||
|
#!/usr/bin/env fish
|
||||||
|
|
||||||
function usage
|
function usage
|
||||||
echo "Usage: "
|
echo "Usage: "
|
||||||
echo " kaktex set [client] [session]"
|
echo " kaktex set [client] [session]"
|
||||||
echo " kaktex jump [file] [line] [column]"
|
echo " kaktex jump [file] [line]"
|
||||||
exit 1
|
exit 1
|
||||||
end
|
end
|
||||||
|
|
||||||
if test (count $argv) -lt 3
|
if test (count $argv) -ne 3
|
||||||
usage
|
usage
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -17,7 +19,7 @@ switch $argv[1]
|
||||||
echo "
|
echo "
|
||||||
evaluate-commands -client $_kaktex_client %{
|
evaluate-commands -client $_kaktex_client %{
|
||||||
evaluate-commands -try-client $_kaktex_client %{
|
evaluate-commands -try-client $_kaktex_client %{
|
||||||
edit -existing -- $argv[2] $(math $argv[3] + 1) $(math $argv[4] + 1)
|
edit -- $argv[2] $argv[3]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
" | kak -p $_kaktex_session
|
" | kak -p $_kaktex_session
|
24
home/kakoune/kaktex.nix
Normal file
24
home/kakoune/kaktex.nix
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
kaktexScript = ./kaktex;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# Create kak-tex executable
|
||||||
|
home.file.kaktex = {
|
||||||
|
source = kaktexScript;
|
||||||
|
executable = true;
|
||||||
|
target = ".bin/kaktex";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Source kaktex whenever we have a tex file
|
||||||
|
programs.my-kakoune.rc = ''
|
||||||
|
hook global WinSetOption filetype=(tex|latex) %{
|
||||||
|
hook window WinDisplay '.*' %{
|
||||||
|
eval %sh{
|
||||||
|
${kaktexScript} set $kak_client $kak_session
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
#!/usr/bin/env fish
|
||||||
|
|
||||||
if test (pwd) = "/home/natsukagami/.config/kak"
|
if test (pwd) = "/home/natsukagami/.config/kak"
|
||||||
exit 0
|
exit 0
|
||||||
end
|
end
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ config, pkgs, lib, ... }:
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [ ./common.nix ];
|
imports = [ ./common.nix ];
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
let
|
let
|
||||||
discord = pkgs.armcord.override { nss = pkgs.nss_latest; };
|
discord =
|
||||||
|
(pkgs.armcord.override { nss = pkgs.nss_latest; }).overrideAttrs (attrs: {
|
||||||
|
postInstall = ''
|
||||||
|
# Wrap the startup command
|
||||||
|
makeWrapper $out/opt/ArmCord/armcord $out/bin/armcord \
|
||||||
|
"''${gappsWrapperArgs[@]}" \
|
||||||
|
--prefix XDG_DATA_DIRS : "${pkgs.gtk3}/share/gsettings-schemas/${pkgs.gtk3.name}/" \
|
||||||
|
--add-flags "--ozone-platform=x11 --enable-features=UseOzonePlatform --enable-features=WebRTCPipeWireCapturer" \
|
||||||
|
--prefix LD_LIBRARY_PATH : "${lib.makeLibraryPath attrs.buildInputs}" \
|
||||||
|
--suffix PATH : ${lib.makeBinPath [ pkgs.xdg-utils ]}
|
||||||
|
'';
|
||||||
|
});
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
|
@ -15,8 +21,7 @@ in
|
||||||
# We use our own firefox
|
# We use our own firefox
|
||||||
# ./firefox.nix
|
# ./firefox.nix
|
||||||
# osu!
|
# osu!
|
||||||
# ./osu
|
# ./osu.nix
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# Home Manager needs a bit of information about you and the
|
# Home Manager needs a bit of information about you and the
|
||||||
|
@ -25,7 +30,7 @@ in
|
||||||
home.homeDirectory = "/home/nki";
|
home.homeDirectory = "/home/nki";
|
||||||
|
|
||||||
nki.programs.kitty.enable = true;
|
nki.programs.kitty.enable = true;
|
||||||
nki.programs.kitty.fontSize = 16;
|
nki.programs.kitty.fontSize = 18;
|
||||||
programs.fish.shellInit = lib.mkAfter ''
|
programs.fish.shellInit = lib.mkAfter ''
|
||||||
set -eg MESA_GL_VERSION_OVERRIDE
|
set -eg MESA_GL_VERSION_OVERRIDE
|
||||||
set -eg MESA_GLSL_VERSION_OVERRIDE
|
set -eg MESA_GLSL_VERSION_OVERRIDE
|
||||||
|
@ -35,9 +40,12 @@ in
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# More packages
|
# More packages
|
||||||
home.packages = (
|
home.packages = (with pkgs; [
|
||||||
with pkgs;
|
# CLI stuff
|
||||||
[
|
python3
|
||||||
|
zip
|
||||||
|
# TeX
|
||||||
|
texlive.combined.scheme-full
|
||||||
mate.mate-terminal
|
mate.mate-terminal
|
||||||
|
|
||||||
firefox-wayland
|
firefox-wayland
|
||||||
|
@ -45,23 +53,26 @@ in
|
||||||
discord
|
discord
|
||||||
|
|
||||||
typora
|
typora
|
||||||
]
|
|
||||||
);
|
# Java & sbt
|
||||||
|
openjdk11
|
||||||
|
sbt
|
||||||
|
]);
|
||||||
|
|
||||||
# Graphical set up
|
# Graphical set up
|
||||||
linux.graphical.type = "wayland";
|
linux.graphical.type = "wayland";
|
||||||
linux.graphical.wallpaper = ./images/wallpaper-macbook.jpg;
|
linux.graphical.wallpaper = ./images/wallpaper-macbook.jpg;
|
||||||
# Enable sway
|
# Enable sway
|
||||||
programs.my-sway.enable = true;
|
programs.my-sway.enable = true;
|
||||||
programs.my-sway.fontSize = 14.0;
|
programs.my-sway.fontSize = 12.0;
|
||||||
programs.my-sway.enableLaptop = true;
|
programs.my-sway.enableLaptopBars = true;
|
||||||
programs.my-waybar.enableMpd = false;
|
programs.my-sway.enableMpd = false;
|
||||||
programs.my-sway.discord = "${discord}/bin/armcord";
|
programs.my-sway.discord = "${discord}/bin/armcord";
|
||||||
# Keyboard options
|
# Keyboard options
|
||||||
wayland.windowManager.sway.config.input."type:keyboard".xkb_layout = "jp";
|
wayland.windowManager.sway.config.input."type:keyboard".xkb_layout = "jp";
|
||||||
wayland.windowManager.sway.config.output."eDP-1" = {
|
wayland.windowManager.sway.config.output."eDP-1" = {
|
||||||
mode = "2560x1600@60Hz";
|
mode = "2560x1600@60Hz";
|
||||||
scale = "1.25";
|
scale = "1.5";
|
||||||
subpixel = "vrgb";
|
subpixel = "vrgb";
|
||||||
};
|
};
|
||||||
wayland.windowManager.sway.config.input."1452:641:Apple_Internal_Keyboard_/_Trackpad" = {
|
wayland.windowManager.sway.config.input."1452:641:Apple_Internal_Keyboard_/_Trackpad" = {
|
||||||
|
@ -101,7 +112,7 @@ in
|
||||||
|
|
||||||
home.file.".gnupg/gpg-agent.conf" = {
|
home.file.".gnupg/gpg-agent.conf" = {
|
||||||
text = ''
|
text = ''
|
||||||
pinentry-program ${pkgs.pinentry-gnome3}/bin/pinentry-gnome3
|
pinentry-program ${pkgs.pinentry-gnome}/bin/pinentry-gnome3
|
||||||
'';
|
'';
|
||||||
onChange = ''
|
onChange = ''
|
||||||
echo "Reloading gpg-agent"
|
echo "Reloading gpg-agent"
|
||||||
|
@ -110,6 +121,10 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
# Autostart
|
# Autostart
|
||||||
|
xdg.configFile."autostart/polkit.desktop".text = ''
|
||||||
|
${builtins.readFile "${pkgs.pantheon.pantheon-agent-polkit}/etc/xdg/autostart/io.elementary.desktop.agent-polkit.desktop"}
|
||||||
|
OnlyShowIn=sway;
|
||||||
|
'';
|
||||||
xdg.configFile."autostart/input-remapper-autoload.desktop".source =
|
xdg.configFile."autostart/input-remapper-autoload.desktop".source =
|
||||||
"${pkgs.input-remapper}/share/applications/input-remapper-autoload.desktop";
|
"${pkgs.input-remapper}/share/applications/input-remapper-autoload.desktop";
|
||||||
|
|
||||||
|
@ -133,3 +148,4 @@ in
|
||||||
# changes in each release.
|
# changes in each release.
|
||||||
home.stateVersion = "21.05";
|
home.stateVersion = "21.05";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
|
@ -33,10 +28,7 @@ in
|
||||||
};
|
};
|
||||||
shell = {
|
shell = {
|
||||||
program = "/bin/sh";
|
program = "/bin/sh";
|
||||||
args = [
|
args = [ "-ic" "${config.programs.fish.package}/bin/fish" ];
|
||||||
"-ic"
|
|
||||||
"${config.programs.fish.package}/bin/fish"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
colors = {
|
colors = {
|
||||||
# Default colors
|
# Default colors
|
||||||
|
@ -65,11 +57,7 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
key_bindings = [
|
key_bindings = [
|
||||||
{
|
{ key = "C"; mods = "Alt|Control"; action = "SpawnNewInstance"; }
|
||||||
key = "C";
|
|
||||||
mods = "Alt|Control";
|
|
||||||
action = "SpawnNewInstance";
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,110 +1,35 @@
|
||||||
{
|
{ pkgs, lib, config, ... }:
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.linux.graphical;
|
cfg = config.linux.graphical;
|
||||||
|
|
||||||
vscode = with pkgs; if stdenv.isAarch64 then unstable.vscode else unstable.vscode-fhs;
|
vscode = with pkgs; if stdenv.isAarch64 then unstable.vscode else unstable.vscode-fhs;
|
||||||
|
|
||||||
wifi-indicator = pkgs.writeScriptBin "wifi-indicator" ''
|
alwaysStartup = with pkgs; [ ];
|
||||||
#!/usr/bin/env fish
|
|
||||||
|
|
||||||
set wifi_output (${lib.getExe pkgs.iw} wlan0 link | rg "SSID: (.+)" --replace '🛜 $1' | string trim)
|
|
||||||
|
|
||||||
if test -z $wifi_output
|
|
||||||
echo "❌ not connected"
|
|
||||||
else
|
|
||||||
echo $wifi_output
|
|
||||||
end
|
|
||||||
'';
|
|
||||||
|
|
||||||
mkPackageWithDesktopOption =
|
|
||||||
opts:
|
|
||||||
mkOption (
|
|
||||||
{
|
|
||||||
type = types.submodule {
|
|
||||||
options = {
|
|
||||||
package = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
description = "The package for " + description;
|
|
||||||
};
|
|
||||||
desktopFile = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = "The desktop file name for " + description + ", defaults to [packagename].desktop";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// opts
|
|
||||||
);
|
|
||||||
|
|
||||||
desktopFileOf =
|
|
||||||
cfg:
|
|
||||||
if cfg.desktopFile == null then
|
|
||||||
"${cfg.package}/share/applications/${cfg.package.pname}.desktop"
|
|
||||||
else
|
|
||||||
cfg.desktopFile;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [ ./x11.nix ./wayland.nix ./alacritty.nix ];
|
||||||
./x11.nix
|
|
||||||
./wayland.nix
|
|
||||||
./alacritty.nix
|
|
||||||
];
|
|
||||||
options.linux.graphical = {
|
options.linux.graphical = {
|
||||||
type = mkOption {
|
type = mkOption {
|
||||||
type = types.nullOr (
|
type = types.nullOr (types.enum [ "x11" "wayland" ]);
|
||||||
types.enum [
|
|
||||||
"x11"
|
|
||||||
"wayland"
|
|
||||||
]
|
|
||||||
);
|
|
||||||
description = "Enable linux graphical configurations, with either 'x11' or 'wayland'";
|
description = "Enable linux graphical configurations, with either 'x11' or 'wayland'";
|
||||||
default = null;
|
default = null;
|
||||||
};
|
};
|
||||||
wallpaper = mkOption {
|
wallpaper = mkOption {
|
||||||
type = types.oneOf [
|
type = types.oneOf [ types.str types.path ];
|
||||||
types.str
|
|
||||||
types.path
|
|
||||||
];
|
|
||||||
description = "Path to the wallpaper file";
|
description = "Path to the wallpaper file";
|
||||||
default = "";
|
default = "";
|
||||||
};
|
};
|
||||||
startup = mkOption {
|
startup = mkOption {
|
||||||
type = types.listOf types.package;
|
type = types.listOf types.package;
|
||||||
description = "List of packages to include in ~/.config/autostart";
|
description = "List of packages to include in ~/.config/autostart";
|
||||||
default = [
|
default = [ ];
|
||||||
cfg.defaults.webBrowser.package
|
|
||||||
pkgs.thunderbird
|
|
||||||
cfg.defaults.discord.package
|
|
||||||
];
|
|
||||||
};
|
|
||||||
defaults = {
|
|
||||||
webBrowser = mkPackageWithDesktopOption { description = "default web browser"; };
|
|
||||||
terminal = mkPackageWithDesktopOption {
|
|
||||||
description = "default terminal";
|
|
||||||
default.package = pkgs.kitty;
|
|
||||||
};
|
|
||||||
discord = mkPackageWithDesktopOption {
|
|
||||||
description = "Discord client";
|
|
||||||
default.package = pkgs.vesktop;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config = mkIf (cfg.type != null) {
|
config = mkIf (cfg.type != null) {
|
||||||
# Packages
|
# Packages
|
||||||
|
|
||||||
home.packages = (
|
home.packages = (with pkgs; [
|
||||||
with pkgs;
|
|
||||||
[
|
|
||||||
cfg.defaults.webBrowser.package
|
|
||||||
cfg.defaults.terminal.package
|
|
||||||
|
|
||||||
## GUI stuff
|
## GUI stuff
|
||||||
evince # PDF reader
|
evince # PDF reader
|
||||||
gparted
|
gparted
|
||||||
|
@ -112,52 +37,34 @@ in
|
||||||
feh # For images?
|
feh # For images?
|
||||||
deluge # Torrent client
|
deluge # Torrent client
|
||||||
pavucontrol # PulseAudio control panel
|
pavucontrol # PulseAudio control panel
|
||||||
|
firefox
|
||||||
|
librewolf
|
||||||
|
cinnamon.nemo # File manager
|
||||||
|
thunderbird # Email
|
||||||
sublime-music # For navidrome
|
sublime-music # For navidrome
|
||||||
# cinny-desktop
|
|
||||||
gajim
|
|
||||||
vivaldi
|
|
||||||
# Audio
|
|
||||||
qpwgraph # Pipewire graph
|
|
||||||
audacity
|
|
||||||
vlc
|
|
||||||
|
|
||||||
unstable.zotero
|
zotero
|
||||||
libreoffice
|
libreoffice
|
||||||
|
|
||||||
mpv # for anki
|
|
||||||
anki-bin
|
|
||||||
|
|
||||||
# Chat stuff
|
|
||||||
tdesktop
|
|
||||||
whatsapp-for-linux
|
|
||||||
slack
|
|
||||||
zoom-us
|
|
||||||
|
|
||||||
## CLI stuff
|
## CLI stuff
|
||||||
dex # .desktop file management, startup
|
dex # .desktop file management, startup
|
||||||
# sct # Display color temperature
|
# sct # Display color temperature
|
||||||
xdg-utils # Open stuff
|
xdg-utils # Open stuff
|
||||||
wifi-indicator
|
] ++ (if pkgs.stdenv.isAarch64 then [ ] else [
|
||||||
]
|
gnome.cheese # Webcam check, expensive
|
||||||
++ cfg.startup
|
mailspring
|
||||||
);
|
# Chat stuff
|
||||||
|
unstable.slack
|
||||||
|
]));
|
||||||
|
|
||||||
|
nki.programs.discord.enable = pkgs.stdenv.isx86_64;
|
||||||
|
|
||||||
# OBS
|
|
||||||
programs.obs-studio = {
|
|
||||||
enable = true;
|
|
||||||
plugins = with pkgs.obs-studio-plugins; [
|
|
||||||
wlrobs
|
|
||||||
input-overlay
|
|
||||||
obs-pipewire-audio-capture
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Cursor
|
# Cursor
|
||||||
home.pointerCursor = {
|
home.pointerCursor = {
|
||||||
package = pkgs.suwako-cursors;
|
package = pkgs.numix-cursor-theme;
|
||||||
gtk.enable = true;
|
name = "Numix-Cursor";
|
||||||
name = "Suwako";
|
size = 24;
|
||||||
size = 32;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# MIME set ups
|
# MIME set ups
|
||||||
|
@ -165,66 +72,22 @@ in
|
||||||
xdg.mimeApps.enable = true;
|
xdg.mimeApps.enable = true;
|
||||||
|
|
||||||
xdg.mimeApps.associations.added = {
|
xdg.mimeApps.associations.added = {
|
||||||
"x-scheme-handler/mailto" = [
|
"x-scheme-handler/mailto" = [ "org.gnome.Evolution.desktop" ];
|
||||||
"thunderbird.desktop"
|
|
||||||
"org.gnome.Evolution.desktop"
|
|
||||||
];
|
|
||||||
"application/pdf" = [ "org.gnome.Evince.desktop" ];
|
"application/pdf" = [ "org.gnome.Evince.desktop" ];
|
||||||
"text/plain" = [ "kakoune.desktop" ];
|
"text/plain" = [ "kakoune.desktop" ];
|
||||||
|
|
||||||
# Other Thunderbird stuff
|
|
||||||
"x-scheme-handler/mid" = [ "thunderbird.desktop" ];
|
|
||||||
"x-scheme-handler/news" = [ "thunderbird.desktop" ];
|
|
||||||
"x-scheme-handler/snews" = [ "thunderbird.desktop" ];
|
|
||||||
"x-scheme-handler/nntp" = [ "thunderbird.desktop" ];
|
|
||||||
"x-scheme-handler/feed" = [ "thunderbird.desktop" ];
|
|
||||||
"application/rss+xml" = [ "thunderbird.desktop" ];
|
|
||||||
"application/x-extension-rss" = [ "thunderbird.desktop" ];
|
|
||||||
"x-scheme-handler/tg2" = [ "org.telegram.desktop.desktop" ];
|
|
||||||
"x-scheme-handler/tonsite2" = [ "org.telegram.desktop.desktop" ];
|
|
||||||
|
|
||||||
# Other browser stuff
|
|
||||||
"application/x-extension-htm" = [ (desktopFileOf cfg.defaults.webBrowser) ];
|
|
||||||
"application/x-extension-html" = [ (desktopFileOf cfg.defaults.webBrowser) ];
|
|
||||||
"application/x-extension-shtml" = [ (desktopFileOf cfg.defaults.webBrowser) ];
|
|
||||||
"application/xhtml+xml" = [ (desktopFileOf cfg.defaults.webBrowser) ];
|
|
||||||
"application/x-extension-xhtml" = [ (desktopFileOf cfg.defaults.webBrowser) ];
|
|
||||||
"application/x-extension-xht" = [ (desktopFileOf cfg.defaults.webBrowser) ];
|
|
||||||
};
|
};
|
||||||
xdg.mimeApps.defaultApplications = {
|
xdg.mimeApps.defaultApplications = {
|
||||||
# Email
|
# Email
|
||||||
"x-scheme-handler/mailto" = [
|
"x-scheme-handler/mailto" = [ "org.gnome.Evolution.desktop" ];
|
||||||
"thunderbird.desktop"
|
|
||||||
"org.gnome.Evolution.desktop"
|
|
||||||
];
|
|
||||||
"x-scheme-handler/webcal" = [ "thunderbird.desktop" ];
|
|
||||||
"x-scheme-handler/webcals" = [ "thunderbird.desktop" ];
|
|
||||||
|
|
||||||
# Other Thunderbird stuff
|
|
||||||
"x-scheme-handler/mid" = [ "thunderbird.desktop" ];
|
|
||||||
"x-scheme-handler/news" = [ "thunderbird.desktop" ];
|
|
||||||
"x-scheme-handler/snews" = [ "thunderbird.desktop" ];
|
|
||||||
"x-scheme-handler/nntp" = [ "thunderbird.desktop" ];
|
|
||||||
"x-scheme-handler/feed" = [ "thunderbird.desktop" ];
|
|
||||||
"application/rss+xml" = [ "thunderbird.desktop" ];
|
|
||||||
"application/x-extension-rss" = [ "thunderbird.desktop" ];
|
|
||||||
|
|
||||||
# Default web browser stuff
|
# Default web browser stuff
|
||||||
"text/html" = [ (desktopFileOf cfg.defaults.webBrowser) ];
|
"text/html" = [ "firefox.desktop" ];
|
||||||
"x-scheme-handler/chrome" = [ (desktopFileOf cfg.defaults.webBrowser) ];
|
"x-scheme-handler/about" = [ "firefox.desktop" ];
|
||||||
"x-scheme-handler/about" = [ (desktopFileOf cfg.defaults.webBrowser) ];
|
"x-scheme-handler/unknown" = [ "firefox.desktop" ];
|
||||||
"x-scheme-handler/unknown" = [ (desktopFileOf cfg.defaults.webBrowser) ];
|
"x-scheme-handler/http" = [ "firefox.desktop" ];
|
||||||
"x-scheme-handler/http" = [ (desktopFileOf cfg.defaults.webBrowser) ];
|
"x-scheme-handler/https" = [ "firefox.desktop" ];
|
||||||
"x-scheme-handler/https" = [ (desktopFileOf cfg.defaults.webBrowser) ];
|
"x-scheme-handler/ftp" = [ "firefox.desktop" ];
|
||||||
"x-scheme-handler/ftp" = [ (desktopFileOf cfg.defaults.webBrowser) ];
|
"x-scheme-handler/ftps" = [ "firefox.desktop" ];
|
||||||
"x-scheme-handler/ftps" = [ (desktopFileOf cfg.defaults.webBrowser) ];
|
|
||||||
"x-scheme-handler/file" = [ (desktopFileOf cfg.defaults.webBrowser) ];
|
|
||||||
"application/x-extension-htm" = [ (desktopFileOf cfg.defaults.webBrowser) ];
|
|
||||||
"application/x-extension-html" = [ (desktopFileOf cfg.defaults.webBrowser) ];
|
|
||||||
"application/x-extension-shtml" = [ (desktopFileOf cfg.defaults.webBrowser) ];
|
|
||||||
"application/xhtml+xml" = [ (desktopFileOf cfg.defaults.webBrowser) ];
|
|
||||||
"application/x-extension-xhtml" = [ (desktopFileOf cfg.defaults.webBrowser) ];
|
|
||||||
"application/x-extension-xht" = [ (desktopFileOf cfg.defaults.webBrowser) ];
|
|
||||||
|
|
||||||
# Torrent
|
# Torrent
|
||||||
"application/x-bittorrent" = [ "deluge.desktop" ];
|
"application/x-bittorrent" = [ "deluge.desktop" ];
|
||||||
|
@ -232,24 +95,17 @@ in
|
||||||
|
|
||||||
# Text
|
# Text
|
||||||
"text/plain" = [ "kakoune.desktop" ];
|
"text/plain" = [ "kakoune.desktop" ];
|
||||||
"application/pdf" = [ "okularApplication_pdf.desktop" ];
|
"application/pdf" = [ "org.gnome.Evince.desktop" ];
|
||||||
|
|
||||||
# Files
|
# Files
|
||||||
"inode/directory" = [ "dolphin.desktop" ];
|
"inode/directory" = [ "nemo.desktop" ];
|
||||||
|
|
||||||
# Telegram
|
|
||||||
"x-scheme-handler/tg2" = "org.telegram.desktop.desktop";
|
|
||||||
"x-scheme-handler/tonsite2" = "org.telegram.desktop.desktop";
|
|
||||||
|
|
||||||
# Discord
|
|
||||||
"x-scheme-handler/discord" = [ (desktopFileOf cfg.defaults.discord) ];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Add one for kakoune
|
# Add one for kakoune
|
||||||
xdg.desktopEntries."kakoune" = {
|
xdg.desktopEntries."kakoune" = {
|
||||||
name = "Kakoune";
|
name = "Kakoune";
|
||||||
genericName = "Text Editor";
|
genericName = "Text Editor";
|
||||||
exec = ''${lib.getExe pkgs.kitty} --class kitty-float -o initial_window_width=150c -o initial_window_height=40c ${pkgs.writeShellScript "editor.sh" ''
|
exec = ''kitty --class kitty-float -o initial_window_width=150c -o initial_window_height=40c ${pkgs.writeShellScript "editor.sh" ''
|
||||||
$EDITOR "$@"
|
$EDITOR "$@"
|
||||||
''} %U'';
|
''} %U'';
|
||||||
# exec = "kakoune %U";
|
# exec = "kakoune %U";
|
||||||
|
@ -261,39 +117,26 @@ in
|
||||||
## GTK
|
## GTK
|
||||||
gtk.enable = true;
|
gtk.enable = true;
|
||||||
gtk.cursorTheme = { inherit (config.home.pointerCursor) package name size; };
|
gtk.cursorTheme = { inherit (config.home.pointerCursor) package name size; };
|
||||||
gtk.font.name = "IBM Plex Sans JP";
|
gtk.font.name = "system-ui";
|
||||||
gtk.font.size = 10;
|
gtk.font.size = 10;
|
||||||
gtk.iconTheme = {
|
gtk.iconTheme = {
|
||||||
package = pkgs.kdePackages.breeze-icons;
|
package = pkgs.numix-icon-theme;
|
||||||
name = "breeze";
|
name = "Numix";
|
||||||
};
|
};
|
||||||
gtk.theme = {
|
gtk.theme = {
|
||||||
package = pkgs.kdePackages.breeze-gtk;
|
package = pkgs.numix-gtk-theme;
|
||||||
name = "Breeze";
|
name = "Numix";
|
||||||
};
|
};
|
||||||
gtk.gtk2.configLocation = "${config.xdg.configHome}/gtk-2.0/gtkrc";
|
|
||||||
gtk.gtk2.extraConfig = ''
|
|
||||||
gtk-enable-animations=1
|
|
||||||
gtk-im-module="fcitx"
|
|
||||||
gtk-theme-name="Numix"
|
|
||||||
gtk-primary-button-warps-slider=1
|
|
||||||
gtk-toolbar-style=3
|
|
||||||
gtk-menu-images=1
|
|
||||||
gtk-button-images=1
|
|
||||||
gtk-sound-theme-name="ocean"
|
|
||||||
gtk-icon-theme-name="breeze"
|
|
||||||
'';
|
|
||||||
gtk.gtk3.extraConfig.gtk-im-module = "fcitx";
|
|
||||||
gtk.gtk4.extraConfig.gtk-im-module = "fcitx";
|
|
||||||
## Qt
|
## Qt
|
||||||
qt.enable = true;
|
qt.enable = true;
|
||||||
qt.platformTheme.name = "kde";
|
qt.platformTheme = "gnome";
|
||||||
qt.platformTheme.package = with pkgs.kdePackages; [
|
qt.style.package = pkgs.adwaita-qt;
|
||||||
plasma-integration
|
qt.style.name = "adwaita";
|
||||||
systemsettings
|
|
||||||
];
|
home.sessionVariables = {
|
||||||
qt.style.package = [ pkgs.kdePackages.breeze ];
|
# Set up Java font style
|
||||||
qt.style.name = "Breeze";
|
_JAVA_OPTIONS = "-Dawt.useSystemAAFontSettings=lcd";
|
||||||
|
};
|
||||||
|
|
||||||
xdg.configFile =
|
xdg.configFile =
|
||||||
let
|
let
|
||||||
|
@ -304,22 +147,16 @@ in
|
||||||
let
|
let
|
||||||
srcFile = pkgs.runCommand "${pkg.name}-startup" { } ''
|
srcFile = pkgs.runCommand "${pkg.name}-startup" { } ''
|
||||||
mkdir - p $out
|
mkdir - p $out
|
||||||
cp $(ls -d ${pkg}/share/applications/*.desktop | head -n 1) $out/${pkg.name}.desktop
|
cp $
|
||||||
|
(ls - d ${
|
||||||
|
pkg}/share/applications/*.desktop | head -n 1) $out/${pkg.name}.desktop
|
||||||
'';
|
'';
|
||||||
in
|
in
|
||||||
"${srcFile}/${pkg.name}.desktop";
|
"${srcFile}/${pkg.name}.desktop";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
autoStartup = listToAttrs (map f cfg.startup);
|
|
||||||
in
|
in
|
||||||
autoStartup
|
listToAttrs (map f (cfg.startup ++ alwaysStartup));
|
||||||
// {
|
|
||||||
## Polkit UI
|
|
||||||
"autostart/polkit.desktop".text = ''
|
|
||||||
${builtins.readFile "${pkgs.pantheon.pantheon-agent-polkit}/etc/xdg/autostart/io.elementary.desktop.agent-polkit.desktop"}
|
|
||||||
OnlyShowIn=sway;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
# IBus configuration
|
# IBus configuration
|
||||||
# dconf.settings."desktop/ibus/general" = {
|
# dconf.settings."desktop/ibus/general" = {
|
||||||
# engines-order = hm.gvariant.mkArray hm.gvariant.type.string [ "xkb:jp::jpn" "mozc-jp" "Bamboo" ];
|
# engines-order = hm.gvariant.mkArray hm.gvariant.type.string [ "xkb:jp::jpn" "mozc-jp" "Bamboo" ];
|
||||||
|
@ -328,25 +165,7 @@ in
|
||||||
# dconf.settings."desktop/ibus/general/hotkey" = {
|
# dconf.settings."desktop/ibus/general/hotkey" = {
|
||||||
# triggers = hm.gvariant.mkArray hm.gvariant.type.string [ "<Super>z" ];
|
# triggers = hm.gvariant.mkArray hm.gvariant.type.string [ "<Super>z" ];
|
||||||
# };
|
# };
|
||||||
|
|
||||||
# Some graphical targets
|
|
||||||
systemd.user.targets = {
|
|
||||||
# For system trays, usually after graphical-session and graphical-session-pre
|
|
||||||
tray = {
|
|
||||||
Unit.Description = lib.mkDefault "System tray";
|
|
||||||
Unit.After = [ "graphical-session-pre.target" ];
|
|
||||||
Unit.Before = [ "graphical-session.target" ];
|
|
||||||
Unit.BindsTo = [ "graphical-session.target" ];
|
|
||||||
Install.WantedBy = [ "graphical-session.target" ];
|
|
||||||
};
|
|
||||||
# XWayland target
|
|
||||||
xwayland = {
|
|
||||||
Unit.Description = "XWayland support";
|
|
||||||
Unit.After = [ "graphical-session-pre.target" ];
|
|
||||||
Unit.Before = [ "graphical-session.target" ];
|
|
||||||
Unit.BindsTo = [ "graphical-session.target" ];
|
|
||||||
Install.WantedBy = [ "graphical-session.target" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,37 +1,32 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
let
|
||||||
notificationModule =
|
notificationModule = { config, pkgs, lib, ... }:
|
||||||
{
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
let
|
||||||
swaync = pkgs.swaynotificationcenter;
|
swaync = pkgs.unstable.swaynotificationcenter;
|
||||||
in
|
in
|
||||||
with lib;
|
with lib; mkIf (config.linux.graphical.type == "wayland") {
|
||||||
mkIf (config.linux.graphical.type == "wayland") {
|
home.packages = [ swaync ];
|
||||||
services.swaync = {
|
wayland.windowManager.sway.config = {
|
||||||
enable = true;
|
startup = [
|
||||||
settings.widgets = [
|
{ command = "swaync"; }
|
||||||
"inhibitors"
|
|
||||||
"title"
|
|
||||||
"dnd"
|
|
||||||
"mpris"
|
|
||||||
"notifications"
|
|
||||||
];
|
];
|
||||||
style = ./swaync.css;
|
};
|
||||||
|
xdg.configFile = {
|
||||||
|
"swaync/config.json" = {
|
||||||
|
text = builtins.toJSON {
|
||||||
|
widgets = [ "inhibitors" "title" "dnd" "mpris" "notifications" ];
|
||||||
|
scripts = { };
|
||||||
|
};
|
||||||
|
onChange = "swaync-client -R";
|
||||||
|
};
|
||||||
|
"swaync/style.css" = {
|
||||||
|
source = ./swaync.css;
|
||||||
|
onChange = "swaync-client -rs";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.my-waybar = {
|
programs.my-sway.waybar = {
|
||||||
extraSettings = [
|
extraSettings = {
|
||||||
{
|
|
||||||
modules-right = mkAfter [ "custom/swaync" ];
|
modules-right = mkAfter [ "custom/swaync" ];
|
||||||
modules."custom/swaync" = {
|
modules."custom/swaync" = {
|
||||||
tooltip = false;
|
tooltip = false;
|
||||||
|
@ -53,104 +48,35 @@ let
|
||||||
on-click-right = "${swaync}/bin/swaync-client -d -sw";
|
on-click-right = "${swaync}/bin/swaync-client -d -sw";
|
||||||
escape = true;
|
escape = true;
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
];
|
|
||||||
extraStyle = mkAfter ''
|
extraStyle = mkAfter ''
|
||||||
#custom-swaync {
|
#custom-swaync {
|
||||||
|
padding: 0 10px;
|
||||||
|
margin: 0 5px;
|
||||||
background: #F0FFFF;
|
background: #F0FFFF;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
plasmaModule =
|
|
||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
home.packages = with pkgs.kdePackages; [
|
|
||||||
discover
|
|
||||||
kmail
|
|
||||||
kontact
|
|
||||||
akonadi
|
|
||||||
kdepim-runtime
|
|
||||||
kmail-account-wizard
|
|
||||||
akonadi-import-wizard
|
|
||||||
];
|
|
||||||
xdg.configFile."plasma-workspace/env/wayland.sh".source =
|
|
||||||
pkgs.writeScript "plasma-wayland-env.sh" ''
|
|
||||||
export NIXOS_OZONE_WL=1
|
|
||||||
'';
|
|
||||||
xdg.dataFile."dbus-1/services/org.freedesktop.Notifications.service".source =
|
|
||||||
"${pkgs.kdePackages.plasma-workspace}/share/dbus-1/services/org.kde.plasma.Notifications.service";
|
|
||||||
};
|
|
||||||
|
|
||||||
rofi-rbw-script = pkgs.writeTextFile rec {
|
|
||||||
name = "rofi-rbw-script";
|
|
||||||
text = ''
|
|
||||||
#!/usr/bin/env fish
|
|
||||||
set -a PATH ${
|
|
||||||
lib.concatMapStringsSep " " (p: "${lib.getBin p}/bin") [
|
|
||||||
config.programs.rofi.package
|
|
||||||
pkgs.ydotool
|
|
||||||
pkgs.rofi-rbw
|
|
||||||
]
|
|
||||||
}
|
|
||||||
rofi-rbw
|
|
||||||
'';
|
|
||||||
executable = true;
|
|
||||||
destination = "/bin/${name}";
|
|
||||||
meta.mainProgram = name;
|
|
||||||
};
|
|
||||||
in
|
in
|
||||||
with lib;
|
with lib;
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [ notificationModule ];
|
||||||
notificationModule
|
|
||||||
plasmaModule
|
|
||||||
];
|
|
||||||
config = mkIf (config.linux.graphical.type == "wayland") {
|
config = mkIf (config.linux.graphical.type == "wayland") {
|
||||||
# Additional packages
|
# Additional packages
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
wl-clipboard # Clipboard management
|
wl-clipboard # Clipboard management
|
||||||
rofi-rbw-script
|
|
||||||
|
|
||||||
# Mimic the clipboard stuff in MacOS
|
# Mimic the clipboard stuff in MacOS
|
||||||
(pkgs.writeShellScriptBin "pbcopy" ''
|
(pkgs.writeShellScriptBin "pbcopy" ''
|
||||||
exec ${pkgs.wl-clipboard}/bin/wl-copy "$@"
|
exec ${pkgs.wl-clipboard}/bin/wl-copy
|
||||||
'')
|
'')
|
||||||
(pkgs.writeShellScriptBin "pbpaste" ''
|
(pkgs.writeShellScriptBin "pbpaste" ''
|
||||||
exec ${pkgs.wl-clipboard}/bin/wl-paste "$@"
|
exec ${pkgs.wl-clipboard}/bin/wl-paste -n
|
||||||
'')
|
'')
|
||||||
];
|
];
|
||||||
|
|
||||||
programs.rofi = {
|
|
||||||
enable = true;
|
|
||||||
package = pkgs.rofi-wayland;
|
|
||||||
cycle = true;
|
|
||||||
font = "monospace";
|
|
||||||
terminal = "${lib.getExe config.programs.kitty.package}";
|
|
||||||
theme = "Paper";
|
|
||||||
plugins = with pkgs; [
|
|
||||||
rofi-bluetooth
|
|
||||||
rofi-calc
|
|
||||||
rofi-rbw
|
|
||||||
rofi-power-menu
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
home.sessionVariables = {
|
|
||||||
ANKI_WAYLAND = "1";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Yellow light!
|
|
||||||
services.wlsunset = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
# Lausanne
|
|
||||||
latitude = "46.31";
|
|
||||||
longitude = "6.38";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Notification system
|
# Notification system
|
||||||
# services.dunst = {
|
# services.dunst = {
|
||||||
# enable = true;
|
# enable = true;
|
||||||
|
@ -170,5 +96,9 @@ with lib;
|
||||||
|
|
||||||
# settings.experimental.per_monitor_dpi = "true";
|
# settings.experimental.per_monitor_dpi = "true";
|
||||||
# };
|
# };
|
||||||
|
|
||||||
|
# Forward wallpaper settings to sway
|
||||||
|
programs.my-sway.wallpaper = config.linux.graphical.wallpaper;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,10 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
let
|
||||||
cfg = config.linux.graphical;
|
cfg = config.linux.graphical;
|
||||||
in
|
in
|
||||||
with lib;
|
with lib;
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [ ./x11/hidpi.nix ./x11/i3.nix ];
|
||||||
./x11/hidpi.nix
|
|
||||||
./x11/i3.nix
|
|
||||||
];
|
|
||||||
options.linux.graphical.hasDE = mkOption {
|
options.linux.graphical.hasDE = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
description = "When enabled, disable stuff that already comes with a DE";
|
description = "When enabled, disable stuff that already comes with a DE";
|
||||||
|
@ -51,3 +43,4 @@ with lib;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
|
@ -23,14 +18,12 @@ let
|
||||||
"10: 10"
|
"10: 10"
|
||||||
];
|
];
|
||||||
wsAttrs = builtins.listToAttrs (
|
wsAttrs = builtins.listToAttrs (
|
||||||
map (i: {
|
map
|
||||||
name = toString (remainder i 10);
|
(i: { name = toString (remainder i 10); value = builtins.elemAt workspaces (i - 1); })
|
||||||
value = builtins.elemAt workspaces (i - 1);
|
(range 1 11)
|
||||||
}) (range 1 11)
|
|
||||||
);
|
);
|
||||||
remainder = x: y: x - (builtins.div x y) * y;
|
remainder = x: y: x - (builtins.div x y) * y;
|
||||||
range =
|
range = from: to:
|
||||||
from: to:
|
|
||||||
let
|
let
|
||||||
f = cur: if cur == to then [ ] else [ cur ] ++ f (cur + 1);
|
f = cur: if cur == to then [ ] else [ cur ] ++ f (cur + 1);
|
||||||
in
|
in
|
||||||
|
@ -50,8 +43,7 @@ in
|
||||||
"${wsAttrs."1"}" = [{ class = "^firefox$"; }];
|
"${wsAttrs."1"}" = [{ class = "^firefox$"; }];
|
||||||
"${wsAttrs."2"}" = [{ class = "^discord$"; }];
|
"${wsAttrs."2"}" = [{ class = "^discord$"; }];
|
||||||
};
|
};
|
||||||
config.bars = [
|
config.bars = [{
|
||||||
{
|
|
||||||
command = "${pkgs.i3-gaps}/bin/i3bar -t";
|
command = "${pkgs.i3-gaps}/bin/i3bar -t";
|
||||||
statusCommand = "${pkgs.i3status-rust}/bin/i3status-rs ~/.config/i3status-rust/config-default.toml";
|
statusCommand = "${pkgs.i3status-rust}/bin/i3status-rs ~/.config/i3status-rust/config-default.toml";
|
||||||
position = "top";
|
position = "top";
|
||||||
|
@ -60,42 +52,15 @@ in
|
||||||
statusline = "#ffffff";
|
statusline = "#ffffff";
|
||||||
separator = "#666666";
|
separator = "#666666";
|
||||||
|
|
||||||
focusedWorkspace = {
|
focusedWorkspace = { background = "#4c7899"; border = "#285577"; text = "#ffffff"; };
|
||||||
background = "#4c7899";
|
activeWorkspace = { background = "#333333"; border = "#5f676a"; text = "#ffffff"; };
|
||||||
border = "#285577";
|
inactiveWorkspace = { background = "#333333"; border = "#222222"; text = "#888888"; };
|
||||||
text = "#ffffff";
|
urgentWorkspace = { background = "#2f343a"; border = "#900000"; text = "#ffffff"; };
|
||||||
|
bindingMode = { background = "#2f343a"; border = "#900000"; text = "#ffffff"; };
|
||||||
};
|
};
|
||||||
activeWorkspace = {
|
}];
|
||||||
background = "#333333";
|
|
||||||
border = "#5f676a";
|
|
||||||
text = "#ffffff";
|
|
||||||
};
|
|
||||||
inactiveWorkspace = {
|
|
||||||
background = "#333333";
|
|
||||||
border = "#222222";
|
|
||||||
text = "#888888";
|
|
||||||
};
|
|
||||||
urgentWorkspace = {
|
|
||||||
background = "#2f343a";
|
|
||||||
border = "#900000";
|
|
||||||
text = "#ffffff";
|
|
||||||
};
|
|
||||||
bindingMode = {
|
|
||||||
background = "#2f343a";
|
|
||||||
border = "#900000";
|
|
||||||
text = "#ffffff";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
config.focus.newWindow = "none";
|
config.focus.newWindow = "none";
|
||||||
config.fonts = {
|
config.fonts = { names = [ "FantasqueSansMono Nerd Font Mono" "monospace" ]; size = 11.0; };
|
||||||
names = [
|
|
||||||
"FantasqueSansMono Nerd Font Mono"
|
|
||||||
"monospace"
|
|
||||||
];
|
|
||||||
size = 11.0;
|
|
||||||
};
|
|
||||||
config.gaps.outer = 5;
|
config.gaps.outer = 5;
|
||||||
config.gaps.inner = 5;
|
config.gaps.inner = 5;
|
||||||
config.gaps.smartGaps = true;
|
config.gaps.smartGaps = true;
|
||||||
|
@ -104,8 +69,7 @@ in
|
||||||
config.window.titlebar = false;
|
config.window.titlebar = false;
|
||||||
|
|
||||||
# Keybindings
|
# Keybindings
|
||||||
config.keybindings = lib.mkOptionDefault (
|
config.keybindings = lib.mkOptionDefault ({
|
||||||
{
|
|
||||||
## vim-style movements
|
## vim-style movements
|
||||||
"${mod}+h" = "focus left";
|
"${mod}+h" = "focus left";
|
||||||
"${mod}+j" = "focus down";
|
"${mod}+j" = "focus down";
|
||||||
|
@ -121,10 +85,9 @@ in
|
||||||
## Run
|
## Run
|
||||||
"${mod}+r" = "exec ${pkgs.dmenu}/bin/dmenu_run";
|
"${mod}+r" = "exec ${pkgs.dmenu}/bin/dmenu_run";
|
||||||
"${mod}+d" = "exec i3-dmenu-desktop --dmenu='${pkgs.dmenu}/bin/dmenu -i'";
|
"${mod}+d" = "exec i3-dmenu-desktop --dmenu='${pkgs.dmenu}/bin/dmenu -i'";
|
||||||
}
|
} // (
|
||||||
// (builtins.listToAttrs (
|
builtins.listToAttrs (lib.flatten (map
|
||||||
lib.flatten (
|
(key: [
|
||||||
map (key: [
|
|
||||||
{
|
{
|
||||||
name = "${mod}+${key}";
|
name = "${mod}+${key}";
|
||||||
value = "workspace ${builtins.getAttr key wsAttrs}";
|
value = "workspace ${builtins.getAttr key wsAttrs}";
|
||||||
|
@ -133,28 +96,26 @@ in
|
||||||
name = "${mod}+Shift+${key}";
|
name = "${mod}+Shift+${key}";
|
||||||
value = "move to workspace ${builtins.getAttr key wsAttrs}";
|
value = "move to workspace ${builtins.getAttr key wsAttrs}";
|
||||||
}
|
}
|
||||||
]) (builtins.attrNames wsAttrs)
|
])
|
||||||
)
|
(builtins.attrNames wsAttrs))
|
||||||
))
|
)));
|
||||||
);
|
|
||||||
|
|
||||||
# Workspace
|
# Workspace
|
||||||
config.defaultWorkspace = "workspace ${builtins.getAttr "1" wsAttrs}";
|
config.defaultWorkspace = "workspace ${builtins.getAttr "1" wsAttrs}";
|
||||||
config.startup =
|
config.startup = [
|
||||||
[
|
|
||||||
{ command = "firefox"; }
|
{ command = "firefox"; }
|
||||||
{ command = "discord"; }
|
{ command = "discord"; }
|
||||||
{ command = "dex -ae i3"; }
|
{ command = "dex -ae i3"; }
|
||||||
{ command = "ibus-daemon -drxR"; }
|
{ command = "ibus-daemon -drxR"; }
|
||||||
]
|
] ++
|
||||||
++ (
|
(
|
||||||
if (config.linux.graphical.wallpaper != "") then
|
if (config.linux.graphical.wallpaper != "")
|
||||||
[ { command = "${pkgs.feh}/bin/feh --bg-fill ${config.linux.graphical.wallpaper}"; } ]
|
then [{ command = "${pkgs.feh}/bin/feh --bg-fill ${config.linux.graphical.wallpaper}"; }]
|
||||||
else
|
else [ ]
|
||||||
[ ]
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
# i3status
|
# i3status
|
||||||
programs.i3status-rust.enable = true;
|
programs.i3status-rust.enable = true;
|
||||||
programs.i3status-rust.bars.default = {
|
programs.i3status-rust.bars.default = {
|
||||||
|
@ -193,3 +154,5 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,119 +0,0 @@
|
||||||
# A monitor list and common sway set up
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib;
|
|
||||||
let
|
|
||||||
monitors = {
|
|
||||||
# Internal
|
|
||||||
"framework" = {
|
|
||||||
name = "BOE 0x0BCA Unknown";
|
|
||||||
meta.mode = {
|
|
||||||
width = 2256;
|
|
||||||
height = 1504;
|
|
||||||
refresh = 60.0;
|
|
||||||
};
|
|
||||||
scale = 1.25;
|
|
||||||
};
|
|
||||||
"yoga" = {
|
|
||||||
name = "AU Optronics 0xD291 Unknown";
|
|
||||||
meta.connection = "eDP-1";
|
|
||||||
meta.mode = {
|
|
||||||
width = 1920;
|
|
||||||
height = 1080;
|
|
||||||
refresh = 60.026;
|
|
||||||
};
|
|
||||||
scale = 1;
|
|
||||||
};
|
|
||||||
# External
|
|
||||||
## Work @ EPFL
|
|
||||||
"work" = {
|
|
||||||
name = "LG Electronics LG ULTRAFINE 301MAXSGHD10";
|
|
||||||
meta.mode = {
|
|
||||||
width = 3840;
|
|
||||||
height = 2160;
|
|
||||||
refresh = 60.0;
|
|
||||||
};
|
|
||||||
scale = 1.25;
|
|
||||||
};
|
|
||||||
"home_4k" = {
|
|
||||||
name = "AOC U28G2G6B PPYP2JA000013";
|
|
||||||
scale = 1.5;
|
|
||||||
adaptive_sync = "on";
|
|
||||||
meta = {
|
|
||||||
connection = "DP-2";
|
|
||||||
mode = {
|
|
||||||
width = 3840;
|
|
||||||
height = 2160;
|
|
||||||
refresh = 60.0;
|
|
||||||
};
|
|
||||||
fixedPosition = {
|
|
||||||
x = 0;
|
|
||||||
y = 0;
|
|
||||||
};
|
|
||||||
niriName = "PNP(AOC) U28G2G6B PPYP2JA000013";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
"home_1440" = {
|
|
||||||
name = "AOC Q27G2G3R3B VXJP6HA000442";
|
|
||||||
adaptive_sync = "on";
|
|
||||||
meta = {
|
|
||||||
connection = "DP-3";
|
|
||||||
mode = {
|
|
||||||
width = 2560;
|
|
||||||
height = 1440;
|
|
||||||
refresh = 165.0;
|
|
||||||
};
|
|
||||||
fixedPosition = {
|
|
||||||
x = 2560;
|
|
||||||
y = 0;
|
|
||||||
};
|
|
||||||
niriName = "PNP(AOC) Q27G2G3R3B VXJP6HA000442";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
"viewsonic_1080" = {
|
|
||||||
name = "ViewSonic Corporation XG2402 SERIES V4K182501054";
|
|
||||||
meta.mode = {
|
|
||||||
width = 1920;
|
|
||||||
height = 1080;
|
|
||||||
refresh = 144.0;
|
|
||||||
};
|
|
||||||
adaptive_sync = "on";
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
eachMonitor = _name: monitor: {
|
|
||||||
name = monitor.name;
|
|
||||||
value =
|
|
||||||
builtins.removeAttrs monitor [
|
|
||||||
"scale"
|
|
||||||
"name"
|
|
||||||
"meta"
|
|
||||||
]
|
|
||||||
// (lib.optionalAttrs (monitor ? scale) {
|
|
||||||
scale = toString monitor.scale;
|
|
||||||
})
|
|
||||||
// {
|
|
||||||
mode = with monitor.meta.mode; "${toString width}x${toString height}@${toString refresh}Hz";
|
|
||||||
}
|
|
||||||
// (lib.optionalAttrs (monitor.meta ? fixedPosition) {
|
|
||||||
position = with monitor.meta.fixedPosition; "${toString x} ${toString y}";
|
|
||||||
});
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.common.monitors = mkOption {
|
|
||||||
type = types.attrsOf types.attrs;
|
|
||||||
description = "A list of monitors";
|
|
||||||
};
|
|
||||||
config.common.monitors = monitors;
|
|
||||||
config.home.packages = mkIf config.wayland.windowManager.sway.enable (with pkgs; [ kanshi ]);
|
|
||||||
config.wayland.windowManager.sway.config.output = mkIf config.wayland.windowManager.sway.enable (
|
|
||||||
mapAttrs' eachMonitor config.common.monitors
|
|
||||||
);
|
|
||||||
}
|
|
27
home/modules/programs/discord.nix
Normal file
27
home/modules/programs/discord.nix
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.nki.programs.discord;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.nki.programs.discord = {
|
||||||
|
enable = mkEnableOption "Enable discord";
|
||||||
|
|
||||||
|
basePackage = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.discord;
|
||||||
|
description = "The base Discord package that will get patched";
|
||||||
|
};
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = cfg.basePackage.override { nss = pkgs.nss_latest; };
|
||||||
|
description = "The actual package to use";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
home.packages = [ cfg.package ];
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ config, pkgs, lib, ... }:
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
|
@ -96,13 +91,10 @@ in
|
||||||
|
|
||||||
# Add an extra syntax_color config
|
# Add an extra syntax_color config
|
||||||
xdg.configFile."broot/conf.toml".source = mkOverride 1 (
|
xdg.configFile."broot/conf.toml".source = mkOverride 1 (
|
||||||
tomlFormat.generate "broot-config" (
|
tomlFormat.generate "broot-config" (with config.programs.broot; {
|
||||||
with config.programs.broot;
|
|
||||||
{
|
|
||||||
inherit (settings) verbs modal skin;
|
inherit (settings) verbs modal skin;
|
||||||
syntax_theme = "base16-ocean.light";
|
syntax_theme = "base16-ocean.light";
|
||||||
}
|
})
|
||||||
)
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,40 @@
|
||||||
{
|
{ config, pkgs, lib, ... }:
|
||||||
config,
|
|
||||||
options,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.programs.my-kakoune;
|
cfg = config.programs.my-kakoune;
|
||||||
|
|
||||||
|
autoloadModule = types.submodule {
|
||||||
|
options = {
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "Name of the autoload script/folder. It might affect kakoune's load order.";
|
||||||
|
};
|
||||||
|
src = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
description = "Path to the autoload script/folder.";
|
||||||
|
};
|
||||||
|
wrapAsModule = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Wrap the given source file in a `provide-module` command. Fails if the `src` is not a single file.";
|
||||||
|
};
|
||||||
|
activationScript = mkOption {
|
||||||
|
type = types.nullOr types.lines;
|
||||||
|
default = null;
|
||||||
|
description = "Add an activation script to the module. It will be wrapped in a `hook global KakBegin .*` wrapper.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [ ./kak-lsp.nix ./fish-session.nix ./tree-sitter.nix ];
|
||||||
./fish-session.nix
|
|
||||||
./tree-sitter.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
options.programs.my-kakoune = {
|
options.programs.my-kakoune = {
|
||||||
enable = mkEnableOption "My version of the kakoune configuration";
|
enable = mkEnableOption "My version of the kakoune configuration";
|
||||||
package = mkOption {
|
package = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
default = pkgs.nki-kakoune;
|
default = pkgs.kakoune;
|
||||||
description = "The kakoune package to be installed";
|
description = "The kakoune package to be installed";
|
||||||
};
|
};
|
||||||
rc = mkOption {
|
rc = mkOption {
|
||||||
|
@ -28,16 +42,22 @@ in
|
||||||
default = "";
|
default = "";
|
||||||
description = "Content of the kakrc file. A line-concatenated string";
|
description = "Content of the kakrc file. A line-concatenated string";
|
||||||
};
|
};
|
||||||
|
autoload = mkOption {
|
||||||
|
type = types.listOf autoloadModule;
|
||||||
|
default = [ ];
|
||||||
|
description = "Sources to autoload";
|
||||||
|
};
|
||||||
|
themes = mkOption {
|
||||||
|
type = types.attrsOf types.path;
|
||||||
|
default = { };
|
||||||
|
description = "Themes to load";
|
||||||
|
};
|
||||||
|
|
||||||
extraFaces = mkOption {
|
extraFaces = mkOption {
|
||||||
type = types.attrsOf types.str;
|
type = types.attrsOf types.str;
|
||||||
default = { };
|
default = { };
|
||||||
description = "Extra faces to include";
|
description = "Extra faces to include";
|
||||||
};
|
};
|
||||||
autoloadFile = mkOption {
|
|
||||||
type = options.xdg.configFile.type;
|
|
||||||
default = { };
|
|
||||||
description = "Extra autoload files";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
@ -45,18 +65,44 @@ in
|
||||||
|
|
||||||
xdg.configFile =
|
xdg.configFile =
|
||||||
let
|
let
|
||||||
|
kakouneAutoload = { name, src, wrapAsModule ? false, activationScript ? null }:
|
||||||
|
[
|
||||||
|
(if !wrapAsModule then {
|
||||||
|
name = "kak/autoload/${name}";
|
||||||
|
value.source = src;
|
||||||
|
} else {
|
||||||
|
name = "kak/autoload/${name}/module.kak";
|
||||||
|
value.text = ''
|
||||||
|
provide-module ${name} %◍
|
||||||
|
${readFile src}
|
||||||
|
◍
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
] ++ (if activationScript == null then [ ] else [{
|
||||||
|
name = "kak/autoload/on-load/${name}.kak";
|
||||||
|
value.text = ''
|
||||||
|
hook global KakBegin .* %{
|
||||||
|
${activationScript}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
}]);
|
||||||
|
|
||||||
|
kakouneThemes = builtins.listToAttrs (builtins.attrValues (
|
||||||
|
builtins.mapAttrs
|
||||||
|
(name: src: {
|
||||||
|
name = "kak/colors/${name}.kak";
|
||||||
|
value.source = src;
|
||||||
|
})
|
||||||
|
cfg.themes
|
||||||
|
));
|
||||||
|
|
||||||
kakouneFaces =
|
kakouneFaces =
|
||||||
let
|
let
|
||||||
txt = strings.concatStringsSep "\n" (
|
txt = strings.concatStringsSep "\n" (builtins.attrValues (builtins.mapAttrs (name: face: "face global ${name} \"${face}\"") cfg.extraFaces));
|
||||||
builtins.attrValues (
|
|
||||||
builtins.mapAttrs (name: face: "face global ${name} \"${face}\"") cfg.extraFaces
|
|
||||||
)
|
|
||||||
);
|
|
||||||
in
|
in
|
||||||
pkgs.writeText "faces.kak" txt;
|
pkgs.writeText "faces.kak" txt;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
"kak/autoload/builtin".source = "${cfg.package}/share/kak/autoload";
|
|
||||||
# kakrc
|
# kakrc
|
||||||
"kak/kakrc".text = ''
|
"kak/kakrc".text = ''
|
||||||
${cfg.rc}
|
${cfg.rc}
|
||||||
|
@ -64,13 +110,15 @@ in
|
||||||
# Load faces
|
# Load faces
|
||||||
source ${kakouneFaces}
|
source ${kakouneFaces}
|
||||||
'';
|
'';
|
||||||
|
} //
|
||||||
|
(builtins.listToAttrs (lib.lists.flatten (map kakouneAutoload ([
|
||||||
|
# include the original autoload files
|
||||||
|
{
|
||||||
|
name = "rc";
|
||||||
|
src = "${cfg.package}/share/kak/autoload/rc";
|
||||||
}
|
}
|
||||||
// lib.mapAttrs' (name: attrs: {
|
] ++ cfg.autoload))))
|
||||||
name = "kak/autoload/${name}";
|
// kakouneThemes;
|
||||||
value = attrs // {
|
|
||||||
target = "kak/autoload/${name}";
|
|
||||||
};
|
|
||||||
}) cfg.autoloadFile;
|
|
||||||
xdg.dataFile."kak".source = "${cfg.package}/share/kak";
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ config, pkgs, lib, ... }:
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
|
@ -30,8 +25,9 @@ in
|
||||||
echo "New kakoune session started (pid = $last_pid, session name = $kak_session)."
|
echo "New kakoune session started (pid = $last_pid, session name = $kak_session)."
|
||||||
|
|
||||||
# Rebind $VISUAL, $EDITOR and e command
|
# Rebind $VISUAL, $EDITOR and e command
|
||||||
set -gx VISUAL kak -c $kak_session
|
set -gx VISUAL "kak -c $kak_session"
|
||||||
set -gx EDITOR kak -c $kak_session
|
set -gx EDITOR "kak -c $kak_session"
|
||||||
|
alias e="kak -c $kak_session"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
kill-kak-session = ''
|
kill-kak-session = ''
|
||||||
|
@ -46,17 +42,16 @@ in
|
||||||
# Rebind $VISUAL, $EDITOR and e command
|
# Rebind $VISUAL, $EDITOR and e command
|
||||||
set -gx VISUAL "kak"
|
set -gx VISUAL "kak"
|
||||||
set -gx EDITOR "kak"
|
set -gx EDITOR "kak"
|
||||||
|
alias e="kak"
|
||||||
'';
|
'';
|
||||||
};
|
|
||||||
programs.fish.tide = {
|
_tide_item_kakoune = ''
|
||||||
items.kakoune = ''
|
|
||||||
if set -q kak_session
|
if set -q kak_session
|
||||||
set -U tide_kakoune_color FFA500
|
set -U tide_kakoune_color FFA500
|
||||||
set -U tide_kakoune_bg_color normal
|
set -U tide_kakoune_bg_color normal
|
||||||
_tide_print_item kakoune " " "e[$kak_session]"
|
_tide_print_item kakoune " " "e[$kak_session]"
|
||||||
end
|
end
|
||||||
'';
|
'';
|
||||||
rightItems = mkAfter [ "kakoune" ];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
293
home/modules/programs/my-kakoune/kak-lsp.nix
Normal file
293
home/modules/programs/my-kakoune/kak-lsp.nix
Normal file
|
@ -0,0 +1,293 @@
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
lspConfig =
|
||||||
|
{
|
||||||
|
language = {
|
||||||
|
bash = {
|
||||||
|
args = [ "start" ];
|
||||||
|
command = "bash-language-server";
|
||||||
|
filetypes = [ "sh" ];
|
||||||
|
roots = [ ".git" ".hg" ];
|
||||||
|
};
|
||||||
|
c_cpp = {
|
||||||
|
args = [ "-v=2" "-log-file=/tmp/ccls.log" ];
|
||||||
|
command = "ccls";
|
||||||
|
filetypes = [ "c" "cpp" ];
|
||||||
|
roots = [ "compile_commands.json" ".cquery" ".git" ];
|
||||||
|
};
|
||||||
|
crystal = {
|
||||||
|
command = "scry";
|
||||||
|
filetypes = [ "crystal" ];
|
||||||
|
roots = [ "shard.yml" ];
|
||||||
|
};
|
||||||
|
css = {
|
||||||
|
args = [ "--stdio" ];
|
||||||
|
command = "css-languageserver";
|
||||||
|
filetypes = [ "css" ];
|
||||||
|
roots = [ "package.json" ];
|
||||||
|
};
|
||||||
|
d = {
|
||||||
|
command = "dls";
|
||||||
|
filetypes = [ "d" "di" ];
|
||||||
|
roots = [ ".git" "dub.sdl" "dub.json" ];
|
||||||
|
};
|
||||||
|
dart = {
|
||||||
|
command = "dart_language_server";
|
||||||
|
filetypes = [ "dart" ];
|
||||||
|
roots = [ "pubspec.yaml" ".git" ];
|
||||||
|
};
|
||||||
|
elm = {
|
||||||
|
args = [ "--stdio" ];
|
||||||
|
command = "elm-language-server";
|
||||||
|
filetypes = [ "elm" ];
|
||||||
|
roots = [ "elm.json" ];
|
||||||
|
};
|
||||||
|
fsharp = {
|
||||||
|
command = "FSharpLanguageServer";
|
||||||
|
filetypes = [ "fsharp" ];
|
||||||
|
roots = [ ".git" "*.fsx" ];
|
||||||
|
};
|
||||||
|
go = {
|
||||||
|
command = "gopls";
|
||||||
|
filetypes = [ "go" ];
|
||||||
|
offset_encoding = "utf-8";
|
||||||
|
roots = [ "Gopkg.toml" "go.mod" ".git" ".hg" ];
|
||||||
|
settings = { gopls = { hoverKind = "SynopsisDocumentation"; semanticTokens = true; }; };
|
||||||
|
settings_section = "gopls";
|
||||||
|
};
|
||||||
|
haskell = {
|
||||||
|
args = [ "--lsp" ];
|
||||||
|
command = "haskell-language-server-wrapper";
|
||||||
|
filetypes = [ "haskell" ];
|
||||||
|
roots = [ "Setup.hs" "stack.yaml" "*.cabal" "package.yaml" ];
|
||||||
|
settings_section = "haskell";
|
||||||
|
};
|
||||||
|
html = {
|
||||||
|
args = [ "--stdio" ];
|
||||||
|
command = "html-languageserver";
|
||||||
|
filetypes = [ "html" ];
|
||||||
|
roots = [ "package.json" ];
|
||||||
|
};
|
||||||
|
javascript = {
|
||||||
|
args = [ "lsp" ];
|
||||||
|
command = "flow";
|
||||||
|
filetypes = [ "javascript" ];
|
||||||
|
roots = [ ".flowconfig" ];
|
||||||
|
};
|
||||||
|
json = {
|
||||||
|
args = [ "--stdio" ];
|
||||||
|
command = "json-languageserver";
|
||||||
|
filetypes = [ "json" ];
|
||||||
|
roots = [ "package.json" ];
|
||||||
|
};
|
||||||
|
latex = {
|
||||||
|
command = "texlab";
|
||||||
|
filetypes = [ "latex" ];
|
||||||
|
roots = [ ".git" "main.tex" "all.tex" ];
|
||||||
|
settings_section = "texlab";
|
||||||
|
settings.texlab = {
|
||||||
|
build.executable = "latexmk";
|
||||||
|
build.args = [ "-pdf" "-shell-escape" "-interaction=nonstopmode" "-synctex=1" "%f" ];
|
||||||
|
|
||||||
|
build.forwardSearchAfter = true;
|
||||||
|
build.onSave = true;
|
||||||
|
|
||||||
|
forwardSearch = {
|
||||||
|
executable = "/Applications/Skim.app/Contents/SharedSupport/displayline";
|
||||||
|
args = [ "-r" "-g" "%l" "%p" "%f" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
nim = {
|
||||||
|
command = "nimlsp";
|
||||||
|
filetypes = [ "nim" ];
|
||||||
|
roots = [ "*.nimble" ".git" ];
|
||||||
|
};
|
||||||
|
nix = {
|
||||||
|
command = "rnix-lsp";
|
||||||
|
filetypes = [ "nix" ];
|
||||||
|
roots = [ "flake.nix" "shell.nix" ".git" ];
|
||||||
|
};
|
||||||
|
ocaml = {
|
||||||
|
args = [ ];
|
||||||
|
command = "ocamllsp";
|
||||||
|
filetypes = [ "ocaml" ];
|
||||||
|
roots = [ "Makefile" "opam" "*.opam" "dune" ".merlin" ".ocamlformat" ];
|
||||||
|
};
|
||||||
|
php = {
|
||||||
|
args = [ "--stdio" ];
|
||||||
|
command = "intelephense";
|
||||||
|
filetypes = [ "php" ];
|
||||||
|
roots = [ ".htaccess" "composer.json" ];
|
||||||
|
};
|
||||||
|
python = {
|
||||||
|
command = "pyls";
|
||||||
|
filetypes = [ "python" ];
|
||||||
|
offset_encoding = "utf-8";
|
||||||
|
roots = [ "requirements.txt" "setup.py" ".git" ".hg" ];
|
||||||
|
};
|
||||||
|
racket = {
|
||||||
|
args = [ "-l" "racket-langserver" ];
|
||||||
|
command = "racket";
|
||||||
|
filetypes = [ "racket" ];
|
||||||
|
roots = [ ".git" ];
|
||||||
|
};
|
||||||
|
reason = {
|
||||||
|
args = [ "--stdio" ];
|
||||||
|
command = "ocaml-language-server";
|
||||||
|
filetypes = [ "reason" ];
|
||||||
|
roots = [ "package.json" "Makefile" ".git" ".hg" ];
|
||||||
|
};
|
||||||
|
ruby = {
|
||||||
|
args = [ "stdio" ];
|
||||||
|
command = "solargraph";
|
||||||
|
filetypes = [ "ruby" ];
|
||||||
|
roots = [ "Gemfile" ];
|
||||||
|
};
|
||||||
|
rust = {
|
||||||
|
args = [ ];
|
||||||
|
command = "rust-analyzer";
|
||||||
|
filetypes = [ "rust" ];
|
||||||
|
roots = [ "Cargo.toml" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
semantic_tokens.faces = [
|
||||||
|
## Items
|
||||||
|
# (Rust) Macros
|
||||||
|
{ face = "attribute"; token = "attribute"; }
|
||||||
|
{ face = "attribute"; token = "derive"; }
|
||||||
|
{ face = "macro"; token = "macro"; } # Function-like Macro
|
||||||
|
# Keyword and Fixed Tokens
|
||||||
|
{ face = "keyword"; token = "keyword"; }
|
||||||
|
{ face = "operator"; token = "operator"; }
|
||||||
|
# Functions and Methods
|
||||||
|
{ face = "function"; token = "function"; }
|
||||||
|
{ face = "method"; token = "method"; }
|
||||||
|
# Constants
|
||||||
|
{ face = "string"; token = "string"; }
|
||||||
|
{ face = "format_specifier"; token = "formatSpecifier"; }
|
||||||
|
# Variables
|
||||||
|
{ face = "mutable_variable"; token = "variable"; modifiers = [ "mutable" ]; }
|
||||||
|
{ face = "variable"; token = "variable"; }
|
||||||
|
{ face = "module"; token = "namespace"; }
|
||||||
|
{ face = "variable"; token = "type_parameter"; }
|
||||||
|
{ face = "class"; token = "enum"; }
|
||||||
|
{ face = "class"; token = "struct"; }
|
||||||
|
{ face = "class"; token = "trait"; }
|
||||||
|
{ face = "class"; token = "union"; }
|
||||||
|
{ face = "class"; token = "class"; }
|
||||||
|
|
||||||
|
## Comments
|
||||||
|
{ face = "documentation"; token = "comment"; modifiers = [ "documentation" ]; }
|
||||||
|
{ face = "comment"; token = "comment"; }
|
||||||
|
];
|
||||||
|
server = { timeout = 1800; };
|
||||||
|
snippet_support = false;
|
||||||
|
verbosity = 255;
|
||||||
|
};
|
||||||
|
|
||||||
|
languageOption = types.submodule {
|
||||||
|
options = {
|
||||||
|
filetypes = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
description = "The list of filetypes to assign the language to";
|
||||||
|
};
|
||||||
|
roots = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
description = "The list of root filenames that are used to determine the project root";
|
||||||
|
};
|
||||||
|
command = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The LSP server command to be called.";
|
||||||
|
};
|
||||||
|
args = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
description = "The arguments passed onto the LSP server.";
|
||||||
|
};
|
||||||
|
offset_encoding = mkOption {
|
||||||
|
type = types.nullOr (types.enum [ "utf-8" ]);
|
||||||
|
default = null;
|
||||||
|
description = "The offset encoding used by the LSP server.";
|
||||||
|
};
|
||||||
|
settings_section = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "The settings section to be sent to LSP server.";
|
||||||
|
};
|
||||||
|
settings = mkOption {
|
||||||
|
type = types.nullOr (types.attrsOf types.anything);
|
||||||
|
default = null;
|
||||||
|
description = "Additional settings to be passed to the LSP server.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
cfg = config.programs.kak-lsp;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.programs.kak-lsp = {
|
||||||
|
enable = mkEnableOption "Enable kak-lsp support";
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.kak-lsp;
|
||||||
|
};
|
||||||
|
|
||||||
|
enableSnippets = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Enable snippet support";
|
||||||
|
};
|
||||||
|
|
||||||
|
semanticTokens.faces = mkOption {
|
||||||
|
type = types.listOf types.anything;
|
||||||
|
default = lspConfig.semantic_tokens.faces;
|
||||||
|
description = "The semantic tokens faces mapping given to kak";
|
||||||
|
};
|
||||||
|
semanticTokens.additionalFaces = mkOption {
|
||||||
|
type = types.listOf types.anything;
|
||||||
|
default = [ ];
|
||||||
|
description = "The semantic tokens faces mapping given to kak";
|
||||||
|
};
|
||||||
|
|
||||||
|
serverTimeout = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 1000;
|
||||||
|
description = "Server timeout";
|
||||||
|
};
|
||||||
|
|
||||||
|
languages = mkOption {
|
||||||
|
type = types.attrsOf languageOption;
|
||||||
|
default = { };
|
||||||
|
description = "The language options";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
home.packages = [ cfg.package ];
|
||||||
|
|
||||||
|
# Configurations
|
||||||
|
xdg.configFile."kak-lsp/kak-lsp.toml" = {
|
||||||
|
source = pkgs.runCommand "config.toml"
|
||||||
|
{
|
||||||
|
buildInputs = [ pkgs.yj ];
|
||||||
|
preferLocalBuild = true;
|
||||||
|
} ''
|
||||||
|
yj -jt -i \
|
||||||
|
< ${
|
||||||
|
pkgs.writeText "config.json" (builtins.toJSON {
|
||||||
|
semantic_tokens.faces = cfg.semanticTokens.faces ++ cfg.semanticTokens.additionalFaces;
|
||||||
|
server.timeout = cfg.serverTimeout;
|
||||||
|
snippet_support = cfg.enableSnippets;
|
||||||
|
verbosity = 255;
|
||||||
|
language = lspConfig.language // cfg.languages;
|
||||||
|
})
|
||||||
|
} \
|
||||||
|
> $out
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ config, pkgs, lib, ... }:
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.programs.my-kakoune.tree-sitter;
|
cfg = config.programs.my-kakoune.tree-sitter;
|
||||||
|
@ -19,44 +14,14 @@ let
|
||||||
default = "src";
|
default = "src";
|
||||||
};
|
};
|
||||||
grammar.compile = {
|
grammar.compile = {
|
||||||
command = mkOption {
|
command = mkOption { type = types.str; default = "${pkgs.gcc}/bin/gcc"; };
|
||||||
type = types.str;
|
args = mkOption { type = types.listOf types.str; default = [ "-c" "-fpic" "../parser.c" "../scanner.c" "-I" ".." ]; };
|
||||||
default = "${pkgs.gcc}/bin/gcc";
|
flags = mkOption { type = types.listOf types.str; default = [ "-O3" ]; };
|
||||||
};
|
|
||||||
args = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [
|
|
||||||
"-c"
|
|
||||||
"-fpic"
|
|
||||||
"../parser.c"
|
|
||||||
"../scanner.c"
|
|
||||||
"-I"
|
|
||||||
".."
|
|
||||||
];
|
|
||||||
};
|
|
||||||
flags = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [ "-O3" ];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
grammar.link = {
|
grammar.link = {
|
||||||
command = mkOption {
|
command = mkOption { type = types.str; default = "${pkgs.gcc}/bin/gcc"; };
|
||||||
type = types.str;
|
args = mkOption { type = types.listOf types.str; default = [ "-shared" "-fpic" "parser.o" "scanner.o" ]; };
|
||||||
default = "${pkgs.gcc}/bin/gcc";
|
flags = mkOption { type = types.listOf types.str; default = [ "-O3" ]; };
|
||||||
};
|
|
||||||
args = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [
|
|
||||||
"-shared"
|
|
||||||
"-fpic"
|
|
||||||
"parser.o"
|
|
||||||
"scanner.o"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
flags = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [ "-O3" ];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
queries.src = mkOption {
|
queries.src = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
|
@ -68,42 +33,6 @@ let
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
mkGrammarPackage =
|
|
||||||
{
|
|
||||||
name,
|
|
||||||
src,
|
|
||||||
grammarPath ? "src",
|
|
||||||
grammarCompileArgs ? [
|
|
||||||
"-O3"
|
|
||||||
"-c"
|
|
||||||
"-fpic"
|
|
||||||
"../parser.c"
|
|
||||||
"../scanner.c"
|
|
||||||
"-I"
|
|
||||||
".."
|
|
||||||
],
|
|
||||||
grammarLinkArgs ? [
|
|
||||||
"-shared"
|
|
||||||
"-fpic"
|
|
||||||
"parser.o"
|
|
||||||
"scanner.o"
|
|
||||||
],
|
|
||||||
}:
|
|
||||||
pkgs.stdenv.mkDerivation {
|
|
||||||
inherit src;
|
|
||||||
name = "kak-tree-sitter-grammar-${name}.so";
|
|
||||||
version = "latest";
|
|
||||||
buildPhase = ''
|
|
||||||
mkdir ${grammarPath}/build
|
|
||||||
cd ${grammarPath}/build
|
|
||||||
$CC ${lib.concatStringsSep " " grammarCompileArgs}
|
|
||||||
$CC ${lib.concatStringsSep " " grammarLinkArgs} -o ${name}.so
|
|
||||||
'';
|
|
||||||
installPhase = ''
|
|
||||||
cp ${name}.so $out
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.programs.my-kakoune.tree-sitter = {
|
options.programs.my-kakoune.tree-sitter = {
|
||||||
|
@ -114,19 +43,6 @@ in
|
||||||
};
|
};
|
||||||
package = mkPackageOption pkgs "kak-tree-sitter" { };
|
package = mkPackageOption pkgs "kak-tree-sitter" { };
|
||||||
|
|
||||||
features = {
|
|
||||||
highlighting = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
description = "Enable highlighting";
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
text_objects = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
description = "Enable text objects";
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
highlighterGroups = mkOption {
|
highlighterGroups = mkOption {
|
||||||
type = types.attrsOf types.str;
|
type = types.attrsOf types.str;
|
||||||
default = {
|
default = {
|
||||||
|
@ -174,11 +90,11 @@ in
|
||||||
markup_link_url = "%opt{teal}+u";
|
markup_link_url = "%opt{teal}+u";
|
||||||
markup_link_uri = "%opt{teal}+u";
|
markup_link_uri = "%opt{teal}+u";
|
||||||
markup_link_text = "%opt{blue}";
|
markup_link_text = "%opt{blue}";
|
||||||
markup_quote = "%opt{crust}";
|
markup_quote = "%opt{gray1}";
|
||||||
markup_raw = "%opt{sky}";
|
markup_raw = "%opt{sky}";
|
||||||
markup_raw_block = "%opt{sky}";
|
markup_raw_block = "%opt{sky}";
|
||||||
markup_raw_inline = "%opt{green}";
|
markup_raw_inline = "%opt{green}";
|
||||||
markup_strikethrough = "%opt{crust}+s";
|
markup_strikethrough = "%opt{gray1}+s";
|
||||||
namespace = "@module";
|
namespace = "@module";
|
||||||
operator = "@operator";
|
operator = "@operator";
|
||||||
property = "%opt{sky}";
|
property = "%opt{sky}";
|
||||||
|
@ -197,12 +113,12 @@ in
|
||||||
tag = "%opt{teal}";
|
tag = "%opt{teal}";
|
||||||
tag_error = "%opt{red}";
|
tag_error = "%opt{red}";
|
||||||
text_title = "%opt{mauve}";
|
text_title = "%opt{mauve}";
|
||||||
type = "@type";
|
type = "%opt{yellow}";
|
||||||
type_enum_variant = "+i@ts_type";
|
type_enum_variant = "%opt{flamingo}";
|
||||||
variable = "@variable";
|
variable = "@variable";
|
||||||
variable_builtin = "@builtin";
|
variable_builtin = "@builtin";
|
||||||
variable_other_member = "%opt{teal}";
|
variable_other_member = "%opt{teal}";
|
||||||
variable_parameter = "+i@variable";
|
variable_parameter = "%opt{maroon}+i";
|
||||||
warning = "%opt{peach}+b";
|
warning = "%opt{peach}+b";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -258,6 +174,8 @@ in
|
||||||
|
|
||||||
config =
|
config =
|
||||||
let
|
let
|
||||||
|
aliasedOnce = name: values: if asserts.assertMsg (builtins.length values 1) "face ${name} was aliased more than once: ${toString values}" then (builtins.head values) else [ ];
|
||||||
|
|
||||||
allGroups = attrsets.recursiveUpdate cfg.highlighterGroups cfg.extraHighlighterGroups;
|
allGroups = attrsets.recursiveUpdate cfg.highlighterGroups cfg.extraHighlighterGroups;
|
||||||
|
|
||||||
aliases = attrsets.recursiveUpdate cfg.aliases cfg.extraAliases;
|
aliases = attrsets.recursiveUpdate cfg.aliases cfg.extraAliases;
|
||||||
|
@ -265,70 +183,60 @@ in
|
||||||
toTs = name: "ts_${strings.concatStringsSep "_" (strings.splitString "." name)}";
|
toTs = name: "ts_${strings.concatStringsSep "_" (strings.splitString "." name)}";
|
||||||
toScm = name: strings.concatStringsSep "." (strings.splitString "_" name);
|
toScm = name: strings.concatStringsSep "." (strings.splitString "_" name);
|
||||||
|
|
||||||
definedFaces = attrsets.mapAttrs' (name: value: {
|
definedFaces = attrsets.mapAttrs' (name: value: { inherit value; name = toTs name; }) allGroups;
|
||||||
inherit value;
|
aliasFaces = attrsets.mapAttrs' (name: value: { name = toTs name; value = "@${toTs value}"; }) aliases;
|
||||||
name = toTs name;
|
|
||||||
}) allGroups;
|
|
||||||
aliasFaces = attrsets.mapAttrs' (name: value: {
|
|
||||||
name = toTs name;
|
|
||||||
value = "@${toTs value}";
|
|
||||||
}) aliases;
|
|
||||||
faces = attrsets.recursiveUpdate definedFaces aliasFaces;
|
faces = attrsets.recursiveUpdate definedFaces aliasFaces;
|
||||||
|
|
||||||
toml = pkgs.formats.toml { };
|
toml = pkgs.formats.toml { };
|
||||||
|
|
||||||
toLanguageConf =
|
toLanguageConf = name: lang: with lang; {
|
||||||
name: lang: with lang; {
|
|
||||||
grammar = {
|
grammar = {
|
||||||
source.local.path = mkGrammarPackage {
|
inherit (grammar) path;
|
||||||
inherit name;
|
url = "${grammar.src}";
|
||||||
src = grammar.src;
|
|
||||||
grammarPath = grammar.path;
|
|
||||||
grammarCompileArgs = grammar.compile.flags ++ grammar.compile.args;
|
|
||||||
grammarLinkArgs = grammar.link.flags ++ grammar.link.args;
|
|
||||||
};
|
|
||||||
compile = grammar.compile.command;
|
compile = grammar.compile.command;
|
||||||
compile_args = grammar.compile.args;
|
compile_args = grammar.compile.args;
|
||||||
compile_flags = grammar.compile.flags;
|
compile_flags = grammar.compile.flags;
|
||||||
link = grammar.link.command;
|
link = grammar.link.command;
|
||||||
link_args = grammar.link.args ++ [
|
link_args = grammar.link.args ++ [ "-o" "${name}.so" ];
|
||||||
"-o"
|
|
||||||
"${name}.so"
|
|
||||||
];
|
|
||||||
link_flags = grammar.link.flags;
|
link_flags = grammar.link.flags;
|
||||||
};
|
};
|
||||||
queries = rec {
|
queries = {
|
||||||
|
url = "${queries.src}";
|
||||||
path = if queries.path == null then "runtime/queries/${name}" else queries.path;
|
path = if queries.path == null then "runtime/queries/${name}" else queries.path;
|
||||||
source.local.path = "${queries.src}/${path}";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
mkIf cfg.enable {
|
mkIf cfg.enable {
|
||||||
assertions =
|
assertions = with lib.asserts; ([ ]
|
||||||
with lib.asserts;
|
++ attrsets.mapAttrsToList
|
||||||
(
|
(name: _: {
|
||||||
[ ]
|
|
||||||
++ attrsets.mapAttrsToList (name: _: {
|
|
||||||
assertion = (! (builtins.hasAttr name allGroups));
|
assertion = (! (builtins.hasAttr name allGroups));
|
||||||
message = "${name} was both defined and aliased";
|
message = "${name} was both defined and aliased";
|
||||||
}) aliases
|
})
|
||||||
|
aliases
|
||||||
);
|
);
|
||||||
home.packages = [ cfg.package ];
|
home.packages = [ cfg.package ];
|
||||||
|
|
||||||
xdg.configFile."kak-tree-sitter/config.toml" = {
|
xdg.configFile."kak-tree-sitter/config.toml" = {
|
||||||
source = toml.generate "config.toml" {
|
source = toml.generate "config.toml" {
|
||||||
highlight.groups = builtins.map toScm (builtins.attrNames allGroups ++ builtins.attrNames aliases);
|
highlight.groups = builtins.map toScm (builtins.attrNames allGroups ++ builtins.attrNames aliases);
|
||||||
features = cfg.features;
|
|
||||||
language = builtins.mapAttrs toLanguageConf cfg.languages;
|
language = builtins.mapAttrs toLanguageConf cfg.languages;
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
programs.my-kakoune.extraFaces = faces;
|
onChange =
|
||||||
programs.my-kakoune.autoloadFile."kak-tree-sitter.kak".text = ''
|
let
|
||||||
# Enable kak-tree-sitter
|
buildCmd = lang: "ktsctl -fci ${lang}";
|
||||||
eval %sh{kak-tree-sitter --kakoune -d --server --init $kak_session}
|
buildAll = strings.concatMapStringsSep "\n" buildCmd (builtins.attrNames cfg.languages);
|
||||||
map global normal <c-t> ": enter-user-mode tree-sitter<ret>"
|
in
|
||||||
|
''
|
||||||
|
# Rebuild languages
|
||||||
|
${buildAll}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
programs.my-kakoune.extraFaces = faces;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,9 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
let
|
||||||
cfg = config.nki.programs.kitty;
|
cfg = config.nki.programs.kitty;
|
||||||
cmd = "cmd";
|
cmd = "cmd";
|
||||||
in
|
in
|
||||||
with lib;
|
with lib; {
|
||||||
{
|
|
||||||
programs.kitty = mkIf (cfg.enable && pkgs.stdenv.isDarwin) {
|
programs.kitty = mkIf (cfg.enable && pkgs.stdenv.isDarwin) {
|
||||||
|
|
||||||
# Darwin-specific setup
|
# Darwin-specific setup
|
||||||
|
@ -30,3 +24,4 @@ with lib;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,49 +1,15 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.nki.programs.kitty;
|
cfg = config.nki.programs.kitty;
|
||||||
|
cmd = if pkgs.stdenv.isDarwin then "cmd" else "ctrl";
|
||||||
theme =
|
|
||||||
{
|
|
||||||
lib,
|
|
||||||
options,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
programs.kitty = lib.mkIf config.nki.programs.kitty.enable (
|
|
||||||
if builtins.hasAttr "themeFile" options.programs.kitty then
|
|
||||||
{
|
|
||||||
themeFile = "ayu_light";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
theme = "Ayu Light";
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
in
|
in
|
||||||
with lib;
|
with lib;
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [ ./darwin.nix ./linux.nix ./tabs.nix ];
|
||||||
theme
|
|
||||||
./darwin.nix
|
|
||||||
./linux.nix
|
|
||||||
./tabs.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
options.nki.programs.kitty = {
|
options.nki.programs.kitty = {
|
||||||
enable = mkEnableOption "Enable kitty";
|
enable = mkEnableOption "Enable kitty";
|
||||||
setDefault = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
description = "Set kitty as default terminal";
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
package = mkOption {
|
package = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
|
@ -76,11 +42,7 @@ with lib;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config.programs.kitty = mkIf cfg.enable {
|
||||||
linux.graphical = mkIf cfg.setDefault {
|
|
||||||
defaults.terminal.package = cfg.package;
|
|
||||||
};
|
|
||||||
programs.kitty = {
|
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
package = cfg.package;
|
package = cfg.package;
|
||||||
|
@ -89,17 +51,16 @@ with lib;
|
||||||
font.name = "Fantasque Sans Mono";
|
font.name = "Fantasque Sans Mono";
|
||||||
font.size = cfg.fontSize;
|
font.size = cfg.fontSize;
|
||||||
|
|
||||||
|
theme = "Ayu Light";
|
||||||
|
|
||||||
settings =
|
settings =
|
||||||
let
|
let
|
||||||
# Background color and transparency
|
# Background color and transparency
|
||||||
background =
|
background =
|
||||||
if isNull cfg.background then
|
if isNull cfg.background then {
|
||||||
{
|
background_opacity = "0.85";
|
||||||
background_opacity = "0.93";
|
|
||||||
dynamic_background_opacity = true;
|
dynamic_background_opacity = true;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
background_image = "${cfg.background}";
|
background_image = "${cfg.background}";
|
||||||
background_image_layout = "scaled";
|
background_image_layout = "scaled";
|
||||||
background_tint = "0.85";
|
background_tint = "0.85";
|
||||||
|
@ -129,52 +90,9 @@ with lib;
|
||||||
## Clear screen
|
## Clear screen
|
||||||
"${cfg.cmd}+backspace" = "clear_terminal to_cursor active";
|
"${cfg.cmd}+backspace" = "clear_terminal to_cursor active";
|
||||||
"${cfg.cmd}+shift+backspace" = "clear_terminal reset active";
|
"${cfg.cmd}+shift+backspace" = "clear_terminal reset active";
|
||||||
|
## Hints
|
||||||
## Command scrolling
|
"${cfg.cmd}+shift+p>n" = "kitten hints --type=linenum --linenum-action=tab kak {path} +{line}";
|
||||||
"${cfg.cmd}+shift+j" = "scroll_to_prompt 1";
|
|
||||||
"${cfg.cmd}+shift+k" = "scroll_to_prompt -1";
|
|
||||||
};
|
|
||||||
|
|
||||||
extraConfig =
|
|
||||||
let
|
|
||||||
# Nerd Fonts glyph map
|
|
||||||
glyphMap = pkgs.fetchurl {
|
|
||||||
url = "https://raw.githubusercontent.com/Sharparam/dotfiles/main/kitty/.config/kitty/font-nerd-symbols.conf";
|
|
||||||
hash = "sha256-1OaDWLC3y8ASD2ttRWWgPEpRnfKXu6H6vS3cFVpzT0o=";
|
|
||||||
};
|
|
||||||
in
|
|
||||||
''
|
|
||||||
include ${glyphMap}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
# Open protocol
|
|
||||||
xdg.configFile."kitty/open-actions.conf".text = ''
|
|
||||||
protocol file
|
|
||||||
fragment_matches [0-9]+
|
|
||||||
action launch --type=overlay --cwd=current -- $\{EDITOR} +$\{FRAGMENT} -- $\{FILE_PATH}
|
|
||||||
|
|
||||||
# Open HTML files with xdg-open
|
|
||||||
protocol file
|
|
||||||
mime text/html
|
|
||||||
action launch xdg-open $\{FILE_PATH}
|
|
||||||
|
|
||||||
# Open text files without fragments in the editor
|
|
||||||
protocol file
|
|
||||||
mime text/*
|
|
||||||
action launch --type=overlay --cwd=current -- $\{EDITOR} -- $\{FILE_PATH}
|
|
||||||
|
|
||||||
# Open other files with xdg-open
|
|
||||||
protocol file
|
|
||||||
action launch xdg-open $\{FILE_PATH}
|
|
||||||
'';
|
|
||||||
|
|
||||||
programs.fish.shellAliases = {
|
|
||||||
"ssh+" = "kitten ssh";
|
|
||||||
"clip" = "kitten clipboard";
|
|
||||||
"eg" = "kitten hyperlinked-grep";
|
|
||||||
"icat" = "kitten icat";
|
|
||||||
"notify" = "kitten notify";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ config, pkgs, lib, ... }:
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
let
|
||||||
cfg = config.nki.programs.kitty;
|
cfg = config.nki.programs.kitty;
|
||||||
in
|
in
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ config, pkgs, lib, ... }:
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.nki.programs.kitty;
|
cfg = config.nki.programs.kitty;
|
||||||
|
@ -12,8 +7,7 @@ in
|
||||||
with lib;
|
with lib;
|
||||||
{
|
{
|
||||||
programs.kitty = mkIf cfg.enableTabs {
|
programs.kitty = mkIf cfg.enableTabs {
|
||||||
keybindings =
|
keybindings = {
|
||||||
{
|
|
||||||
"${cmd}+t" = "new_tab_with_cwd";
|
"${cmd}+t" = "new_tab_with_cwd";
|
||||||
"${cmd}+shift+t" = "new_tab";
|
"${cmd}+shift+t" = "new_tab";
|
||||||
"${cmd}+shift+o" = "launch --cwd=current --location=vsplit";
|
"${cmd}+shift+o" = "launch --cwd=current --location=vsplit";
|
||||||
|
@ -36,9 +30,10 @@ with lib;
|
||||||
"${cmd}+f" = "toggle_layout stack";
|
"${cmd}+f" = "toggle_layout stack";
|
||||||
}
|
}
|
||||||
# Tab bindings
|
# Tab bindings
|
||||||
// builtins.listToAttrs (
|
// builtins.listToAttrs
|
||||||
map (x: attrsets.nameValuePair "${cmd}+${toString x}" "goto_tab ${toString x}") (lists.range 1 9)
|
(map
|
||||||
);
|
(x: attrsets.nameValuePair "${cmd}+${toString x}" "goto_tab ${toString x}")
|
||||||
|
(lists.range 1 9));
|
||||||
settings = {
|
settings = {
|
||||||
# Tab settings
|
# Tab settings
|
||||||
tab_bar_edge = "top";
|
tab_bar_edge = "top";
|
||||||
|
|
|
@ -1,583 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
osConfig,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.programs.my-niri;
|
|
||||||
|
|
||||||
sh = config.lib.niri.actions.spawn "sh" "-c";
|
|
||||||
playerctl = lib.getExe pkgs.playerctl;
|
|
||||||
amixer = lib.getExe' pkgs.alsa-utils "amixer";
|
|
||||||
brightnessctl = lib.getExe pkgs.brightnessctl;
|
|
||||||
app-menu = "${pkgs.dmenu}/bin/dmenu_path | ${pkgs.bemenu}/bin/bemenu | ${pkgs.findutils}/bin/xargs niri msg action spawn --";
|
|
||||||
|
|
||||||
wallpaper = config.linux.graphical.wallpaper;
|
|
||||||
|
|
||||||
xwayland-display = ":0";
|
|
||||||
|
|
||||||
# Override for lack of per-keyboard layout
|
|
||||||
ydotool-en = pkgs.writeScriptBin "ydotool" ''
|
|
||||||
#!/usr/bin/env sh
|
|
||||||
niri msg action switch-layout 1 && fcitx5-remote -c # us
|
|
||||||
${lib.getExe pkgs.ydotool} "$@"
|
|
||||||
niri msg action switch-layout 0 # ja
|
|
||||||
'';
|
|
||||||
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.programs.my-niri = {
|
|
||||||
enable = lib.mkEnableOption "My own niri configuration";
|
|
||||||
|
|
||||||
enableLaptop = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Enable laptop options";
|
|
||||||
};
|
|
||||||
|
|
||||||
lock-command = lib.mkOption {
|
|
||||||
type = lib.types.listOf lib.types.str;
|
|
||||||
description = "The command to lock the screen";
|
|
||||||
default =
|
|
||||||
[ "${pkgs.swaylock}/bin/swaylock" ]
|
|
||||||
++ (
|
|
||||||
if wallpaper == "" then
|
|
||||||
[ "" ]
|
|
||||||
else
|
|
||||||
[
|
|
||||||
"-i"
|
|
||||||
"${wallpaper}"
|
|
||||||
"-s"
|
|
||||||
"fill"
|
|
||||||
]
|
|
||||||
)
|
|
||||||
++ [
|
|
||||||
"-l"
|
|
||||||
"-k"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
workspaces = lib.mkOption {
|
|
||||||
type = lib.types.attrsOf (
|
|
||||||
lib.types.submodule {
|
|
||||||
options = {
|
|
||||||
name = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = "workspace name";
|
|
||||||
};
|
|
||||||
fixed = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
description = "whether workspace always exists";
|
|
||||||
};
|
|
||||||
monitor = lib.mkOption {
|
|
||||||
type = lib.types.nullOr lib.types.str;
|
|
||||||
default = null;
|
|
||||||
description = "Default monitor to spawn workspace in";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
description = "A mapping of ordering to workspace names, for fixed workspaces";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
home.packages = [ ydotool-en ];
|
|
||||||
programs.my-niri.workspaces = {
|
|
||||||
# Default workspaces, always there
|
|
||||||
"01" = {
|
|
||||||
name = "🌏 web";
|
|
||||||
};
|
|
||||||
"02" = {
|
|
||||||
name = "💬 chat";
|
|
||||||
};
|
|
||||||
"03" = {
|
|
||||||
name = "⚙️ code";
|
|
||||||
};
|
|
||||||
"04" = {
|
|
||||||
name = "🎶 music";
|
|
||||||
};
|
|
||||||
"05" = {
|
|
||||||
name = "🔧 extra";
|
|
||||||
};
|
|
||||||
"06" = {
|
|
||||||
name = "🧰 6";
|
|
||||||
};
|
|
||||||
"07" = {
|
|
||||||
name = "🔩 7";
|
|
||||||
};
|
|
||||||
"08" = {
|
|
||||||
name = "🛠️ 8";
|
|
||||||
};
|
|
||||||
"09" = {
|
|
||||||
name = "🔨 9";
|
|
||||||
};
|
|
||||||
"10" = {
|
|
||||||
name = "🎲 misc";
|
|
||||||
};
|
|
||||||
"99" = {
|
|
||||||
name = "📧 Email";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
systemd.user.services.swaync.Install.WantedBy = [ "niri.service" ];
|
|
||||||
systemd.user.services.swaync.Unit.After = [ "niri.service" ];
|
|
||||||
systemd.user.targets.tray.Unit.After = [ "niri.service" ];
|
|
||||||
systemd.user.targets.xwayland.Unit.After = [ "niri.service" ];
|
|
||||||
|
|
||||||
programs.my-waybar = {
|
|
||||||
enable = true;
|
|
||||||
enableLaptopBars = lib.mkDefault cfg.enableLaptop;
|
|
||||||
};
|
|
||||||
systemd.user.services.waybar.Unit.After = [ "niri.service" ];
|
|
||||||
systemd.user.services.waybar.Install.WantedBy = [ "niri.service" ];
|
|
||||||
|
|
||||||
# xwayland-satellite
|
|
||||||
systemd.user.services.niri-xwayland-satellite = lib.mkIf cfg.enable {
|
|
||||||
Unit = {
|
|
||||||
Description = "XWayland Client for niri";
|
|
||||||
PartOf = [ "xwayland.target" ];
|
|
||||||
Before = [
|
|
||||||
"xwayland.target"
|
|
||||||
"xdg-desktop-autostart.target"
|
|
||||||
];
|
|
||||||
After = [ "niri.service" ];
|
|
||||||
};
|
|
||||||
Install.WantedBy = [ "niri.service" ];
|
|
||||||
Install.UpheldBy = [ "niri.service" ];
|
|
||||||
Service.Slice = "session.slice";
|
|
||||||
Service.Type = "notify";
|
|
||||||
Service.ExecStart = "${lib.getExe pkgs.xwayland-satellite} ${xwayland-display}";
|
|
||||||
Service.ExecStartPost = [ "systemctl --user set-environment DISPLAY=${xwayland-display}" ];
|
|
||||||
Service.ExecStopPost = [ "systemctl --user unset-environment" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
programs.niri.settings = {
|
|
||||||
environment =
|
|
||||||
{
|
|
||||||
QT_QPA_PLATFORM = "wayland";
|
|
||||||
QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
|
|
||||||
QT_IM_MODULE = "fcitx";
|
|
||||||
# export NIXOS_OZONE_WL=1 # Until text-input is merged
|
|
||||||
DISPLAY = xwayland-display;
|
|
||||||
}
|
|
||||||
// lib.optionalAttrs osConfig.services.desktopManager.plasma6.enable {
|
|
||||||
XDG_MENU_PREFIX = "plasma-";
|
|
||||||
};
|
|
||||||
input.keyboard.xkb = {
|
|
||||||
layout = "jp,us";
|
|
||||||
};
|
|
||||||
input.touchpad = lib.mkIf cfg.enableLaptop {
|
|
||||||
tap = true;
|
|
||||||
dwt = true;
|
|
||||||
natural-scroll = true;
|
|
||||||
middle-emulation = true;
|
|
||||||
};
|
|
||||||
input.mouse = {
|
|
||||||
accel-profile = "flat";
|
|
||||||
};
|
|
||||||
input.warp-mouse-to-focus = true;
|
|
||||||
input.focus-follows-mouse = {
|
|
||||||
enable = true;
|
|
||||||
max-scroll-amount = "0%";
|
|
||||||
};
|
|
||||||
|
|
||||||
outputs =
|
|
||||||
let
|
|
||||||
eachMonitor = _: monitor: {
|
|
||||||
name = monitor.meta.niriName or monitor.name; # Niri might not find the monitor by name
|
|
||||||
value = {
|
|
||||||
mode = monitor.meta.mode;
|
|
||||||
position = monitor.meta.fixedPosition or null;
|
|
||||||
scale = monitor.scale or 1;
|
|
||||||
variable-refresh-rate = (monitor.adaptive_sync or "off") == "on";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in
|
|
||||||
lib.mapAttrs' eachMonitor config.common.monitors;
|
|
||||||
|
|
||||||
spawn-at-startup = [
|
|
||||||
# Wallpaper
|
|
||||||
{
|
|
||||||
command = [
|
|
||||||
(lib.getExe pkgs.swaybg)
|
|
||||||
"-i"
|
|
||||||
"${wallpaper}"
|
|
||||||
"-m"
|
|
||||||
"fill"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
# Waybar
|
|
||||||
{
|
|
||||||
command = [
|
|
||||||
"systemctl"
|
|
||||||
"--user"
|
|
||||||
"start"
|
|
||||||
"xdg-desktop-portal-gtk.service"
|
|
||||||
"xdg-desktop-portal.service"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
layout = {
|
|
||||||
gaps = 16;
|
|
||||||
preset-column-widths = [
|
|
||||||
{ proportion = 1. / 3.; }
|
|
||||||
{ proportion = 1. / 2.; }
|
|
||||||
{ proportion = 2. / 3.; }
|
|
||||||
];
|
|
||||||
default-column-width.proportion = 1. / 2.;
|
|
||||||
|
|
||||||
focus-ring = {
|
|
||||||
width = 4;
|
|
||||||
active.gradient = {
|
|
||||||
from = "#00447AFF";
|
|
||||||
to = "#71C4FFAA";
|
|
||||||
angle = 45;
|
|
||||||
};
|
|
||||||
inactive.color = "#505050";
|
|
||||||
};
|
|
||||||
border.enable = false;
|
|
||||||
struts =
|
|
||||||
let
|
|
||||||
v = 8;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
left = v;
|
|
||||||
right = v;
|
|
||||||
bottom = v;
|
|
||||||
top = v;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
prefer-no-csd = true;
|
|
||||||
|
|
||||||
workspaces =
|
|
||||||
let
|
|
||||||
fixedWorkspaces = lib.filterAttrs (_: w: w.fixed) cfg.workspaces;
|
|
||||||
workspaceConfig = lib.mapAttrs (
|
|
||||||
_: w:
|
|
||||||
{
|
|
||||||
inherit (w) name;
|
|
||||||
}
|
|
||||||
// (lib.optionalAttrs (w.monitor != null) {
|
|
||||||
open-on-output = w.monitor;
|
|
||||||
})
|
|
||||||
) fixedWorkspaces;
|
|
||||||
in
|
|
||||||
workspaceConfig;
|
|
||||||
|
|
||||||
window-rules = [
|
|
||||||
# Rounded Corners
|
|
||||||
{
|
|
||||||
geometry-corner-radius =
|
|
||||||
let
|
|
||||||
v = 8.0;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
bottom-left = v;
|
|
||||||
bottom-right = v;
|
|
||||||
top-left = v;
|
|
||||||
top-right = v;
|
|
||||||
};
|
|
||||||
clip-to-geometry = true;
|
|
||||||
}
|
|
||||||
# Workspace assignments
|
|
||||||
{
|
|
||||||
open-on-workspace = cfg.workspaces."01".name;
|
|
||||||
open-maximized = true;
|
|
||||||
matches = [
|
|
||||||
{
|
|
||||||
at-startup = true;
|
|
||||||
app-id = "^firefox$";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
at-startup = true;
|
|
||||||
app-id = "^librewolf$";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
at-startup = true;
|
|
||||||
app-id = "^zen$";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
open-on-workspace = cfg.workspaces."02".name;
|
|
||||||
open-maximized = true;
|
|
||||||
matches = [
|
|
||||||
{ title = "^((d|D)iscord|((A|a)rm(c|C)ord))$"; }
|
|
||||||
{ title = "VencordDesktop"; }
|
|
||||||
{ app-id = "VencordDesktop"; }
|
|
||||||
{ title = "vesktop"; }
|
|
||||||
{ app-id = "vesktop"; }
|
|
||||||
|
|
||||||
{ title = "Slack"; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
open-on-workspace = cfg.workspaces."99".name;
|
|
||||||
open-maximized = true;
|
|
||||||
matches = [
|
|
||||||
{ app-id = "thunderbird"; }
|
|
||||||
{ app-id = "evolution"; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
# Floating
|
|
||||||
{
|
|
||||||
open-floating = true;
|
|
||||||
matches = [
|
|
||||||
{ app-id = ".*float.*"; }
|
|
||||||
{ app-id = "org\\.freedesktop\\.impl\\.portal\\.desktop\\..*"; }
|
|
||||||
{ title = ".*float.*"; }
|
|
||||||
{ title = "Extension: .*Bitwarden.*"; }
|
|
||||||
{ app-id = "Rofi"; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
# xwaylandvideobridge
|
|
||||||
{
|
|
||||||
matches = [ { app-id = "^xwaylandvideobridge$"; } ];
|
|
||||||
open-floating = true;
|
|
||||||
focus-ring.enable = false;
|
|
||||||
opacity = 0.0;
|
|
||||||
default-floating-position = {
|
|
||||||
x = 0;
|
|
||||||
y = 0;
|
|
||||||
relative-to = "bottom-right";
|
|
||||||
};
|
|
||||||
min-width = 1;
|
|
||||||
max-width = 1;
|
|
||||||
min-height = 1;
|
|
||||||
max-height = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Kitty dimming
|
|
||||||
{
|
|
||||||
matches = [ { app-id = "kitty"; } ];
|
|
||||||
excludes = [ { is-focused = true; } ];
|
|
||||||
opacity = 0.95;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
layer-rules = [
|
|
||||||
{
|
|
||||||
matches = [ { namespace = "^swaync-.*"; } ];
|
|
||||||
block-out-from = "screen-capture";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
binds = with config.lib.niri.actions; {
|
|
||||||
# Mod-Shift-/, which is usually the same as Mod-?,
|
|
||||||
# shows a list of important hotkeys.
|
|
||||||
"Mod+Shift+Slash".action = show-hotkey-overlay;
|
|
||||||
|
|
||||||
# Some basic spawns
|
|
||||||
"Mod+Return".action = spawn (lib.getExe config.linux.graphical.defaults.terminal.package);
|
|
||||||
"Mod+Space".action = spawn "rofi" "-show" "drun";
|
|
||||||
"Mod+R".action = sh app-menu;
|
|
||||||
"Mod+Semicolon".action = spawn cfg.lock-command;
|
|
||||||
"Mod+Shift+P".action = spawn "rofi-rbw-script";
|
|
||||||
|
|
||||||
# Audio and Volume
|
|
||||||
"XF86AudioPrev" = {
|
|
||||||
action = spawn playerctl "previous";
|
|
||||||
allow-when-locked = true;
|
|
||||||
};
|
|
||||||
"XF86AudioPlay" = {
|
|
||||||
action = spawn playerctl "play-pause";
|
|
||||||
allow-when-locked = true;
|
|
||||||
};
|
|
||||||
"Shift+XF86AudioPlay" = {
|
|
||||||
action = spawn playerctl "stop";
|
|
||||||
allow-when-locked = true;
|
|
||||||
};
|
|
||||||
"XF86AudioNext" = {
|
|
||||||
action = spawn playerctl "next";
|
|
||||||
allow-when-locked = true;
|
|
||||||
};
|
|
||||||
"XF86AudioRecord" = {
|
|
||||||
action = spawn amixer "-q" "set" "Capture" "toggle";
|
|
||||||
allow-when-locked = true;
|
|
||||||
};
|
|
||||||
"XF86AudioMute" = {
|
|
||||||
action = spawn amixer "-q" "set" "Master" "toggle";
|
|
||||||
allow-when-locked = true;
|
|
||||||
};
|
|
||||||
"XF86AudioLowerVolume" = {
|
|
||||||
action = spawn amixer "-q" "set" "Master" "3%-";
|
|
||||||
allow-when-locked = true;
|
|
||||||
};
|
|
||||||
"XF86AudioRaiseVolume" = {
|
|
||||||
action = spawn amixer "-q" "set" "Master" "3%+";
|
|
||||||
allow-when-locked = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Backlight
|
|
||||||
"XF86MonBrightnessDown".action = spawn brightnessctl "s" "10%-";
|
|
||||||
"XF86MonBrightnessUp".action = spawn brightnessctl "s" "10%+";
|
|
||||||
"Shift+XF86MonBrightnessDown".action = spawn brightnessctl "-d" "kbd_backlight" "s" "25%-";
|
|
||||||
"Shift+XF86MonBrightnessUp".action = spawn brightnessctl "-d" "kbd_backlight" "s" "25%+";
|
|
||||||
|
|
||||||
"Mod+Shift+Q".action = close-window;
|
|
||||||
|
|
||||||
"Mod+Left".action = focus-column-or-monitor-left;
|
|
||||||
"Mod+Right".action = focus-column-or-monitor-right;
|
|
||||||
"Mod+Up".action = focus-window-or-workspace-up;
|
|
||||||
"Mod+Down".action = focus-window-or-workspace-down;
|
|
||||||
"Mod+H".action = focus-column-or-monitor-left;
|
|
||||||
"Mod+L".action = focus-column-or-monitor-right;
|
|
||||||
"Mod+K".action = focus-window-or-workspace-up;
|
|
||||||
"Mod+J".action = focus-window-or-workspace-down;
|
|
||||||
|
|
||||||
"Mod+Shift+Left".action = move-column-left-or-to-monitor-left;
|
|
||||||
"Mod+Shift+Right".action = move-column-right-or-to-monitor-right;
|
|
||||||
"Mod+Shift+Up".action = move-window-up-or-to-workspace-up;
|
|
||||||
"Mod+Shift+Down".action = move-window-down-or-to-workspace-down;
|
|
||||||
"Mod+Shift+H".action = move-column-left-or-to-monitor-left;
|
|
||||||
"Mod+Shift+L".action = move-column-right-or-to-monitor-right;
|
|
||||||
"Mod+Shift+K".action = move-window-up-or-to-workspace-up;
|
|
||||||
"Mod+Shift+J".action = move-window-down-or-to-workspace-down;
|
|
||||||
|
|
||||||
"Mod+Bracketleft".action = focus-column-first;
|
|
||||||
"Mod+Bracketright".action = focus-column-last;
|
|
||||||
"Mod+Shift+Bracketleft".action = move-column-to-first;
|
|
||||||
"Mod+Shift+Bracketright".action = move-column-to-last;
|
|
||||||
|
|
||||||
# For compat with my current sway
|
|
||||||
"Mod+Ctrl+H".action = move-workspace-to-monitor-left;
|
|
||||||
"Mod+Ctrl+L".action = move-workspace-to-monitor-right;
|
|
||||||
|
|
||||||
"Mod+I".action = focus-workspace-down;
|
|
||||||
"Mod+O".action = focus-workspace-up;
|
|
||||||
"Mod+Shift+I".action = move-column-to-workspace-down;
|
|
||||||
"Mod+Shift+O".action = move-column-to-workspace-up;
|
|
||||||
"Mod+Ctrl+I".action = move-workspace-down;
|
|
||||||
"Mod+Ctrl+O".action = move-workspace-up;
|
|
||||||
|
|
||||||
# Mouse bindings
|
|
||||||
"Mod+WheelScrollDown" = {
|
|
||||||
action = focus-workspace-down;
|
|
||||||
cooldown-ms = 150;
|
|
||||||
};
|
|
||||||
"Mod+WheelScrollUp" = {
|
|
||||||
action = focus-workspace-up;
|
|
||||||
cooldown-ms = 150;
|
|
||||||
};
|
|
||||||
"Mod+Ctrl+WheelScrollDown" = {
|
|
||||||
action = move-column-to-workspace-down;
|
|
||||||
cooldown-ms = 150;
|
|
||||||
};
|
|
||||||
"Mod+Ctrl+WheelScrollUp" = {
|
|
||||||
action = move-column-to-workspace-up;
|
|
||||||
cooldown-ms = 150;
|
|
||||||
};
|
|
||||||
|
|
||||||
"Mod+WheelScrollRight".action = focus-column-right;
|
|
||||||
"Mod+WheelScrollLeft".action = focus-column-left;
|
|
||||||
"Mod+Ctrl+WheelScrollRight".action = move-column-right;
|
|
||||||
"Mod+Ctrl+WheelScrollLeft".action = move-column-left;
|
|
||||||
|
|
||||||
# You can refer to workspaces by index. However, keep in mind that
|
|
||||||
# niri is a dynamic workspace system, so these commands are kind of
|
|
||||||
# "best effort". Trying to refer to a workspace index bigger than
|
|
||||||
# the current workspace count will instead refer to the bottommost
|
|
||||||
# (empty) workspace.
|
|
||||||
#
|
|
||||||
# For example, with 2 workspaces + 1 empty, indices 3, 4, 5 and so on
|
|
||||||
# will all refer to the 3rd workspace.
|
|
||||||
"Mod+1" = lib.mkIf cfg.workspaces."01".fixed {
|
|
||||||
action = focus-workspace (cfg.workspaces."01".name);
|
|
||||||
};
|
|
||||||
"Mod+2" = lib.mkIf cfg.workspaces."02".fixed {
|
|
||||||
action = focus-workspace (cfg.workspaces."02".name);
|
|
||||||
};
|
|
||||||
"Mod+3" = lib.mkIf cfg.workspaces."03".fixed {
|
|
||||||
action = focus-workspace (cfg.workspaces."03".name);
|
|
||||||
};
|
|
||||||
"Mod+4" = lib.mkIf cfg.workspaces."04".fixed {
|
|
||||||
action = focus-workspace (cfg.workspaces."04".name);
|
|
||||||
};
|
|
||||||
"Mod+5" = lib.mkIf cfg.workspaces."05".fixed {
|
|
||||||
action = focus-workspace (cfg.workspaces."05".name);
|
|
||||||
};
|
|
||||||
"Mod+6" = lib.mkIf cfg.workspaces."06".fixed {
|
|
||||||
action = focus-workspace (cfg.workspaces."06".name);
|
|
||||||
};
|
|
||||||
"Mod+7" = lib.mkIf cfg.workspaces."07".fixed {
|
|
||||||
action = focus-workspace (cfg.workspaces."07".name);
|
|
||||||
};
|
|
||||||
"Mod+8" = lib.mkIf cfg.workspaces."08".fixed {
|
|
||||||
action = focus-workspace (cfg.workspaces."08".name);
|
|
||||||
};
|
|
||||||
"Mod+9" = lib.mkIf cfg.workspaces."09".fixed {
|
|
||||||
action = focus-workspace (cfg.workspaces."09".name);
|
|
||||||
};
|
|
||||||
"Mod+0" = lib.mkIf cfg.workspaces."10".fixed {
|
|
||||||
action = focus-workspace (cfg.workspaces."10".name);
|
|
||||||
};
|
|
||||||
"Mod+Shift+1" = lib.mkIf cfg.workspaces."01".fixed {
|
|
||||||
action = move-column-to-workspace (cfg.workspaces."01".name);
|
|
||||||
};
|
|
||||||
"Mod+Shift+2" = lib.mkIf cfg.workspaces."02".fixed {
|
|
||||||
action = move-column-to-workspace (cfg.workspaces."02".name);
|
|
||||||
};
|
|
||||||
"Mod+Shift+3" = lib.mkIf cfg.workspaces."03".fixed {
|
|
||||||
action = move-column-to-workspace (cfg.workspaces."03".name);
|
|
||||||
};
|
|
||||||
"Mod+Shift+4" = lib.mkIf cfg.workspaces."04".fixed {
|
|
||||||
action = move-column-to-workspace (cfg.workspaces."04".name);
|
|
||||||
};
|
|
||||||
"Mod+Shift+5" = lib.mkIf cfg.workspaces."05".fixed {
|
|
||||||
action = move-column-to-workspace (cfg.workspaces."05".name);
|
|
||||||
};
|
|
||||||
"Mod+Shift+6" = lib.mkIf cfg.workspaces."06".fixed {
|
|
||||||
action = move-column-to-workspace (cfg.workspaces."06".name);
|
|
||||||
};
|
|
||||||
"Mod+Shift+7" = lib.mkIf cfg.workspaces."07".fixed {
|
|
||||||
action = move-column-to-workspace (cfg.workspaces."07".name);
|
|
||||||
};
|
|
||||||
"Mod+Shift+8" = lib.mkIf cfg.workspaces."08".fixed {
|
|
||||||
action = move-column-to-workspace (cfg.workspaces."08".name);
|
|
||||||
};
|
|
||||||
"Mod+Shift+9" = lib.mkIf cfg.workspaces."09".fixed {
|
|
||||||
action = move-column-to-workspace (cfg.workspaces."09".name);
|
|
||||||
};
|
|
||||||
"Mod+Shift+0" = lib.mkIf cfg.workspaces."10".fixed {
|
|
||||||
action = move-column-to-workspace (cfg.workspaces."10".name);
|
|
||||||
};
|
|
||||||
|
|
||||||
"Mod+asciicircum".action = focus-workspace (cfg.workspaces."99".name);
|
|
||||||
"Mod+Shift+asciicircum".action = move-column-to-workspace (cfg.workspaces."99".name);
|
|
||||||
|
|
||||||
"Mod+Tab".action = focus-workspace-previous;
|
|
||||||
|
|
||||||
"Mod+Comma".action = consume-or-expel-window-left;
|
|
||||||
"Mod+Period".action = consume-or-expel-window-right;
|
|
||||||
|
|
||||||
"Mod+W".action = switch-preset-column-width;
|
|
||||||
"Mod+Shift+W".action = switch-preset-window-height;
|
|
||||||
"Mod+Ctrl+W".action = reset-window-height;
|
|
||||||
"Mod+F".action = maximize-column;
|
|
||||||
"Mod+Shift+F".action = fullscreen-window;
|
|
||||||
"Mod+E".action = center-column;
|
|
||||||
|
|
||||||
"Mod+Minus".action = set-column-width "-10%";
|
|
||||||
"Mod+At".action = set-column-width "+10%";
|
|
||||||
"Mod+Shift+Minus".action = set-window-height "-10%";
|
|
||||||
"Mod+Shift+At".action = set-window-height "+10%";
|
|
||||||
|
|
||||||
"Mod+V".action = switch-focus-between-floating-and-tiling;
|
|
||||||
"Mod+Shift+V".action = toggle-window-floating;
|
|
||||||
"Mod+Shift+Space".action = toggle-window-floating; # Sway compat
|
|
||||||
|
|
||||||
"Print".action = screenshot;
|
|
||||||
"Ctrl+Print".action.screenshot-screen = [ ];
|
|
||||||
"Shift+Print".action = screenshot-window;
|
|
||||||
|
|
||||||
"Mod+Shift+E".action = quit;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,11 +1,4 @@
|
||||||
{
|
{ pkgs, lib, config, ... }:
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
options,
|
|
||||||
config,
|
|
||||||
osConfig,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.programs.my-sway;
|
cfg = config.programs.my-sway;
|
||||||
|
@ -25,18 +18,13 @@ let
|
||||||
"9:🔨 9"
|
"9:🔨 9"
|
||||||
"10:🎲 misc"
|
"10:🎲 misc"
|
||||||
];
|
];
|
||||||
extraWorkspaces = {
|
|
||||||
mail = "📧 Email";
|
|
||||||
};
|
|
||||||
wsAttrs = builtins.listToAttrs (
|
wsAttrs = builtins.listToAttrs (
|
||||||
map (i: {
|
map
|
||||||
name = toString (remainder i 10);
|
(i: { name = toString (remainder i 10); value = builtins.elemAt workspaces (i - 1); })
|
||||||
value = builtins.elemAt workspaces (i - 1);
|
(range 1 11)
|
||||||
}) (range 1 11)
|
|
||||||
);
|
);
|
||||||
remainder = x: y: x - (builtins.div x y) * y;
|
remainder = x: y: x - (builtins.div x y) * y;
|
||||||
range =
|
range = from: to:
|
||||||
from: to:
|
|
||||||
let
|
let
|
||||||
f = cur: if cur == to then [ ] else [ cur ] ++ f (cur + 1);
|
f = cur: if cur == to then [ ] else [ cur ] ++ f (cur + 1);
|
||||||
in
|
in
|
||||||
|
@ -48,21 +36,15 @@ let
|
||||||
${pkgs.grim}/bin/grim -g (${pkgs.slurp}/bin/slurp) - | ${pkgs.wl-clipboard}/bin/wl-copy
|
${pkgs.grim}/bin/grim -g (${pkgs.slurp}/bin/slurp) - | ${pkgs.wl-clipboard}/bin/wl-copy
|
||||||
'';
|
'';
|
||||||
|
|
||||||
screenshotEditScript = pkgs.writeScriptBin "screenshot" ''
|
ignored-devices = [ "Surface_Headphones" ];
|
||||||
#! ${pkgs.fish}/bin/fish
|
playerctl = "${pkgs.playerctl}/bin/playerctl --ignore-player=${strings.concatStringsSep "," ignored-devices}";
|
||||||
|
|
||||||
${pkgs.grim}/bin/grim -g (${pkgs.slurp}/bin/slurp) - | ${pkgs.swappy}/bin/swappy -f -
|
|
||||||
'';
|
|
||||||
playerctl = "${pkgs.playerctl}/bin/playerctl";
|
|
||||||
|
|
||||||
terminalCmd = lib.getExe config.linux.graphical.defaults.terminal.package;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
# imports = [ ./ibus.nix ];
|
# imports = [ ./ibus.nix ];
|
||||||
|
|
||||||
options.programs.my-sway = {
|
options.programs.my-sway = {
|
||||||
enable = mkEnableOption "Enable the sway configuration";
|
enable = mkEnableOption "Enable the sway configuration";
|
||||||
package = mkPackageOption pkgs "swayfx" { };
|
|
||||||
fontSize = mkOption {
|
fontSize = mkOption {
|
||||||
type = types.float;
|
type = types.float;
|
||||||
description = "The default font size";
|
description = "The default font size";
|
||||||
|
@ -73,74 +55,67 @@ in
|
||||||
default = true;
|
default = true;
|
||||||
};
|
};
|
||||||
wallpaper = mkOption {
|
wallpaper = mkOption {
|
||||||
type = types.oneOf [
|
type = types.oneOf [ types.path types.str ];
|
||||||
types.path
|
|
||||||
types.str
|
|
||||||
];
|
|
||||||
description = "Path to the wallpaper to be used";
|
description = "Path to the wallpaper to be used";
|
||||||
default = config.linux.graphical.wallpaper;
|
default = "";
|
||||||
|
};
|
||||||
|
terminal = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The command to the terminal emulator to be used";
|
||||||
|
default = "${config.programs.kitty.package}/bin/kitty";
|
||||||
};
|
};
|
||||||
browser = mkOption {
|
browser = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
description = "The command for the browser";
|
description = "The command for the browser";
|
||||||
default = lib.getExe config.linux.graphical.defaults.webBrowser.package;
|
default = "${pkgs.firefox-wayland}/bin/firefox";
|
||||||
};
|
};
|
||||||
|
discord = mkOption {
|
||||||
enableLaptop = lib.mkOption {
|
type = types.nullOr types.str;
|
||||||
type = lib.types.bool;
|
description = "The command for discord";
|
||||||
description = "Whether to enable laptop-specific stuff";
|
default = "${config.nki.programs.discord.package}/bin/discord";
|
||||||
default = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
lockCmd = mkOption {
|
lockCmd = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
description = "The screen lock command";
|
description = "The screen lock command";
|
||||||
default =
|
default = "${pkgs.swaylock}/bin/swaylock"
|
||||||
"${pkgs.swaylock}/bin/swaylock"
|
|
||||||
+ (if cfg.wallpaper == "" then "" else " -i ${cfg.wallpaper} -s fill")
|
+ (if cfg.wallpaper == "" then "" else " -i ${cfg.wallpaper} -s fill")
|
||||||
+ " -l -k";
|
+ " -l -k";
|
||||||
};
|
};
|
||||||
|
enableLaptopBars = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
description = "Whether to enable laptop-specific bars (battery)";
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
enableMpd = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
description = "Whether to enable mpd on waybar";
|
||||||
|
default = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
config.systemd.user.targets.sway-session = mkIf cfg.enable {
|
waybar = {
|
||||||
Unit.Before = [
|
makeBars = mkOption {
|
||||||
"tray.target"
|
type = types.raw;
|
||||||
"xwayland.target"
|
description = "Create bars with the barWith function, return a list of bars";
|
||||||
"xdg-desktop-portal.service"
|
default = barWith: [ (barWith { }) ];
|
||||||
"xdg-desktop-autostart.target"
|
};
|
||||||
];
|
extraSettings = mkOption {
|
||||||
Unit.Upholds = [ "waybar.service" ];
|
type = types.raw;
|
||||||
Unit.Wants = [ "xdg-desktop-autostart.target" ];
|
description = "Extra settings to be included with every default bar";
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
extraStyle = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "Additional style for the default waybar";
|
||||||
|
default = "";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# Enable waybar
|
|
||||||
config.programs.my-waybar = mkIf cfg.enable {
|
|
||||||
enable = true;
|
|
||||||
fontSize = mkDefault cfg.fontSize;
|
|
||||||
enableLaptopBars = mkDefault cfg.enableLaptop;
|
|
||||||
};
|
};
|
||||||
config.systemd.user.services.swaync.Install.WantedBy = mkIf cfg.enable [ "sway-session.target" ];
|
|
||||||
|
|
||||||
config.wayland.windowManager.sway = mkIf cfg.enable {
|
config.wayland.windowManager.sway = mkIf cfg.enable {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = cfg.package;
|
systemdIntegration = true;
|
||||||
systemd.enable = true;
|
|
||||||
systemd.variables =
|
|
||||||
options.wayland.windowManager.sway.systemd.variables.default
|
|
||||||
++ [
|
|
||||||
"PATH" # for portals
|
|
||||||
"XDG_DATA_DIRS" # For extra icons
|
|
||||||
"XDG_DATA_HOME" # For extra icons
|
|
||||||
]
|
|
||||||
++ lib.optionals osConfig.services.desktopManager.plasma6.enable [
|
|
||||||
"XDG_MENU_PREFIX"
|
|
||||||
];
|
|
||||||
# systemd.extraCommands = options.wayland.windowManager.sway.systemd.extraCommands.default
|
|
||||||
# ++ [
|
|
||||||
# "systemctl --user restart xdg-desktop-portal.service"
|
|
||||||
# ];
|
|
||||||
|
|
||||||
checkConfig = false; # Not working atm
|
|
||||||
config = {
|
config = {
|
||||||
### Inputs
|
### Inputs
|
||||||
#
|
#
|
||||||
|
@ -158,30 +133,35 @@ in
|
||||||
### Seats
|
### Seats
|
||||||
#
|
#
|
||||||
# Cursor
|
# Cursor
|
||||||
seat."*".xcursor_theme =
|
seat."*".xcursor_theme = "${config.home.pointerCursor.name} ${toString config.home.pointerCursor.size}";
|
||||||
"${config.home.pointerCursor.name} ${toString config.home.pointerCursor.size}";
|
|
||||||
|
|
||||||
### Programs
|
### Programs
|
||||||
#
|
#
|
||||||
# Terminal
|
# Terminal
|
||||||
terminal = terminalCmd;
|
terminal = cfg.terminal;
|
||||||
menu = "${pkgs.dmenu}/bin/dmenu_path | ${pkgs.bemenu}/bin/bemenu | ${pkgs.findutils}/bin/xargs swaymsg exec --";
|
menu = "${pkgs.dmenu}/bin/dmenu_path | ${pkgs.bemenu}/bin/bemenu | ${pkgs.findutils}/bin/xargs swaymsg exec --";
|
||||||
# Startup
|
# Startup
|
||||||
startup = [
|
startup = [
|
||||||
# # Dex for autostart
|
# Dex for autostart
|
||||||
# { command = "${pkgs.dex}/bin/dex -ae sway"; }
|
{ command = "${pkgs.dex}/bin/dex -ae sway"; }
|
||||||
# # Waybar
|
# Waybar
|
||||||
# { command = "systemctl --user restart waybar"; always = true; }
|
{ command = "systemctl --user restart waybar"; always = true; }
|
||||||
# IME
|
# Startup programs
|
||||||
{ command = "fcitx5"; }
|
{ command = "${cfg.browser}"; }
|
||||||
];
|
{ command = "thunderbird"; } # Rely on system package with plugins
|
||||||
|
] ++ (if cfg.discord != null then [
|
||||||
|
{ command = "${cfg.discord}"; }
|
||||||
|
] ++ lib.lists.optional
|
||||||
|
(!pkgs.stdenv.isAarch64)
|
||||||
|
(
|
||||||
|
{ command = "${pkgs.premid}/bin/premid"; }
|
||||||
|
) else [ ]);
|
||||||
|
|
||||||
### Keybindings
|
### Keybindings
|
||||||
#
|
#
|
||||||
# Main modifier
|
# Main modifier
|
||||||
modifier = mod;
|
modifier = mod;
|
||||||
keybindings =
|
keybindings = {
|
||||||
{
|
|
||||||
### Default Bindings
|
### Default Bindings
|
||||||
#
|
#
|
||||||
## App management
|
## App management
|
||||||
|
@ -228,9 +208,7 @@ in
|
||||||
# Launcher
|
# Launcher
|
||||||
"${mod}+space" = "exec rofi -show drun";
|
"${mod}+space" = "exec rofi -show drun";
|
||||||
"${mod}+tab" = "exec ${./rofi-window.py}";
|
"${mod}+tab" = "exec ${./rofi-window.py}";
|
||||||
"${mod}+shift+p" = "exec rofi-rbw-script";
|
} // {
|
||||||
}
|
|
||||||
// {
|
|
||||||
## Splits
|
## Splits
|
||||||
"${mod}+v" = "split v";
|
"${mod}+v" = "split v";
|
||||||
"${mod}+Shift+v" = "split h";
|
"${mod}+Shift+v" = "split h";
|
||||||
|
@ -239,7 +217,6 @@ in
|
||||||
"${mod}+Shift+r" = "mode resize";
|
"${mod}+Shift+r" = "mode resize";
|
||||||
## Screenshot
|
## Screenshot
|
||||||
"Print" = "exec ${screenshotScript}/bin/screenshot";
|
"Print" = "exec ${screenshotScript}/bin/screenshot";
|
||||||
"Shift+Print" = "exec ${screenshotEditScript}/bin/screenshot";
|
|
||||||
## Locking
|
## Locking
|
||||||
"${mod}+semicolon" = "exec ${cfg.lockCmd}";
|
"${mod}+semicolon" = "exec ${cfg.lockCmd}";
|
||||||
## Multimedia
|
## Multimedia
|
||||||
|
@ -254,16 +231,12 @@ in
|
||||||
## Backlight
|
## Backlight
|
||||||
"XF86MonBrightnessDown" = "exec ${pkgs.brightnessctl}/bin/brightnessctl s 10%-";
|
"XF86MonBrightnessDown" = "exec ${pkgs.brightnessctl}/bin/brightnessctl s 10%-";
|
||||||
"XF86MonBrightnessUp" = "exec ${pkgs.brightnessctl}/bin/brightnessctl s 10%+";
|
"XF86MonBrightnessUp" = "exec ${pkgs.brightnessctl}/bin/brightnessctl s 10%+";
|
||||||
"Shift+XF86MonBrightnessDown" =
|
"Shift+XF86MonBrightnessDown" = "exec ${pkgs.brightnessctl}/bin/brightnessctl -d kbd_backlight s 25%-";
|
||||||
"exec ${pkgs.brightnessctl}/bin/brightnessctl -d kbd_backlight s 25%-";
|
"Shift+XF86MonBrightnessUp" = "exec ${pkgs.brightnessctl}/bin/brightnessctl -d kbd_backlight s 25%+";
|
||||||
"Shift+XF86MonBrightnessUp" =
|
} //
|
||||||
"exec ${pkgs.brightnessctl}/bin/brightnessctl -d kbd_backlight s 25%+";
|
|
||||||
}
|
|
||||||
//
|
|
||||||
# Map the workspaces
|
# Map the workspaces
|
||||||
(builtins.listToAttrs (
|
(builtins.listToAttrs (lib.flatten (map
|
||||||
lib.flatten (
|
(key: [
|
||||||
map (key: [
|
|
||||||
{
|
{
|
||||||
name = "${mod}+${key}";
|
name = "${mod}+${key}";
|
||||||
value = "workspace ${builtins.getAttr key wsAttrs}";
|
value = "workspace ${builtins.getAttr key wsAttrs}";
|
||||||
|
@ -272,15 +245,9 @@ in
|
||||||
name = "${mod}+Shift+${key}";
|
name = "${mod}+Shift+${key}";
|
||||||
value = "move to workspace ${builtins.getAttr key wsAttrs}";
|
value = "move to workspace ${builtins.getAttr key wsAttrs}";
|
||||||
}
|
}
|
||||||
]) (builtins.attrNames wsAttrs)
|
])
|
||||||
)
|
(builtins.attrNames wsAttrs))
|
||||||
))
|
)) //
|
||||||
// {
|
|
||||||
# Extra workspaces
|
|
||||||
"${mod}+asciicircum" = "workspace ${extraWorkspaces.mail}";
|
|
||||||
"${mod}+shift+asciicircum" = "move to workspace ${extraWorkspaces.mail}";
|
|
||||||
}
|
|
||||||
//
|
|
||||||
# Move workspaces between outputs
|
# Move workspaces between outputs
|
||||||
{
|
{
|
||||||
"${mod}+ctrl+h" = "move workspace to output left";
|
"${mod}+ctrl+h" = "move workspace to output left";
|
||||||
|
@ -290,10 +257,7 @@ in
|
||||||
### Fonts
|
### Fonts
|
||||||
#
|
#
|
||||||
fonts = {
|
fonts = {
|
||||||
names = [
|
names = [ "monospace" "FontAwesome5Free" ];
|
||||||
"monospace"
|
|
||||||
"FontAwesome5Free"
|
|
||||||
];
|
|
||||||
size = cfg.fontSize;
|
size = cfg.fontSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -311,50 +275,21 @@ in
|
||||||
# Assigning windows to workspaces
|
# Assigning windows to workspaces
|
||||||
assigns = {
|
assigns = {
|
||||||
"${builtins.elemAt workspaces 0}" = [
|
"${builtins.elemAt workspaces 0}" = [
|
||||||
{ app_id = "^firefox$"; }
|
{ class = "^firefox$"; }
|
||||||
{ app_id = "^librewolf$"; }
|
|
||||||
{ app_id = "^zen$"; }
|
|
||||||
];
|
];
|
||||||
"${builtins.elemAt workspaces 1}" = [
|
"${builtins.elemAt workspaces 1}" = [
|
||||||
{ class = "^((d|D)iscord|((A|a)rm(c|C)ord))$"; }
|
{ class = "^((d|D)iscord|((A|a)rm(c|C)ord))$"; }
|
||||||
{ class = "VencordDesktop"; }
|
|
||||||
{ app_id = "VencordDesktop"; }
|
|
||||||
{ class = "vesktop"; }
|
|
||||||
{ app_id = "vesktop"; }
|
|
||||||
|
|
||||||
{ class = "Slack"; }
|
|
||||||
];
|
];
|
||||||
${extraWorkspaces.mail} = [
|
"📧 Email" = [
|
||||||
{ app_id = "thunderbird"; }
|
{ app_id = "thunderbird"; }
|
||||||
{ app_id = "evolution"; }
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
# Commands
|
# Commands
|
||||||
window.commands =
|
window.commands = [
|
||||||
[
|
{ criteria = { title = ".*"; }; command = "inhibit_idle fullscreen"; }
|
||||||
{
|
{ criteria = { app_id = ".*float.*"; }; command = "floating enable"; }
|
||||||
criteria = {
|
{ criteria = { class = ".*float.*"; }; command = "floating enable"; }
|
||||||
title = ".*";
|
|
||||||
};
|
|
||||||
command = "inhibit_idle fullscreen";
|
|
||||||
}
|
|
||||||
]
|
|
||||||
++ (
|
|
||||||
# Floating assignments
|
|
||||||
let
|
|
||||||
criterias = [
|
|
||||||
{ app_id = ".*float.*"; }
|
|
||||||
{ app_id = "org\\.freedesktop\\.impl\\.portal\\.desktop\\..*"; }
|
|
||||||
{ class = ".*float.*"; }
|
|
||||||
{ title = "Extension: .*Bitwarden.*"; }
|
|
||||||
];
|
];
|
||||||
toCommand = criteria: {
|
|
||||||
inherit criteria;
|
|
||||||
command = "floating enable";
|
|
||||||
};
|
|
||||||
in
|
|
||||||
map toCommand criterias
|
|
||||||
);
|
|
||||||
# Focus
|
# Focus
|
||||||
focus.followMouse = true;
|
focus.followMouse = true;
|
||||||
focus.mouseWarping = true;
|
focus.mouseWarping = true;
|
||||||
|
@ -363,7 +298,7 @@ in
|
||||||
gaps.outer = 4;
|
gaps.outer = 4;
|
||||||
gaps.inner = 4;
|
gaps.inner = 4;
|
||||||
gaps.smartBorders = "on";
|
gaps.smartBorders = "on";
|
||||||
gaps.smartGaps = false;
|
gaps.smartGaps = true;
|
||||||
|
|
||||||
### Bars
|
### Bars
|
||||||
# Let systemd manage it
|
# Let systemd manage it
|
||||||
|
@ -376,38 +311,23 @@ in
|
||||||
# swaynag
|
# swaynag
|
||||||
swaynag.enable = true;
|
swaynag.enable = true;
|
||||||
# Environment Variables
|
# Environment Variables
|
||||||
extraSessionCommands =
|
extraSessionCommands = ''
|
||||||
''
|
export MOZ_ENABLE_WAYLAND=1
|
||||||
|
export SDL_VIDEODRIVER=wayland
|
||||||
export QT_QPA_PLATFORM=wayland
|
export QT_QPA_PLATFORM=wayland
|
||||||
export QT_WAYLAND_DISABLE_WINDOWDECORATION="1"
|
export QT_WAYLAND_DISABLE_WINDOWDECORATION="1"
|
||||||
export QT_IM_MODULE=fcitx
|
|
||||||
export GTK_IM_MODULE=fcitx # Til text-input is merged
|
|
||||||
# export NIXOS_OZONE_WL=1 # Until text-input is merged
|
|
||||||
|
|
||||||
''
|
'' + (if config.services.gnome-keyring.enable then ''
|
||||||
+ (
|
|
||||||
if config.services.gnome-keyring.enable then
|
|
||||||
''
|
|
||||||
# gnome-keyring
|
# gnome-keyring
|
||||||
if type gnome-keyring-daemon >/dev/null; then
|
|
||||||
eval `gnome-keyring-daemon`
|
eval `gnome-keyring-daemon`
|
||||||
export SSH_AUTH_SOCK
|
export SSH_AUTH_SOCK
|
||||||
fi
|
'' else "");
|
||||||
''
|
|
||||||
else
|
|
||||||
""
|
|
||||||
)
|
|
||||||
+ lib.optionalString osConfig.services.desktopManager.plasma6.enable ''
|
|
||||||
export XDG_MENU_PREFIX=plasma-
|
|
||||||
'';
|
|
||||||
# Extra
|
# Extra
|
||||||
wrapperFeatures.base = true;
|
wrapperFeatures.base = true;
|
||||||
wrapperFeatures.gtk = true;
|
wrapperFeatures.gtk = true;
|
||||||
|
|
||||||
extraConfig =
|
extraConfig =
|
||||||
(
|
(if cfg.enableLaptopBars then ''
|
||||||
if cfg.enableLaptop then
|
|
||||||
''
|
|
||||||
# Lock screen on lid close
|
# Lock screen on lid close
|
||||||
bindswitch lid:off exec ${cfg.lockCmd}
|
bindswitch lid:off exec ${cfg.lockCmd}
|
||||||
|
|
||||||
|
@ -415,11 +335,7 @@ in
|
||||||
bindgesture swipe:3:right workspace prev
|
bindgesture swipe:3:right workspace prev
|
||||||
bindgesture swipe:3:left workspace next
|
bindgesture swipe:3:left workspace next
|
||||||
bindgesture swipe:3:up exec ${./rofi-window.py}
|
bindgesture swipe:3:up exec ${./rofi-window.py}
|
||||||
''
|
'' else "") + ''
|
||||||
else
|
|
||||||
""
|
|
||||||
)
|
|
||||||
+ ''
|
|
||||||
## swayfx stuff
|
## swayfx stuff
|
||||||
# Rounded corners
|
# Rounded corners
|
||||||
corner_radius 5
|
corner_radius 5
|
||||||
|
@ -434,43 +350,368 @@ in
|
||||||
# Blur
|
# Blur
|
||||||
for_window [app_id=".*kitty.*"] blur enable
|
for_window [app_id=".*kitty.*"] blur enable
|
||||||
blur_xray disable
|
blur_xray disable
|
||||||
''
|
'' + ''
|
||||||
+ ''
|
|
||||||
# Enable portal stuff
|
# Enable portal stuff
|
||||||
exec ${pkgs.writeShellScript "start-portals.sh" ''''}
|
exec ${pkgs.writeShellScript "start-portals.sh" ''
|
||||||
|
# Import the WAYLAND_DISPLAY env var from sway into the systemd user session.
|
||||||
|
dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=sway
|
||||||
|
|
||||||
|
# Stop any services that are running, so that they receive the new env var when they restart.
|
||||||
|
systemctl --user stop pipewire pipewire-media-session xdg-desktop-portal xdg-desktop-portal-wlr
|
||||||
|
systemctl --user start pipewire-media-session
|
||||||
|
''}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
config.services.swayidle = mkIf cfg.enable {
|
config.services.swayidle = mkIf cfg.enable {
|
||||||
enable = true;
|
enable = true;
|
||||||
systemdTarget = "sway-session.target";
|
|
||||||
timeouts = [
|
timeouts = [
|
||||||
# Lock after 15 minutes of idle
|
# Lock after 15 minutes of idle
|
||||||
# { timeout = 15 * 60; command = cfg.lockCmd; }
|
{ timeout = 15 * 60; command = cfg.lockCmd; }
|
||||||
];
|
|
||||||
events = [
|
|
||||||
{
|
|
||||||
event = "lock";
|
|
||||||
command = cfg.lockCmd;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
event = "before-sleep";
|
|
||||||
command = cfg.lockCmd;
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
config.home.packages = mkIf cfg.enable (
|
config.programs.waybar =
|
||||||
with pkgs;
|
let
|
||||||
[
|
barWith = { showMedia ? true, showConnectivity ? true, extraSettings ? { }, ... }: (mkMerge [{
|
||||||
|
position = "top";
|
||||||
|
modules-left = [
|
||||||
|
"sway/workspaces"
|
||||||
|
"sway/mode"
|
||||||
|
"sway/window"
|
||||||
|
];
|
||||||
|
modules-center = [
|
||||||
|
];
|
||||||
|
modules-right =
|
||||||
|
lib.optional showMedia (if cfg.enableMpd then "mpd" else "custom/media")
|
||||||
|
++ [
|
||||||
|
"tray"
|
||||||
|
"pulseaudio"
|
||||||
|
] ++ lib.optionals showConnectivity [
|
||||||
|
"bluetooth"
|
||||||
|
"network"
|
||||||
|
] ++ [
|
||||||
|
"cpu"
|
||||||
|
"memory"
|
||||||
|
"temperature"
|
||||||
|
] ++ lib.optionals cfg.enableLaptopBars [ "battery" "battery#bat2" ]
|
||||||
|
++ [
|
||||||
|
"clock"
|
||||||
|
];
|
||||||
|
|
||||||
|
modules = {
|
||||||
|
"sway/workspaces" = {
|
||||||
|
format = "{name}";
|
||||||
|
};
|
||||||
|
"sway/mode" = {
|
||||||
|
format = "<span style=\"italic\">{}</span>";
|
||||||
|
};
|
||||||
|
"sway/window" = {
|
||||||
|
max-length = 70;
|
||||||
|
format = "{title}";
|
||||||
|
"rewrite" = {
|
||||||
|
"(.*) — Mozilla Firefox" = "[🌎] $1";
|
||||||
|
"(.*) - Mozilla Thunderbird" = "[📧] $1";
|
||||||
|
"(.*) - Kakoune" = "[⌨️] $1";
|
||||||
|
"(.*) - fish" = "[>_] $1";
|
||||||
|
"(.*) - Discord" = "[🗨️] $1";
|
||||||
|
# ArmCord thing
|
||||||
|
"• Discord \\| (.*)" = "[🗨️] $1";
|
||||||
|
"\\((\\d+)\\) Discord \\| (.*)" = "[🗨️] {$1} $2";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
"tray" = {
|
||||||
|
icon-size = 21;
|
||||||
|
spacing = 10;
|
||||||
|
};
|
||||||
|
"clock" = {
|
||||||
|
tooltip-format = "{:%Y-%m-%d | %H:%M}";
|
||||||
|
format-alt = "{:%Y-%m-%d}";
|
||||||
|
};
|
||||||
|
"cpu" = {
|
||||||
|
format = "{usage}% ";
|
||||||
|
};
|
||||||
|
"memory" = {
|
||||||
|
format = "{}% ";
|
||||||
|
};
|
||||||
|
"temperature" = {
|
||||||
|
# thermal-zone = 2;
|
||||||
|
# hwmon-path" = "/sys/class/hwmon/hwmon2/temp1_input";
|
||||||
|
critical-threshold = 80;
|
||||||
|
# format-critical = "{temperatureC}°C ";
|
||||||
|
format = "{temperatureC}°C ";
|
||||||
|
};
|
||||||
|
"backlight" = {
|
||||||
|
# device = "acpi_video1";
|
||||||
|
format = "{percent}% {icon}";
|
||||||
|
states = [ 0 50 ];
|
||||||
|
format-icons = [ "" "" ];
|
||||||
|
};
|
||||||
|
"battery" = mkIf cfg.enableLaptopBars {
|
||||||
|
states = {
|
||||||
|
good = 95;
|
||||||
|
warning = 30;
|
||||||
|
critical = 15;
|
||||||
|
};
|
||||||
|
format = "{capacity}% {icon}";
|
||||||
|
# format-good = ""; # An empty format will hide the module
|
||||||
|
# format-full = "";
|
||||||
|
format-icons = [ "" "" "" "" "" ];
|
||||||
|
};
|
||||||
|
"battery#bat2" = mkIf cfg.enableLaptopBars {
|
||||||
|
bat = "BAT2";
|
||||||
|
};
|
||||||
|
"network" = {
|
||||||
|
# interface = wlp2s0 # (Optional) To force the use of this interface
|
||||||
|
format-wifi = "{essid} ({signalStrength}%) ";
|
||||||
|
format-ethernet = "{ifname}: {ipaddr}/{cidr} ";
|
||||||
|
format-disconnected = "Disconnected ⚠";
|
||||||
|
interval = 7;
|
||||||
|
};
|
||||||
|
"bluetooth" = {
|
||||||
|
format = " {status}";
|
||||||
|
format-connected = " {device_alias}";
|
||||||
|
format-connected-battery = " {device_alias} {device_battery_percentage}%";
|
||||||
|
# format-device-preference= [ "device1", "device2" ], // preference list deciding the displayed devic;
|
||||||
|
tooltip-format = "{controller_alias}\t{controller_address}\n\n{num_connections} connected";
|
||||||
|
tooltip-format-connected = "{controller_alias}\t{controller_address}\n\n{num_connections} connected\n\n{device_enumerate}";
|
||||||
|
tooltip-format-enumerate-connected = "{device_alias}\t{device_address}";
|
||||||
|
tooltip-format-enumerate-connected-battery = "{device_alias}\t{device_address}\t{device_battery_percentage}%";
|
||||||
|
on-click = "${pkgs.blueman}/bin/blueman-manager";
|
||||||
|
};
|
||||||
|
"pulseaudio" = {
|
||||||
|
# scroll-step = 1;
|
||||||
|
format = "{volume}% {icon}";
|
||||||
|
format-bluetooth = "{volume}% {icon}";
|
||||||
|
format-muted = "";
|
||||||
|
format-icons = {
|
||||||
|
headphones = "";
|
||||||
|
handsfree = "";
|
||||||
|
headset = "";
|
||||||
|
phone = "";
|
||||||
|
portable = "";
|
||||||
|
car = "";
|
||||||
|
default = [ "" "" ];
|
||||||
|
};
|
||||||
|
on-click = "${pkgs.pavucontrol}/bin/pavucontrol";
|
||||||
|
};
|
||||||
|
"mpd" = {
|
||||||
|
"format" = "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist} - {album} - {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S}) 🎧";
|
||||||
|
"format-disconnected" = "Disconnected 🎧";
|
||||||
|
"format-stopped" = "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped 🎧";
|
||||||
|
"interval" = 2;
|
||||||
|
"consume-icons" = {
|
||||||
|
"on" = " "; # Icon shows only when "consume" is on
|
||||||
|
};
|
||||||
|
"random-icons" = {
|
||||||
|
"off" = "<span color=\"#f53c3c\"></span> "; # Icon grayed out when "random" is off;
|
||||||
|
"on" = " ";
|
||||||
|
};
|
||||||
|
"repeat-icons" = {
|
||||||
|
"on" = " ";
|
||||||
|
};
|
||||||
|
"single-icons" = {
|
||||||
|
"on" = "1 ";
|
||||||
|
};
|
||||||
|
"state-icons" = {
|
||||||
|
"paused" = "";
|
||||||
|
"playing" = "";
|
||||||
|
};
|
||||||
|
"tooltip-format" = "MPD (connected)";
|
||||||
|
"tooltip-format-disconnected" = "MPD (disconnected)";
|
||||||
|
"on-click" = "${pkgs.mpc_cli}/bin/mpc toggle";
|
||||||
|
"on-click-right" = "${pkgs.mpc_cli}/bin/mpc stop";
|
||||||
|
"on-click-middle" = "${cfg.terminal} --class=kitty_ncmpcpp ${pkgs.ncmpcpp}/bin/ncmpcpp";
|
||||||
|
};
|
||||||
|
"custom/media" = {
|
||||||
|
"format" = "{icon}{}";
|
||||||
|
"return-type" = "json";
|
||||||
|
"format-icons" = {
|
||||||
|
"Playing" = " ";
|
||||||
|
"Paused" = " ";
|
||||||
|
};
|
||||||
|
"max-length" = 80;
|
||||||
|
"exec" = "${playerctl} -a metadata --format '{\"text\": \"{{artist}} - {{markup_escape(title)}}\", \"tooltip\": \"{{playerName}} : {{markup_escape(title)}}\", \"alt\": \"{{status}}\", \"class\": \"{{status}}\"}' -F";
|
||||||
|
"on-click" = "${playerctl} play-pause";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
cfg.waybar.extraSettings
|
||||||
|
extraSettings]);
|
||||||
|
in
|
||||||
|
mkIf cfg.enable {
|
||||||
|
enable = true;
|
||||||
|
systemd.enable = true;
|
||||||
|
settings = cfg.waybar.makeBars barWith;
|
||||||
|
style = ''
|
||||||
|
* {
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
font-family: monospace, 'Font Awesome 5', 'Symbols Nerd Font Mono', 'SFNS Display', Helvetica, Arial, sans-serif;
|
||||||
|
font-size: ${toString (cfg.fontSize * 1.1)}px;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
window#waybar {
|
||||||
|
background: rgba(43, 48, 59, 0.8);
|
||||||
|
border-bottom: 3px solid rgba(100, 114, 125, 0.5);
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
window#waybar.hidden {
|
||||||
|
opacity: 0.0;
|
||||||
|
}
|
||||||
|
/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */
|
||||||
|
#workspaces button {
|
||||||
|
padding: 0 5px;
|
||||||
|
background: transparent;
|
||||||
|
color: #ffffff;
|
||||||
|
border-bottom: 3px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#workspaces button.focused {
|
||||||
|
background: #64727D;
|
||||||
|
border-bottom: 3px solid #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#workspaces button.urgent {
|
||||||
|
background-color: #eb4d4b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#window, #sway, #sway-window {
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mode {
|
||||||
|
background: #64727D;
|
||||||
|
border-bottom: 3px solid #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#clock, #battery, #cpu, #memory, #temperature, #backlight, #network, #pulseaudio, #bluetooth, #custom-media, #tray, #mode, #idle_inhibitor, #mpd {
|
||||||
|
padding: 0 10px;
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#clock {
|
||||||
|
background-color: #64727D;
|
||||||
|
}
|
||||||
|
|
||||||
|
#battery {
|
||||||
|
background-color: #ffffff;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#battery.charging {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #26A65B;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes blink {
|
||||||
|
to {
|
||||||
|
background-color: #ffffff;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#battery.critical:not(.charging) {
|
||||||
|
background: #f53c3c;
|
||||||
|
color: #ffffff;
|
||||||
|
animation-name: blink;
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-direction: alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cpu {
|
||||||
|
background: #2ecc71;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#memory {
|
||||||
|
background: #9b59b6;
|
||||||
|
}
|
||||||
|
|
||||||
|
#backlight {
|
||||||
|
background: #90b1b1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#network {
|
||||||
|
background: #2980b9;
|
||||||
|
}
|
||||||
|
|
||||||
|
#network.disconnected {
|
||||||
|
background: #f53c3c;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pulseaudio {
|
||||||
|
background: #f1c40f;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pulseaudio.muted {
|
||||||
|
background: #90b1b1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bluetooth {
|
||||||
|
background: DarkSlateBlue;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#custom-media {
|
||||||
|
background: #66cc99;
|
||||||
|
color: #2a5c45;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-spotify {
|
||||||
|
background: #66cc99;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-vlc {
|
||||||
|
background: #ffa000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#temperature {
|
||||||
|
background: #f0932b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#temperature.critical {
|
||||||
|
background: #eb4d4b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tray {
|
||||||
|
background-color: #2980b9;
|
||||||
|
}
|
||||||
|
|
||||||
|
#idle_inhibitor {
|
||||||
|
background-color: #2d3436;
|
||||||
|
}
|
||||||
|
|
||||||
|
#idle_inhibitor.activated {
|
||||||
|
background-color: #ecf0f1;
|
||||||
|
color: #2d3436;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mpd {
|
||||||
|
background-color: teal;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
'' + cfg.waybar.extraStyle;
|
||||||
|
};
|
||||||
|
config.home.packages = mkIf cfg.enable (with pkgs; [
|
||||||
# Needed for QT_QPA_PLATFORM
|
# Needed for QT_QPA_PLATFORM
|
||||||
kdePackages.qtwayland
|
qt5.qtwayland
|
||||||
# For waybar
|
# For waybar
|
||||||
font-awesome
|
font-awesome
|
||||||
]
|
]);
|
||||||
);
|
|
||||||
|
|
||||||
config.programs.rofi = mkIf cfg.enable {
|
config.programs.rofi = mkIf cfg.enable {
|
||||||
font = lib.mkForce "monospace ${toString cfg.fontSize}";
|
enable = true;
|
||||||
|
package = pkgs.rofi-wayland;
|
||||||
|
cycle = true;
|
||||||
|
font = "monospace ${toString cfg.fontSize}";
|
||||||
|
terminal = cfg.terminal;
|
||||||
|
theme = "Paper";
|
||||||
|
plugins = with pkgs; [ rofi-bluetooth rofi-calc rofi-rbw rofi-power-menu ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.programs.my-sway;
|
cfg = config.programs.my-sway;
|
||||||
|
@ -11,22 +6,15 @@ let
|
||||||
# Set up an ibus script
|
# Set up an ibus script
|
||||||
ibusNext = (
|
ibusNext = (
|
||||||
let
|
let
|
||||||
input-methods = [
|
input-methods = [ "xkb:us::eng" "mozc-jp" "Bamboo" ];
|
||||||
"xkb:us::eng"
|
next = m:
|
||||||
"mozc-jp"
|
|
||||||
"Bamboo"
|
|
||||||
];
|
|
||||||
next =
|
|
||||||
m:
|
|
||||||
let
|
let
|
||||||
nextRec =
|
nextRec = l:
|
||||||
l:
|
if (length l == 1)
|
||||||
if (length l == 1) then
|
then head input-methods
|
||||||
head input-methods
|
else if (m == head l)
|
||||||
else if (m == head l) then
|
then (head (tail l))
|
||||||
(head (tail l))
|
else nextRec (tail l);
|
||||||
else
|
|
||||||
nextRec (tail l);
|
|
||||||
in
|
in
|
||||||
nextRec input-methods;
|
nextRec input-methods;
|
||||||
changeTo = m: ''
|
changeTo = m: ''
|
||||||
|
@ -64,3 +52,4 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,469 +0,0 @@
|
||||||
{
|
|
||||||
lib,
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.programs.my-waybar;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.programs.my-waybar = {
|
|
||||||
enable = lib.mkEnableOption "custom configuration for waybar";
|
|
||||||
fontSize = lib.mkOption {
|
|
||||||
type = lib.types.float;
|
|
||||||
description = "The default font size";
|
|
||||||
};
|
|
||||||
terminal = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = "The command to the terminal emulator to be used";
|
|
||||||
default = "${lib.getExe config.linux.graphical.defaults.terminal.package}";
|
|
||||||
};
|
|
||||||
|
|
||||||
enableLaptopBars = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
description = "Whether to enable laptop-specific bars (battery)";
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
enableMpd = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
description = "Whether to enable mpd on waybar";
|
|
||||||
default = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
makeBars = lib.mkOption {
|
|
||||||
type = lib.types.raw;
|
|
||||||
description = "Create bars with the barWith function, return a list of bars";
|
|
||||||
default = barWith: [ (barWith { }) ];
|
|
||||||
};
|
|
||||||
extraSettings = lib.mkOption {
|
|
||||||
type = lib.types.listOf lib.types.raw;
|
|
||||||
description = "Extra settings to be included with every default bar";
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
extraStyle = lib.mkOption {
|
|
||||||
type = lib.types.lines;
|
|
||||||
description = "Additional style for the default waybar";
|
|
||||||
default = "";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
config.systemd.user.services.waybar = lib.mkIf cfg.enable {
|
|
||||||
Unit.Before = [ "tray.target" ];
|
|
||||||
};
|
|
||||||
config.programs.waybar =
|
|
||||||
let
|
|
||||||
barWith =
|
|
||||||
{
|
|
||||||
showMedia ? true,
|
|
||||||
showConnectivity ? true,
|
|
||||||
extraSettings ? { },
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
lib.mkMerge (
|
|
||||||
[
|
|
||||||
{
|
|
||||||
layer = "top";
|
|
||||||
position = "top";
|
|
||||||
modules-left = [
|
|
||||||
"sway/workspaces"
|
|
||||||
"sway/mode"
|
|
||||||
"sway/window"
|
|
||||||
"niri/workspaces"
|
|
||||||
"niri/window"
|
|
||||||
];
|
|
||||||
modules-center = [
|
|
||||||
];
|
|
||||||
modules-right =
|
|
||||||
lib.optional showMedia (if cfg.enableMpd then "mpd" else "custom/media")
|
|
||||||
++ [
|
|
||||||
"tray"
|
|
||||||
"pulseaudio"
|
|
||||||
]
|
|
||||||
++ lib.optionals showConnectivity [
|
|
||||||
"bluetooth"
|
|
||||||
"network"
|
|
||||||
]
|
|
||||||
++ [
|
|
||||||
"cpu"
|
|
||||||
"memory"
|
|
||||||
"temperature"
|
|
||||||
]
|
|
||||||
++ lib.optionals cfg.enableLaptopBars [
|
|
||||||
"battery"
|
|
||||||
"battery#bat2"
|
|
||||||
]
|
|
||||||
++ [
|
|
||||||
"clock"
|
|
||||||
];
|
|
||||||
|
|
||||||
modules = {
|
|
||||||
"sway/workspaces" = {
|
|
||||||
format = "{name}";
|
|
||||||
};
|
|
||||||
"sway/mode" = {
|
|
||||||
format = "<span style=\"italic\">{}</span>";
|
|
||||||
};
|
|
||||||
"sway/window" = {
|
|
||||||
max-length = 70;
|
|
||||||
format = "{title}";
|
|
||||||
"rewrite" = {
|
|
||||||
"(.*) — Mozilla Firefox" = "[🌎] $1";
|
|
||||||
"(.*) - Mozilla Thunderbird" = "[📧] $1";
|
|
||||||
"(.*) - Kakoune" = "[⌨️] $1";
|
|
||||||
"(.*) - fish" = "[>_] $1";
|
|
||||||
"(.*) - Discord" = "[🗨️] $1";
|
|
||||||
# ArmCord thing
|
|
||||||
"• Discord \\| (.*)" = "[🗨️] $1";
|
|
||||||
"\\((\\d+)\\) Discord \\| (.*)" = "[🗨️] {$1} $2";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
"niri/window" = {
|
|
||||||
format = "{title}";
|
|
||||||
"rewrite" = {
|
|
||||||
"(.*) — Mozilla Firefox" = "[🌎] $1";
|
|
||||||
"(.*) - Mozilla Thunderbird" = "[📧] $1";
|
|
||||||
"(.*) - Kakoune" = "[⌨️] $1";
|
|
||||||
"(.*) - fish" = "[>_] $1";
|
|
||||||
"(.*) - Discord" = "[🗨️] $1";
|
|
||||||
# ArmCord thing
|
|
||||||
"• Discord \\| (.*)" = "[🗨️] $1";
|
|
||||||
"\\((\\d+)\\) Discord \\| (.*)" = "[🗨️] {$1} $2";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
"tray" = {
|
|
||||||
icon-size = 21;
|
|
||||||
spacing = 10;
|
|
||||||
};
|
|
||||||
"clock" = {
|
|
||||||
# format = "{:📅 %Y-%m-%d | 🕰️ %H:%M [%Z]}";
|
|
||||||
format = "📅 {0:%Y-%m-%d} |️ 🕰️ {0:%H:%M [%Z]}";
|
|
||||||
tooltip-format = "\n<span size='9pt' font_family='Noto Sans Mono CJK JP'>{calendar}</span>";
|
|
||||||
timezones = [
|
|
||||||
"Europe/Zurich"
|
|
||||||
"America/Toronto"
|
|
||||||
"Asia/Tokyo"
|
|
||||||
"Asia/Ho_Chi_Minh"
|
|
||||||
];
|
|
||||||
calendar = {
|
|
||||||
mode = "year";
|
|
||||||
mode-mon-col = 3;
|
|
||||||
weeks-pos = "right";
|
|
||||||
on-scroll = 1;
|
|
||||||
on-click-right = "mode";
|
|
||||||
format = {
|
|
||||||
months = "<span color='#ffead3'><b>{}</b></span>";
|
|
||||||
days = "<span color='#ecc6d9'><b>{}</b></span>";
|
|
||||||
weeks = "<span color='#99ffdd'><b>W{}</b></span>";
|
|
||||||
weekdays = "<span color='#ffcc66'><b>日 月 火 水 木 金 土</b></span>"; # See https://github.com/Alexays/Waybar/issues/3132
|
|
||||||
today = "<span color='#ff6699'><b><u>{}</u></b></span>";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
actions = {
|
|
||||||
on-click-middle = "mode";
|
|
||||||
on-click-right = "tz_up";
|
|
||||||
on-scroll-up = "shift_up";
|
|
||||||
on-scroll-down = "shift_down";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
"cpu" = {
|
|
||||||
format = "{usage}% ";
|
|
||||||
};
|
|
||||||
"memory" = {
|
|
||||||
format = "{}% ";
|
|
||||||
};
|
|
||||||
"temperature" = {
|
|
||||||
# thermal-zone = 2;
|
|
||||||
# hwmon-path" = "/sys/class/hwmon/hwmon2/temp1_input";
|
|
||||||
critical-threshold = 80;
|
|
||||||
# format-critical = "{temperatureC}°C ";
|
|
||||||
format = "{temperatureC}°C ";
|
|
||||||
};
|
|
||||||
"backlight" = {
|
|
||||||
# device = "acpi_video1";
|
|
||||||
format = "{percent}% {icon}";
|
|
||||||
states = [
|
|
||||||
0
|
|
||||||
50
|
|
||||||
];
|
|
||||||
format-icons = [
|
|
||||||
""
|
|
||||||
""
|
|
||||||
];
|
|
||||||
};
|
|
||||||
"battery" = lib.mkIf cfg.enableLaptopBars {
|
|
||||||
states = {
|
|
||||||
good = 95;
|
|
||||||
warning = 30;
|
|
||||||
critical = 15;
|
|
||||||
};
|
|
||||||
format = "{capacity}% {icon}";
|
|
||||||
# format-good = ""; # An empty format will hide the module
|
|
||||||
# format-full = "";
|
|
||||||
format-icons = [
|
|
||||||
""
|
|
||||||
""
|
|
||||||
""
|
|
||||||
""
|
|
||||||
""
|
|
||||||
];
|
|
||||||
};
|
|
||||||
"battery#bat2" = lib.mkIf cfg.enableLaptopBars {
|
|
||||||
bat = "BAT2";
|
|
||||||
};
|
|
||||||
"network" = {
|
|
||||||
# interface = wlp2s0 # (Optional) To force the use of this interface
|
|
||||||
format-wifi = "{essid} ({signalStrength}%) ";
|
|
||||||
format-ethernet = "{ifname} ";
|
|
||||||
format-disconnected = "Disconnected ⚠";
|
|
||||||
interval = 7;
|
|
||||||
on-click = "${cfg.terminal} ${lib.getExe' pkgs.iwd "iwctl"}";
|
|
||||||
};
|
|
||||||
"bluetooth" = {
|
|
||||||
format = " {status}";
|
|
||||||
format-connected = " {device_alias}";
|
|
||||||
format-connected-battery = " {device_alias} {device_battery_percentage}%";
|
|
||||||
# format-device-preference= [ "device1", "device2" ], // preference list deciding the displayed devic;
|
|
||||||
tooltip-format = "{controller_alias}\t{controller_address}\n\n{num_connections} connected";
|
|
||||||
tooltip-format-connected = "{controller_alias}\t{controller_address}\n\n{num_connections} connected\n\n{device_enumerate}";
|
|
||||||
tooltip-format-enumerate-connected = "{device_alias}\t{device_address}";
|
|
||||||
tooltip-format-enumerate-connected-battery = "{device_alias}\t{device_address}\t{device_battery_percentage}%";
|
|
||||||
on-click = "${pkgs.blueman}/bin/blueman-manager";
|
|
||||||
};
|
|
||||||
"pulseaudio" = {
|
|
||||||
# scroll-step = 1;
|
|
||||||
format = "{volume}% {icon}";
|
|
||||||
format-bluetooth = "{volume}% {icon}";
|
|
||||||
format-muted = "";
|
|
||||||
format-icons = {
|
|
||||||
headphones = "";
|
|
||||||
handsfree = "";
|
|
||||||
headset = "";
|
|
||||||
phone = "";
|
|
||||||
portable = "";
|
|
||||||
car = "";
|
|
||||||
default = [
|
|
||||||
""
|
|
||||||
""
|
|
||||||
];
|
|
||||||
};
|
|
||||||
on-click = "${pkgs.pavucontrol}/bin/pavucontrol";
|
|
||||||
};
|
|
||||||
"mpd" = {
|
|
||||||
"format" =
|
|
||||||
"{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist} - {album} - {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S}) 🎧";
|
|
||||||
"format-disconnected" = "Disconnected 🎧";
|
|
||||||
"format-stopped" = "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped 🎧";
|
|
||||||
"interval" = 2;
|
|
||||||
"consume-icons" = {
|
|
||||||
"on" = " "; # Icon shows only when "consume" is on
|
|
||||||
};
|
|
||||||
"random-icons" = {
|
|
||||||
"off" = "<span color=\"#f53c3c\"></span> "; # Icon grayed out when "random" is off;
|
|
||||||
"on" = " ";
|
|
||||||
};
|
|
||||||
"repeat-icons" = {
|
|
||||||
"on" = " ";
|
|
||||||
};
|
|
||||||
"single-icons" = {
|
|
||||||
"on" = "1 ";
|
|
||||||
};
|
|
||||||
"state-icons" = {
|
|
||||||
"paused" = "";
|
|
||||||
"playing" = "";
|
|
||||||
};
|
|
||||||
"tooltip-format" = "MPD (connected)";
|
|
||||||
"tooltip-format-disconnected" = "MPD (disconnected)";
|
|
||||||
"on-click" = "${pkgs.mpc_cli}/bin/mpc toggle";
|
|
||||||
"on-click-right" = "${pkgs.mpc_cli}/bin/mpc stop";
|
|
||||||
"on-click-middle" = "${cfg.terminal} --class=kitty_ncmpcpp ${pkgs.ncmpcpp}/bin/ncmpcpp";
|
|
||||||
};
|
|
||||||
"custom/media" = {
|
|
||||||
"format" = "{icon}{}";
|
|
||||||
"return-type" = "json";
|
|
||||||
"format-icons" = {
|
|
||||||
"Playing" = " ";
|
|
||||||
"Paused" = " ";
|
|
||||||
};
|
|
||||||
"max-length" = 80;
|
|
||||||
"exec" =
|
|
||||||
"${lib.getExe pkgs.playerctl} -a metadata --format '{\"text\": \"{{artist}} - {{markup_escape(title)}}\", \"tooltip\": \"{{playerName}} : {{markup_escape(title)}}\", \"alt\": \"{{status}}\", \"class\": \"{{status}}\"}' -F";
|
|
||||||
"on-click" = "${lib.getExe pkgs.playerctl} play-pause";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
]
|
|
||||||
++ cfg.extraSettings
|
|
||||||
++ [ extraSettings ]
|
|
||||||
);
|
|
||||||
in
|
|
||||||
lib.mkIf cfg.enable {
|
|
||||||
enable = true;
|
|
||||||
systemd.enable = true;
|
|
||||||
systemd.target = "sway-session.target";
|
|
||||||
settings = cfg.makeBars barWith;
|
|
||||||
style =
|
|
||||||
''
|
|
||||||
* {
|
|
||||||
border: none;
|
|
||||||
border-radius: 0;
|
|
||||||
font-family: monospace, 'Font Awesome 5', 'Symbols Nerd Font Mono', 'SFNS Display', Helvetica, Arial, sans-serif;
|
|
||||||
font-size: ${toString (cfg.fontSize * 1.1)}px;
|
|
||||||
min-height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
window#waybar {
|
|
||||||
background: rgba(43, 48, 59, 0.8);
|
|
||||||
border-bottom: 3px solid rgba(100, 114, 125, 0.5);
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
window#waybar.hidden {
|
|
||||||
opacity: 0.0;
|
|
||||||
}
|
|
||||||
/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */
|
|
||||||
#workspaces button {
|
|
||||||
padding: 0 5px;
|
|
||||||
background: transparent;
|
|
||||||
color: #ffffff;
|
|
||||||
border-bottom: 3px solid transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
#workspaces button.focused {
|
|
||||||
background: #64727D;
|
|
||||||
border-bottom: 3px solid #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
#workspaces button.urgent {
|
|
||||||
background-color: #eb4d4b;
|
|
||||||
}
|
|
||||||
|
|
||||||
#window, #sway, #sway-window {
|
|
||||||
padding-left: 1em;
|
|
||||||
margin-bottom: 0.4em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mode {
|
|
||||||
background: #64727D;
|
|
||||||
border-bottom: 3px solid #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* #clock, #battery, #cpu, #memory, #temperature, #backlight, #network, #pulseaudio, #bluetooth, #custom-media, #tray, #mode, #idle_inhibitor, #mpd { */
|
|
||||||
.modules-right > * > * {
|
|
||||||
margin: 0.2em 0 0.4em 0;
|
|
||||||
padding: 0.2em 0.5em;
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.25);
|
|
||||||
border-radius: 0.3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modules-right > *:not(:last-child) > * {
|
|
||||||
margin-right: 0.4em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#clock {
|
|
||||||
background-color: #64727D;
|
|
||||||
}
|
|
||||||
|
|
||||||
#battery {
|
|
||||||
background-color: #ffffff;
|
|
||||||
color: #000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
#battery.charging {
|
|
||||||
color: #ffffff;
|
|
||||||
background-color: #26A65B;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes blink {
|
|
||||||
to {
|
|
||||||
background-color: #ffffff;
|
|
||||||
color: #000000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#battery.critical:not(.charging) {
|
|
||||||
background: #f53c3c;
|
|
||||||
color: #ffffff;
|
|
||||||
animation-name: blink;
|
|
||||||
animation-duration: 0.5s;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
animation-direction: alternate;
|
|
||||||
}
|
|
||||||
|
|
||||||
#cpu {
|
|
||||||
background: #2ecc71;
|
|
||||||
color: #000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
#memory {
|
|
||||||
background: #9b59b6;
|
|
||||||
}
|
|
||||||
|
|
||||||
#backlight {
|
|
||||||
background: #90b1b1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#network {
|
|
||||||
background: #2980b9;
|
|
||||||
}
|
|
||||||
|
|
||||||
#network.disconnected {
|
|
||||||
background: #f53c3c;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pulseaudio {
|
|
||||||
background: #f1c40f;
|
|
||||||
color: #000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pulseaudio.muted {
|
|
||||||
background: #90b1b1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#bluetooth {
|
|
||||||
background: DarkSlateBlue;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
#custom-media {
|
|
||||||
background: #66cc99;
|
|
||||||
color: #2a5c45;
|
|
||||||
}
|
|
||||||
|
|
||||||
.custom-spotify {
|
|
||||||
background: #66cc99;
|
|
||||||
}
|
|
||||||
|
|
||||||
.custom-vlc {
|
|
||||||
background: #ffa000;
|
|
||||||
}
|
|
||||||
|
|
||||||
#temperature {
|
|
||||||
background: #f0932b;
|
|
||||||
}
|
|
||||||
|
|
||||||
#temperature.critical {
|
|
||||||
background: #eb4d4b;
|
|
||||||
}
|
|
||||||
|
|
||||||
#tray {
|
|
||||||
background-color: #2980b9;
|
|
||||||
}
|
|
||||||
|
|
||||||
#idle_inhibitor {
|
|
||||||
background-color: #2d3436;
|
|
||||||
}
|
|
||||||
|
|
||||||
#idle_inhibitor.activated {
|
|
||||||
background-color: #ecf0f1;
|
|
||||||
color: #2d3436;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mpd {
|
|
||||||
background-color: teal;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
''
|
|
||||||
+ cfg.extraStyle;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,25 +1,15 @@
|
||||||
{
|
{ pkgs, lib, config, ... }:
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
let
|
||||||
openconnect-epfl = pkgs.writeShellApplication {
|
openconnect-epfl = pkgs.writeShellApplication {
|
||||||
name = "openconnect-epfl";
|
name = "openconnect-epfl";
|
||||||
runtimeInputs = with pkgs; [
|
runtimeInputs = with pkgs; [ openconnect rbw ];
|
||||||
openconnect
|
|
||||||
rbw
|
|
||||||
];
|
|
||||||
text = ''
|
text = ''
|
||||||
RBW_ENTRY="EPFL Microsoft Auth"
|
GASPAR_PASSWORD=$(rbw get gaspar)
|
||||||
GASPAR_PASSWORD=$(rbw get "$RBW_ENTRY")
|
GASPAR_TOKEN=$(rbw code gaspar)
|
||||||
GASPAR_TOKEN=$(rbw code "$RBW_ENTRY")
|
|
||||||
|
|
||||||
printf "%s\n" "$GASPAR_PASSWORD" "$GASPAR_TOKEN" | command sudo openconnect \
|
printf "%s\n%s" "$GASPAR_PASSWORD" "$GASPAR_TOKEN" | sudo openconnect \
|
||||||
--passwd-on-stdin \
|
--passwd-on-stdin \
|
||||||
-u "pham" \
|
-u pham \
|
||||||
--useragent='AnyConnect' \
|
|
||||||
"https://vpn.epfl.ch"
|
"https://vpn.epfl.ch"
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
@ -27,3 +17,4 @@ in
|
||||||
{
|
{
|
||||||
home.packages = [ openconnect-epfl ];
|
home.packages = [ openconnect-epfl ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,123 +0,0 @@
|
||||||
{
|
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
# Common configuration
|
|
||||||
./common.nix
|
|
||||||
# We use our own firefox
|
|
||||||
# ./firefox.nix
|
|
||||||
# osu!
|
|
||||||
./osu
|
|
||||||
];
|
|
||||||
|
|
||||||
# Home Manager needs a bit of information about you and the
|
|
||||||
# paths it should manage.
|
|
||||||
home.username = "nki";
|
|
||||||
home.homeDirectory = "/home/nki";
|
|
||||||
|
|
||||||
# Graphical set up
|
|
||||||
linux.graphical.type = "wayland";
|
|
||||||
linux.graphical.wallpaper = ./images/wallpaper_0.png;
|
|
||||||
linux.graphical.defaults.webBrowser.package = pkgs.zen-browser-bin;
|
|
||||||
linux.graphical.defaults.webBrowser.desktopFile = "zen.desktop";
|
|
||||||
# Enable sway
|
|
||||||
programs.my-sway.enable = true;
|
|
||||||
programs.my-sway.fontSize = 14.0;
|
|
||||||
wayland.windowManager.sway.config = {
|
|
||||||
# Keyboard support
|
|
||||||
input."*".xkb_layout = "jp";
|
|
||||||
input."1278:34:HHKB-Hybrid_3_Keyboard".xkb_layout = "jp";
|
|
||||||
input."1:1:AT_Translated_Set_2_keyboard" = {
|
|
||||||
xkb_options = "ctrl:swapcaps";
|
|
||||||
};
|
|
||||||
input."2362:628:PIXA3854:00_093A:0274_Touchpad" = {
|
|
||||||
drag = "enabled";
|
|
||||||
natural_scroll = "enabled";
|
|
||||||
tap = "enabled";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
programs.my-niri.enable = true;
|
|
||||||
programs.my-niri.enableLaptop = true;
|
|
||||||
programs.my-niri.workspaces = lib.genAttrs [ "04" "05" "06" "07" "08" "09" ] (_: {
|
|
||||||
fixed = false;
|
|
||||||
});
|
|
||||||
programs.niri.settings = {
|
|
||||||
input.keyboard.xkb.options = "ctrl:swapcaps";
|
|
||||||
};
|
|
||||||
programs.my-waybar.extraSettings =
|
|
||||||
let
|
|
||||||
change-mode = pkgs.writeScript "change-mode" ''
|
|
||||||
#!/usr/bin/env ${lib.getExe pkgs.fish}
|
|
||||||
set -ax PATH ${lib.getBin pkgs.power-profiles-daemon} ${lib.getBin config.programs.rofi.package} ${lib.getBin pkgs.ripgrep}
|
|
||||||
|
|
||||||
set profiles (powerprofilesctl list | rg "^[ *] (\S+):" -r '$1')
|
|
||||||
set selected_index (math (contains -i (powerprofilesctl get) $profiles) - 1)
|
|
||||||
set new_profile (printf "%s\n" $profiles | rofi -dmenu -p "Switch to power profile" -a $selected_index)
|
|
||||||
powerprofilesctl set $new_profile
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
[
|
|
||||||
{
|
|
||||||
modules."battery"."on-click" = change-mode;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
# input-remapping
|
|
||||||
xdg.configFile."autostart/input-remapper-autoload.desktop".source =
|
|
||||||
"${pkgs.input-remapper}/share/applications/input-remapper-autoload.desktop";
|
|
||||||
# Kitty
|
|
||||||
nki.programs.kitty = {
|
|
||||||
enable = true;
|
|
||||||
fontSize = 16;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Multiple screen setup
|
|
||||||
services.kanshi = with config.common.monitors; {
|
|
||||||
enable = true;
|
|
||||||
settings = [
|
|
||||||
{
|
|
||||||
profile.name = "undocked";
|
|
||||||
profile.outputs = [ { criteria = "eDP-1"; } ];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
profile.name = "work-both";
|
|
||||||
profile.outputs = [
|
|
||||||
{
|
|
||||||
criteria = "eDP-1";
|
|
||||||
position = "0,${toString (builtins.floor ((2160 / work.scale - 1200) + 1200 / 3))}";
|
|
||||||
status = "enable";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
criteria = work.name;
|
|
||||||
position = "1920,0";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
profile.name = "work-one";
|
|
||||||
profile.outputs = [
|
|
||||||
{
|
|
||||||
criteria = "eDP-1";
|
|
||||||
status = "disable";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{ output.criteria = config.common.monitors.work.name; }
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# This value determines the Home Manager release that your
|
|
||||||
# configuration is compatible with. This helps avoid breakage
|
|
||||||
# when a new Home Manager release introduces backwards
|
|
||||||
# incompatible changes.
|
|
||||||
#
|
|
||||||
# You can update Home Manager without changing this value. See
|
|
||||||
# the Home Manager release notes for a list of state version
|
|
||||||
# changes in each release.
|
|
||||||
home.stateVersion = "21.05";
|
|
||||||
}
|
|
|
@ -1,30 +1,5 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
options,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
let
|
|
||||||
iio-sway = pkgs.stdenv.mkDerivation {
|
|
||||||
name = "iio-sway";
|
|
||||||
version = "0.0.1";
|
|
||||||
src = pkgs.fetchFromGitHub {
|
|
||||||
owner = "okeri";
|
|
||||||
repo = "iio-sway";
|
|
||||||
rev = "e07477d1b2478fede1446e97424a94c80767819d";
|
|
||||||
hash = "sha256-JGacKajslCOvd/BFfFSf7s1/hgF6rJqJ6H6xNnsuMb4=";
|
|
||||||
};
|
|
||||||
buildInputs = with pkgs; [ dbus ];
|
|
||||||
nativeBuildInputs = with pkgs; [
|
|
||||||
meson
|
|
||||||
ninja
|
|
||||||
pkg-config
|
|
||||||
];
|
|
||||||
meta.mainProgram = "iio-sway";
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
# Common configuration
|
# Common configuration
|
||||||
|
@ -32,7 +7,7 @@ in
|
||||||
# We use our own firefox
|
# We use our own firefox
|
||||||
# ./firefox.nix
|
# ./firefox.nix
|
||||||
# osu!
|
# osu!
|
||||||
./osu
|
# ./osu.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
# Home Manager needs a bit of information about you and the
|
# Home Manager needs a bit of information about you and the
|
||||||
|
@ -41,78 +16,33 @@ in
|
||||||
home.homeDirectory = "/home/nki";
|
home.homeDirectory = "/home/nki";
|
||||||
|
|
||||||
# More packages
|
# More packages
|
||||||
home.packages = (
|
home.packages = (with pkgs; [
|
||||||
with pkgs;
|
# CLI stuff
|
||||||
[
|
python3
|
||||||
# Note-taking
|
zip
|
||||||
rnote
|
# TeX
|
||||||
]
|
texlive.combined.scheme-full
|
||||||
);
|
|
||||||
|
# Java & sbt
|
||||||
|
openjdk11
|
||||||
|
sbt
|
||||||
|
]);
|
||||||
|
|
||||||
# Graphical set up
|
# Graphical set up
|
||||||
linux.graphical.type = "wayland";
|
linux.graphical.type = "wayland";
|
||||||
linux.graphical.wallpaper = ./images/wallpaper_0.png;
|
linux.graphical.wallpaper = ./images/wallpaper_0.png;
|
||||||
linux.graphical.startup = options.linux.graphical.startup.default ++ [ pkgs.slack ];
|
|
||||||
linux.graphical.defaults.webBrowser.package = pkgs.zen-browser-bin;
|
|
||||||
linux.graphical.defaults.webBrowser.desktopFile = "zen.desktop";
|
|
||||||
# Enable sway
|
# Enable sway
|
||||||
programs.my-sway.enable = true;
|
programs.my-sway.enable = true;
|
||||||
programs.my-sway.fontSize = 14.0;
|
programs.my-sway.fontSize = 14.0;
|
||||||
wayland.windowManager.sway.config = {
|
programs.my-sway.terminal = "${config.programs.kitty.package}/bin/kitty";
|
||||||
# Keyboard support
|
# Keyboard support
|
||||||
input."*".xkb_layout = "jp";
|
wayland.windowManager.sway.config = {
|
||||||
input."1278:34:HHKB-Hybrid_3_Keyboard".xkb_layout = "jp";
|
input."1278:34:HHKB-Hybrid_3_Keyboard".xkb_layout = "jp";
|
||||||
input."1:1:AT_Translated_Set_2_keyboard" = {
|
input."1:1:AT_Translated_Set_2_keyboard" = {
|
||||||
xkb_options = "ctrl:swapcaps";
|
xkb_options = "ctrl:swapcaps";
|
||||||
};
|
xkb_layout = "us";
|
||||||
|
|
||||||
# Touch and Pen
|
|
||||||
input."1386:21338:Wacom_HID_535A_Finger".map_to_output = "eDP-1";
|
|
||||||
input."1386:21338:Wacom_HID_535A_Pen".map_to_output = "eDP-1";
|
|
||||||
|
|
||||||
startup = [
|
|
||||||
# rotation
|
|
||||||
{ command = "${lib.getExe iio-sway}"; }
|
|
||||||
];
|
|
||||||
};
|
|
||||||
programs.my-niri.enable = true;
|
|
||||||
programs.my-niri.enableLaptop = true;
|
|
||||||
# Assign some of the workspaces to big screen
|
|
||||||
programs.my-niri.workspaces = lib.genAttrs [ "06" "07" "08" "09" "10" ] (_: {
|
|
||||||
monitor = config.common.monitors.work.name;
|
|
||||||
});
|
|
||||||
programs.niri.settings = {
|
|
||||||
# input.keyboard.xkb.options = "ctrl:swapcaps";
|
|
||||||
input.mouse = lib.mkForce {
|
|
||||||
# Make M575 fast for now
|
|
||||||
accel-profile = "adaptive";
|
|
||||||
accel-speed = 0.4;
|
|
||||||
};
|
|
||||||
input.touch.map-to-output = "eDP-1";
|
|
||||||
switch-events = with config.lib.niri.actions; {
|
|
||||||
tablet-mode-on.action = spawn "systemctl" "--user" "kill" "--signal" "SIGUSR2" "wvkbd";
|
|
||||||
tablet-mode-off.action = spawn "systemctl" "--user" "kill" "--signal" "SIGUSR1" "wvkbd";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
## Virtual keyboard
|
|
||||||
systemd.user.services.wvkbd = {
|
|
||||||
Unit = {
|
|
||||||
Description = "Wayland virtual keyboard";
|
|
||||||
};
|
|
||||||
Install.WantedBy = [ "waybar.service" ];
|
|
||||||
Service = {
|
|
||||||
Type = "simple";
|
|
||||||
ExecStart = "${pkgs.wvkbd}/bin/wvkbd-mobintl -l simple,special,emoji --landscape-layers simple,special,emoji --hidden";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
wayland.windowManager.sway.extraConfig = ''
|
|
||||||
bindswitch tablet:on exec systemctl --user kill --signal SIGUSR2 wvkbd
|
|
||||||
bindswitch tablet:off exec systemctl --user kill --signal SIGUSR1 wvkbd
|
|
||||||
'';
|
|
||||||
|
|
||||||
# input-remapping
|
|
||||||
xdg.configFile."autostart/input-remapper-autoload.desktop".source =
|
|
||||||
"${pkgs.input-remapper}/share/applications/input-remapper-autoload.desktop";
|
|
||||||
# Kitty
|
# Kitty
|
||||||
nki.programs.kitty = {
|
nki.programs.kitty = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -120,37 +50,12 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
# Multiple screen setup
|
# Multiple screen setup
|
||||||
services.kanshi = with config.common.monitors; {
|
services.kanshi = {
|
||||||
enable = true;
|
enable = true;
|
||||||
settings = [
|
profiles.undocked.outputs = [{ criteria = "LVDS-1"; }];
|
||||||
{
|
profiles.docked-hdmi.outputs = [
|
||||||
profile.name = "undocked";
|
{ criteria = "LVDS-1"; status = "disable"; }
|
||||||
profile.outputs = [ { criteria = "eDP-1"; } ];
|
{ criteria = "HDMI-A-1"; }
|
||||||
}
|
|
||||||
{
|
|
||||||
profile.name = "work-both";
|
|
||||||
profile.outputs = [
|
|
||||||
{
|
|
||||||
criteria = "eDP-1";
|
|
||||||
position = "0,${toString (builtins.floor ((2160 / work.scale - 1200) + 1200 / 3))}";
|
|
||||||
status = "enable";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
criteria = work.name;
|
|
||||||
position = "1920,0";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
profile.name = "work-one";
|
|
||||||
profile.outputs = [
|
|
||||||
{
|
|
||||||
criteria = "eDP-1";
|
|
||||||
status = "disable";
|
|
||||||
}
|
|
||||||
{ criteria = work.name; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -164,3 +69,4 @@ in
|
||||||
# changes in each release.
|
# changes in each release.
|
||||||
home.stateVersion = "21.05";
|
home.stateVersion = "21.05";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
31
home/osu.nix
Normal file
31
home/osu.nix
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
osu-pkg = with pkgs; with lib;
|
||||||
|
appimageTools.wrapType2 rec {
|
||||||
|
pname = "osu-lazer-bin";
|
||||||
|
version = "2023.123.0";
|
||||||
|
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://github.com/ppy/osu/releases/download/${version}/osu.AppImage";
|
||||||
|
sha256 = "sha256-edu93pvTEM5/s0kW55U1xfYGDl0eUpGXypvuYIwsM3w=";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraPkgs = pkgs: with pkgs; [ icu ];
|
||||||
|
|
||||||
|
extraInstallCommands =
|
||||||
|
let contents = appimageTools.extract { inherit pname version src; };
|
||||||
|
in
|
||||||
|
''
|
||||||
|
mv -v $out/bin/${pname}-${version} $out/bin/osu\!
|
||||||
|
install -m 444 -D ${contents}/osu\!.desktop -t $out/share/applications
|
||||||
|
for i in 16 32 48 64 96 128 256 512 1024; do
|
||||||
|
install -D ${contents}/osu\!.png $out/share/icons/hicolor/''${i}x$i/apps/osu\!.png
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
home.packages = [ osu-pkg ];
|
||||||
|
# home.packages = [ pkgs.osu-lazer ];
|
||||||
|
}
|
|
@ -1,35 +0,0 @@
|
||||||
{ pkgs, lib, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
# osu-pkg = pkgs.unstable.osu-lazer-bin;
|
|
||||||
osu-pkg =
|
|
||||||
with pkgs;
|
|
||||||
with lib;
|
|
||||||
appimageTools.wrapType2 rec {
|
|
||||||
pname = "osu-lazer-bin";
|
|
||||||
version = "2025.424.0";
|
|
||||||
src = fetchurl {
|
|
||||||
url = "https://github.com/ppy/osu/releases/download/${version}/osu.AppImage";
|
|
||||||
hash = "sha256-8nOoSkNbzEFpDj0FivCYI20tZzT02YHcKZblfEfh+Zo=";
|
|
||||||
};
|
|
||||||
extraPkgs = pkgs: with pkgs; [ icu ];
|
|
||||||
|
|
||||||
extraInstallCommands =
|
|
||||||
let
|
|
||||||
contents = appimageTools.extract { inherit pname version src; };
|
|
||||||
in
|
|
||||||
''
|
|
||||||
mv -v $out/bin/${pname} $out/bin/osu\!
|
|
||||||
install -m 444 -D ${contents}/osu\!.desktop -t $out/share/applications
|
|
||||||
install -m 444 -D ${./mimetypes.xml} $out/share/mime/packages/${pname}.xml
|
|
||||||
for i in 16 32 48 64 96 128 256 512 1024; do
|
|
||||||
install -D ${contents}/osu.png $out/share/icons/hicolor/''${i}x$i/apps/osu.png
|
|
||||||
done
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
home.packages = [ osu-pkg ];
|
|
||||||
xdg.mimeApps.defaultApplications."x-scheme-handler/osu" = "osu!.desktop";
|
|
||||||
# home.packages = [ pkgs.osu-lazer ];
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
|
|
||||||
<mime-type type="application/x-osu-beatmap-archive">
|
|
||||||
<icon name="osu"/>
|
|
||||||
<comment xml:lang="en">osu! Beatmap Archive</comment>
|
|
||||||
<glob pattern="*.osz"/>
|
|
||||||
<glob pattern="*.olz"/>
|
|
||||||
</mime-type>
|
|
||||||
<mime-type type="application/x-osu-skin-archive">
|
|
||||||
<icon name="osu"/>
|
|
||||||
<comment xml:lang="en">osu! Skin Archive</comment>
|
|
||||||
<glob pattern="*.osk"/>
|
|
||||||
</mime-type>
|
|
||||||
<mime-type type="application/x-osu-beatmap">
|
|
||||||
<icon name="osu"/>
|
|
||||||
<comment xml:lang="en">osu! Beatmap</comment>
|
|
||||||
<glob pattern="*.osu"/>
|
|
||||||
</mime-type>
|
|
||||||
<mime-type type="application/x-osu-storyboard">
|
|
||||||
<icon name="osu"/>
|
|
||||||
<comment xml:lang="en">osu! Storyboard</comment>
|
|
||||||
<glob pattern="*.osb"/>
|
|
||||||
</mime-type>
|
|
||||||
<mime-type type="application/x-osu-replay">
|
|
||||||
<icon name="osu"/>
|
|
||||||
<comment xml:lang="en">osu! Replay</comment>
|
|
||||||
<glob pattern="*.osr"/>
|
|
||||||
</mime-type>
|
|
||||||
</mime-info>
|
|
|
@ -2,39 +2,18 @@
|
||||||
# your system. Help is available in the configuration.nix(5) man page
|
# your system. Help is available in the configuration.nix(5) man page
|
||||||
# and in the NixOS manual (accessible by running ‘nixos-help’).
|
# and in the NixOS manual (accessible by running ‘nixos-help’).
|
||||||
|
|
||||||
{
|
{ config, pkgs, lib, ... }:
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports =
|
||||||
|
[
|
||||||
# Include the results of the hardware scan.
|
# Include the results of the hardware scan.
|
||||||
./hardware-configuration.nix
|
./hardware-configuration.nix
|
||||||
# Fonts
|
# Fonts
|
||||||
../modules/personal/fonts
|
../modules/personal/fonts
|
||||||
# Encrypted DNS
|
# Encrypted DNS
|
||||||
../modules/services/edns
|
../modules/services/edns
|
||||||
# Override base mesa
|
|
||||||
(
|
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
nixpkgs.overlays = lib.mkBefore [
|
|
||||||
(final: prev: {
|
|
||||||
mesa = prev.mesa.override {
|
|
||||||
enableOpenCL = true;
|
|
||||||
meson = final.unstable.meson;
|
|
||||||
};
|
|
||||||
})
|
|
||||||
];
|
];
|
||||||
}
|
|
||||||
)
|
|
||||||
];
|
|
||||||
|
|
||||||
# time.timeZone = lib.mkForce "Asia/Ho_Chi_Minh";
|
|
||||||
services.xserver.desktopManager.plasma5.enable = true;
|
|
||||||
|
|
||||||
# Asahi kernel configuration
|
# Asahi kernel configuration
|
||||||
hardware.asahi = {
|
hardware.asahi = {
|
||||||
|
@ -45,30 +24,6 @@
|
||||||
useExperimentalGPUDriver = true;
|
useExperimentalGPUDriver = true;
|
||||||
experimentalGPUInstallMode = "overlay";
|
experimentalGPUInstallMode = "overlay";
|
||||||
};
|
};
|
||||||
# Override mesa
|
|
||||||
nixpkgs.overlays = lib.mkAfter [
|
|
||||||
(final: prev: {
|
|
||||||
mesa-asahi-edge = prev.mesa-asahi-edge.overrideAttrs (attrs: {
|
|
||||||
version = "24.0.0";
|
|
||||||
# buildInputs = attrs.buildInputs ++ (with pkgslw; [ libclc cmake (spirv-llvm-translator.override { inherit (llvmPackages_15) llvm; }) ]);
|
|
||||||
# nativeBuildInputs = attrs.nativeBuildInputs ++ (with pkgs; [ pkgs.unstable.spirv-llvm-translator ]);
|
|
||||||
src = final.fetchFromGitLab {
|
|
||||||
# latest release
|
|
||||||
domain = "gitlab.freedesktop.org";
|
|
||||||
owner = "asahi";
|
|
||||||
repo = "mesa";
|
|
||||||
rev = "asahi-20231121";
|
|
||||||
hash = "sha256-IcKKe1RA8sCaUfWK71ELzF15YaBS3DjoYhNMIWiQ5Jw=";
|
|
||||||
};
|
|
||||||
|
|
||||||
patches = lib.forEach attrs.patches (
|
|
||||||
p: if lib.hasSuffix "opencl.patch" p then ./mesa-asahi-edge/opencl.patch else p
|
|
||||||
);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
];
|
|
||||||
## Additional mesa-related packages
|
|
||||||
environment.systemPackages = with pkgs; [ SDL2 ];
|
|
||||||
|
|
||||||
# Power Management
|
# Power Management
|
||||||
services.upower = {
|
services.upower = {
|
||||||
|
@ -85,7 +40,7 @@
|
||||||
services.printing.drivers = with pkgs; [ epfl-cups-drivers ];
|
services.printing.drivers = with pkgs; [ epfl-cups-drivers ];
|
||||||
|
|
||||||
# Enable touchpad support (enabled default in most desktopManager).
|
# Enable touchpad support (enabled default in most desktopManager).
|
||||||
services.libinput.enable = true;
|
services.xserver.libinput.enable = true;
|
||||||
# Keyboard
|
# Keyboard
|
||||||
services.input-remapper.enable = true;
|
services.input-remapper.enable = true;
|
||||||
services.input-remapper.serviceWantedBy = [ "multi-user.target" ];
|
services.input-remapper.serviceWantedBy = [ "multi-user.target" ];
|
||||||
|
@ -160,3 +115,4 @@
|
||||||
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||||||
system.stateVersion = "22.05"; # Did you read the comment?
|
system.stateVersion = "22.05"; # Did you read the comment?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,11 @@
|
||||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
# and may be overwritten by future invocations. Please make changes
|
# and may be overwritten by future invocations. Please make changes
|
||||||
# to /etc/nixos/configuration.nix instead.
|
# to /etc/nixos/configuration.nix instead.
|
||||||
{
|
{ config, lib, pkgs, modulesPath, ... }:
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
modulesPath,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports =
|
||||||
|
[
|
||||||
(modulesPath + "/installer/scan/not-detected.nix")
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -19,21 +14,20 @@
|
||||||
boot.kernelModules = [ ];
|
boot.kernelModules = [ ];
|
||||||
boot.extraModulePackages = [ ];
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
fileSystems."/" = {
|
fileSystems."/" =
|
||||||
|
{
|
||||||
device = "/dev/disk/by-uuid/ebb6bf2e-2d7f-4fa6-88cb-751fdd174ef9";
|
device = "/dev/disk/by-uuid/ebb6bf2e-2d7f-4fa6-88cb-751fdd174ef9";
|
||||||
fsType = "ext4";
|
fsType = "ext4";
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/boot" = {
|
fileSystems."/boot" =
|
||||||
|
{
|
||||||
device = "/dev/disk/by-uuid/19BC-1BE8";
|
device = "/dev/disk/by-uuid/19BC-1BE8";
|
||||||
fsType = "vfat";
|
fsType = "vfat";
|
||||||
};
|
};
|
||||||
|
|
||||||
swapDevices = [
|
swapDevices = [
|
||||||
{
|
{ device = "/swap"; size = 16 * 1024; }
|
||||||
device = "/swap";
|
|
||||||
size = 16 * 1024;
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
|
# nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
diff --git a/meson.build b/meson.build
|
|
||||||
index 04d89987311..babfe440973 100644
|
|
||||||
--- a/meson.build
|
|
||||||
+++ b/meson.build
|
|
||||||
@@ -1812,7 +1812,7 @@ endif
|
|
||||||
|
|
||||||
dep_clang = null_dep
|
|
||||||
if with_clc
|
|
||||||
- llvm_libdir = dep_llvm.get_variable(cmake : 'LLVM_LIBRARY_DIR', configtool: 'libdir')
|
|
||||||
+ llvm_libdir = get_option('clang-libdir')
|
|
||||||
|
|
||||||
dep_clang = cpp.find_library('clang-cpp', dirs : llvm_libdir, required : false)
|
|
||||||
|
|
||||||
diff --git a/meson_options.txt b/meson_options.txt
|
|
||||||
index e885ba61a8a..29ce0270479 100644
|
|
||||||
--- a/meson_options.txt
|
|
||||||
+++ b/meson_options.txt
|
|
||||||
@@ -1,6 +1,12 @@
|
|
||||||
# Copyright © 2017-2019 Intel Corporation
|
|
||||||
# SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
+option(
|
|
||||||
+ 'clang-libdir',
|
|
||||||
+ type : 'string',
|
|
||||||
+ value : '',
|
|
||||||
+ description : 'Locations to search for clang libraries.'
|
|
||||||
+)
|
|
||||||
option(
|
|
||||||
'platforms',
|
|
||||||
type : 'array',
|
|
||||||
diff --git a/src/gallium/targets/opencl/meson.build b/src/gallium/targets/opencl/meson.build
|
|
||||||
index 7c14135898e..74dc6850603 100644
|
|
||||||
--- a/src/gallium/targets/opencl/meson.build
|
|
||||||
+++ b/src/gallium/targets/opencl/meson.build
|
|
||||||
@@ -39,7 +39,8 @@ if dep_llvm.version().version_compare('>=10.0.0')
|
|
||||||
polly_isl_dep = cpp.find_library('PollyISL', dirs : llvm_libdir, required : false)
|
|
||||||
endif
|
|
||||||
|
|
||||||
-dep_clang = cpp.find_library('clang-cpp', dirs : llvm_libdir, required : false)
|
|
||||||
+clang_libdir = get_option('clang-libdir')
|
|
||||||
+dep_clang = cpp.find_library('clang-cpp', dirs : clang_libdir, required : false)
|
|
||||||
|
|
||||||
# meson will return clang-cpp from system dirs if it's not found in llvm_libdir
|
|
||||||
linker_rpath_arg = '-Wl,--rpath=@0@'.format(llvm_libdir)
|
|
||||||
@@ -123,7 +124,7 @@ if with_opencl_icd
|
|
||||||
configuration : _config,
|
|
||||||
input : 'mesa.icd.in',
|
|
||||||
output : 'mesa.icd',
|
|
||||||
- install : true,
|
|
||||||
+ install : false,
|
|
||||||
install_tag : 'runtime',
|
|
||||||
install_dir : join_paths(get_option('sysconfdir'), 'OpenCL', 'vendors'),
|
|
||||||
)
|
|
||||||
diff --git a/src/gallium/targets/rusticl/meson.build b/src/gallium/targets/rusticl/meson.build
|
|
||||||
index b2963fe6dfa..99d6d801b94 100644
|
|
||||||
--- a/src/gallium/targets/rusticl/meson.build
|
|
||||||
+++ b/src/gallium/targets/rusticl/meson.build
|
|
||||||
@@ -76,7 +76,7 @@ configure_file(
|
|
||||||
configuration : _config,
|
|
||||||
input : 'rusticl.icd.in',
|
|
||||||
output : 'rusticl.icd',
|
|
||||||
- install : true,
|
|
||||||
+ install : false,
|
|
||||||
install_tag : 'runtime',
|
|
||||||
install_dir : join_paths(get_option('sysconfdir'), 'OpenCL', 'vendors'),
|
|
||||||
)
|
|
|
@ -1,23 +1,19 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.cloud.authentik;
|
cfg = config.cloud.authentik;
|
||||||
|
|
||||||
mkImage = { imageName, imageDigest, ... }: "${imageName}@${imageDigest}";
|
mkImage =
|
||||||
|
{ imageName, imageDigest, ... }: "${imageName}@${imageDigest}";
|
||||||
# If we can pullImage we can just do
|
# If we can pullImage we can just do
|
||||||
# mkImage = pkgs.dockerTools.pullImage;
|
# mkImage = pkgs.dockerTools.pullImage;
|
||||||
|
|
||||||
images = {
|
images = {
|
||||||
postgresql = mkImage {
|
postgresql = mkImage {
|
||||||
imageName = "postgres";
|
imageName = "postgres";
|
||||||
finalImageTag = "16-alpine";
|
finalImageTag = "12-alpine";
|
||||||
imageDigest = "sha256:b40547ea0c7bcb401d8f11c6a233ebe65e2067e5966e54ccf9b03c5f01c2957c";
|
imageDigest = "sha256:f52ffee699232c84d820c35c28656363f4fda6a3e3e934b83f4e5e1898e2bdfa";
|
||||||
};
|
};
|
||||||
redis = mkImage {
|
redis = mkImage {
|
||||||
imageName = "redis";
|
imageName = "redis";
|
||||||
|
@ -26,8 +22,8 @@ let
|
||||||
};
|
};
|
||||||
authentik = mkImage {
|
authentik = mkImage {
|
||||||
imageName = "ghcr.io/goauthentik/server";
|
imageName = "ghcr.io/goauthentik/server";
|
||||||
finalImageTag = "2025.2.4";
|
finalImageTag = "2023.5.5";
|
||||||
imageDigest = "sha256:36233579415aa2e2e52a6b0c45736cb871fe71460bfe0cf95d83f67528fb1182";
|
imageDigest = "sha256:7a82b9dcd0236e06079b3c78e7b3f1b8f3c597a7d2026c60244d685d4908a23b";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
authentikEnv = pkgs.writeText "authentik.env" ''
|
authentikEnv = pkgs.writeText "authentik.env" ''
|
||||||
|
@ -52,24 +48,13 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
systemd.services.arion-authentik = {
|
systemd.services.arion-authentik.serviceConfig.EnvironmentFile = cfg.envFile;
|
||||||
serviceConfig.EnvironmentFile = cfg.envFile;
|
|
||||||
serviceConfig.Type = "notify";
|
|
||||||
serviceConfig.NotifyAccess = "all";
|
|
||||||
serviceConfig.TimeoutSec = 300;
|
|
||||||
script = lib.mkBefore ''
|
|
||||||
${lib.getExe pkgs.wait4x} http http://127.0.0.1:${toString cfg.port} --expect-status-code 200 -t 0 -q -- systemd-notify --ready &
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
virtualisation.arion.projects.authentik.settings = {
|
virtualisation.arion.projects.authentik.settings = {
|
||||||
services.postgresql.service = {
|
services.postgresql.service = {
|
||||||
image = images.postgresql;
|
image = images.postgresql;
|
||||||
restart = "unless-stopped";
|
restart = "unless-stopped";
|
||||||
healthcheck = {
|
healthcheck = {
|
||||||
test = [
|
test = [ "CMD-SHELL" "pg_isready -d $\${POSTGRES_DB} -U $\${POSTGRES_USER}" ];
|
||||||
"CMD-SHELL"
|
|
||||||
"pg_isready -d $\${POSTGRES_DB} -U $\${POSTGRES_USER}"
|
|
||||||
];
|
|
||||||
start_period = "20s";
|
start_period = "20s";
|
||||||
interval = "30s";
|
interval = "30s";
|
||||||
retries = 5;
|
retries = 5;
|
||||||
|
@ -80,20 +65,14 @@ in
|
||||||
POSTGRES_USER = "authentik";
|
POSTGRES_USER = "authentik";
|
||||||
POSTGRES_DB = "authentik";
|
POSTGRES_DB = "authentik";
|
||||||
};
|
};
|
||||||
env_file = [
|
env_file = [ cfg.envFile "${postgresEnv}" ];
|
||||||
cfg.envFile
|
|
||||||
"${postgresEnv}"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
services.redis.service = {
|
services.redis.service = {
|
||||||
image = images.redis;
|
image = images.redis;
|
||||||
command = "--save 60 1 --loglevel warning";
|
command = "--save 60 1 --loglevel warning";
|
||||||
restart = "unless-stopped";
|
restart = "unless-stopped";
|
||||||
healthcheck = {
|
healthcheck = {
|
||||||
test = [
|
test = [ "CMD-SHELL" "redis-cli ping | grep PONG" ];
|
||||||
"CMD-SHELL"
|
|
||||||
"redis-cli ping | grep PONG"
|
|
||||||
];
|
|
||||||
start_period = "20s";
|
start_period = "20s";
|
||||||
interval = "30s";
|
interval = "30s";
|
||||||
retries = 5;
|
retries = 5;
|
||||||
|
@ -115,14 +94,10 @@ in
|
||||||
AUTHENTIK_POSTGRESQL__USER = "authentik";
|
AUTHENTIK_POSTGRESQL__USER = "authentik";
|
||||||
AUTHENTIK_POSTGRESQL__NAME = "authentik";
|
AUTHENTIK_POSTGRESQL__NAME = "authentik";
|
||||||
};
|
};
|
||||||
env_file = [
|
env_file = [ cfg.envFile "${authentikEnv}" ];
|
||||||
cfg.envFile
|
|
||||||
"${authentikEnv}"
|
|
||||||
];
|
|
||||||
ports = [
|
ports = [
|
||||||
"127.0.0.1:${toString cfg.port}:9000"
|
"127.0.0.1:${toString cfg.port}:9000"
|
||||||
];
|
];
|
||||||
|
|
||||||
};
|
};
|
||||||
services.worker.service = {
|
services.worker.service = {
|
||||||
image = images.authentik;
|
image = images.authentik;
|
||||||
|
@ -140,11 +115,7 @@ in
|
||||||
AUTHENTIK_POSTGRESQL__USER = "authentik";
|
AUTHENTIK_POSTGRESQL__USER = "authentik";
|
||||||
AUTHENTIK_POSTGRESQL__NAME = "authentik";
|
AUTHENTIK_POSTGRESQL__NAME = "authentik";
|
||||||
};
|
};
|
||||||
env_file = [
|
env_file = [ cfg.envFile "${authentikEnv}" ];
|
||||||
cfg.envFile
|
|
||||||
"${authentikEnv}"
|
|
||||||
];
|
|
||||||
user = "root";
|
|
||||||
};
|
};
|
||||||
docker-compose.volumes = {
|
docker-compose.volumes = {
|
||||||
database.driver = "local";
|
database.driver = "local";
|
||||||
|
@ -153,3 +124,4 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ pkgs, lib, config, ... }:
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
|
@ -15,19 +10,12 @@ let
|
||||||
user = "bitwarden";
|
user = "bitwarden";
|
||||||
|
|
||||||
port = 8001;
|
port = 8001;
|
||||||
|
notificationsPort = 8002;
|
||||||
|
|
||||||
host = "bw.nkagami.me";
|
host = "bw.nkagami.me";
|
||||||
|
|
||||||
package = pkgs.vaultwarden-postgresql;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.cloud.bitwarden = {
|
options.cloud.bitwarden = { };
|
||||||
envFile = mkOption {
|
|
||||||
type = types.nullOr types.path;
|
|
||||||
description = "Path to the env file containing stuff";
|
|
||||||
default = null;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
# users
|
# users
|
||||||
|
@ -41,7 +29,11 @@ in
|
||||||
# traefik
|
# traefik
|
||||||
cloud.traefik.hosts.bitwarden = {
|
cloud.traefik.hosts.bitwarden = {
|
||||||
inherit port host;
|
inherit port host;
|
||||||
noCloudflare = true;
|
};
|
||||||
|
cloud.traefik.hosts.bitwarden-notifications = {
|
||||||
|
inherit host;
|
||||||
|
port = notificationsPort;
|
||||||
|
path = "/notifications/hub";
|
||||||
};
|
};
|
||||||
# systemd unit
|
# systemd unit
|
||||||
systemd.services.bitwarden-server = {
|
systemd.services.bitwarden-server = {
|
||||||
|
@ -52,20 +44,19 @@ in
|
||||||
DATABASE_URL = databaseUrl;
|
DATABASE_URL = databaseUrl;
|
||||||
|
|
||||||
DATA_FOLDER = "/var/lib/bitwarden-server";
|
DATA_FOLDER = "/var/lib/bitwarden-server";
|
||||||
WEB_VAULT_FOLDER = "${pkgs.vaultwarden-vault}/share/vaultwarden/vault";
|
WEB_VAULT_FOLDER = "${pkgs.unstable.vaultwarden-vault}/share/vaultwarden/vault";
|
||||||
|
|
||||||
ROCKET_PORT = toString port;
|
ROCKET_PORT = toString port;
|
||||||
|
|
||||||
PUSH_ENABLED = "true";
|
WEBSOCKET_ENABLED = "true";
|
||||||
|
WEBSOCKET_PORT = toString notificationsPort;
|
||||||
|
|
||||||
DOMAIN = "https://${host}";
|
DOMAIN = "https://${host}";
|
||||||
};
|
};
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
User = user;
|
User = user;
|
||||||
Group = user;
|
Group = user;
|
||||||
ExecStart = "${package}/bin/vaultwarden";
|
ExecStart = "${pkgs.unstable.vaultwarden-postgresql}/bin/vaultwarden";
|
||||||
EnvironmentFile = lists.optional (cfg.envFile != null) cfg.envFile;
|
|
||||||
LimitNOFILE = "1048576";
|
LimitNOFILE = "1048576";
|
||||||
PrivateTmp = "true";
|
PrivateTmp = "true";
|
||||||
PrivateDevices = "true";
|
PrivateDevices = "true";
|
||||||
|
@ -74,7 +65,6 @@ in
|
||||||
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
|
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
|
||||||
StateDirectory = "bitwarden-server";
|
StateDirectory = "bitwarden-server";
|
||||||
};
|
};
|
||||||
requires = [ "postgresql.service" ];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.cloud.conduit;
|
cfg = config.cloud.conduit;
|
||||||
|
@ -38,8 +33,7 @@ with lib;
|
||||||
};
|
};
|
||||||
|
|
||||||
instances = mkOption {
|
instances = mkOption {
|
||||||
type = types.attrsOf (
|
type = types.attrsOf (types.submodule {
|
||||||
types.submodule {
|
|
||||||
options = {
|
options = {
|
||||||
host = mkOption {
|
host = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
|
@ -51,10 +45,6 @@ with lib;
|
||||||
port = mkOption {
|
port = mkOption {
|
||||||
type = types.int;
|
type = types.int;
|
||||||
};
|
};
|
||||||
noCloudflare = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
};
|
|
||||||
allow_registration = mkOption {
|
allow_registration = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
|
@ -63,37 +53,30 @@ with lib;
|
||||||
type = types.int;
|
type = types.int;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
});
|
||||||
);
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config.systemd.services = mkIf cfg.enable (
|
config.systemd.services = mkIf cfg.enable
|
||||||
lib.attrsets.mapAttrs' (
|
(lib.attrsets.mapAttrs'
|
||||||
name: instance:
|
(name: instance: lib.attrsets.nameValuePair "matrix-conduit-${name}"
|
||||||
lib.attrsets.nameValuePair "matrix-conduit-${name}" (
|
(
|
||||||
let
|
let
|
||||||
srvName = "matrix-conduit-${name}";
|
srvName = "matrix-conduit-${name}";
|
||||||
format = pkgs.formats.toml { };
|
format = pkgs.formats.toml { };
|
||||||
server_name = if instance.server_name == "" then instance.host else instance.server_name;
|
server_name = if instance.server_name == "" then instance.host else instance.server_name;
|
||||||
configFile = format.generate "conduit.toml" (
|
configFile = format.generate "conduit.toml" (lib.attrsets.recursiveUpdate defaultConfig {
|
||||||
lib.attrsets.recursiveUpdate defaultConfig {
|
|
||||||
global.server_name = server_name;
|
global.server_name = server_name;
|
||||||
global.port = instance.port;
|
global.port = instance.port;
|
||||||
global.allow_registration = instance.allow_registration;
|
global.allow_registration = instance.allow_registration;
|
||||||
global.database_path = "/mnt/data/${srvName}/";
|
global.database_path = "/var/lib/${srvName}/";
|
||||||
global.well_known_client = "https://${instance.host}";
|
});
|
||||||
global.well_known_server = "${instance.host}:443";
|
|
||||||
}
|
|
||||||
);
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
description = "Conduit Matrix Server (for ${server_name})";
|
description = "Conduit Matrix Server (for ${server_name})";
|
||||||
documentation = [ "https://gitlab.com/famedly/conduit/" ];
|
documentation = [ "https://gitlab.com/famedly/conduit/" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
environment = {
|
environment = { CONDUIT_CONFIG = configFile; };
|
||||||
CONDUIT_CONFIG = configFile;
|
|
||||||
};
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
DynamicUser = true;
|
DynamicUser = true;
|
||||||
User = "${srvName}";
|
User = "${srvName}";
|
||||||
|
@ -108,10 +91,7 @@ with lib;
|
||||||
PrivateDevices = true;
|
PrivateDevices = true;
|
||||||
PrivateMounts = true;
|
PrivateMounts = true;
|
||||||
PrivateUsers = true;
|
PrivateUsers = true;
|
||||||
RestrictAddressFamilies = [
|
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
|
||||||
"AF_INET"
|
|
||||||
"AF_INET6"
|
|
||||||
];
|
|
||||||
RestrictNamespaces = true;
|
RestrictNamespaces = true;
|
||||||
RestrictRealtime = true;
|
RestrictRealtime = true;
|
||||||
SystemCallArchitectures = "native";
|
SystemCallArchitectures = "native";
|
||||||
|
@ -119,24 +99,65 @@ with lib;
|
||||||
"@system-service"
|
"@system-service"
|
||||||
"~@privileged"
|
"~@privileged"
|
||||||
];
|
];
|
||||||
# StateDirectory = "/mnt/data/${srvName}";
|
StateDirectory = "${srvName}";
|
||||||
BindPaths = [ "/mnt/data/${srvName}" ];
|
|
||||||
ExecStart = "${cfg.package}/bin/conduit";
|
ExecStart = "${cfg.package}/bin/conduit";
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
RestartSec = 10;
|
RestartSec = 10;
|
||||||
StartLimitBurst = 5;
|
StartLimitBurst = 5;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
)
|
))
|
||||||
) cfg.instances
|
cfg.instances);
|
||||||
);
|
|
||||||
|
# Serving .well-known files
|
||||||
|
# This is a single .well-known/matrix/server file that points to the server,
|
||||||
|
# which is NOT on port 8448 since Cloudflare doesn't allow us to route HTTPS
|
||||||
|
# through that port.
|
||||||
|
config.services.nginx = mkIf cfg.enable
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
virtualHosts = lib.attrsets.mapAttrs'
|
||||||
|
(name: instance: lib.attrsets.nameValuePair "conduit-${name}-well-known" {
|
||||||
|
listen = [{ addr = "127.0.0.1"; port = instance.well-known_port; }];
|
||||||
|
# Check https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/configuring-well-known.md
|
||||||
|
# for the file structure.
|
||||||
|
root = pkgs.symlinkJoin
|
||||||
|
{
|
||||||
|
name = "well-known-files-for-conduit-${name}";
|
||||||
|
paths = [
|
||||||
|
(pkgs.writeTextDir ".well-known/matrix/client" (builtins.toJSON {
|
||||||
|
"m.homeserver".base_url = "https://${instance.host}";
|
||||||
|
}))
|
||||||
|
(pkgs.writeTextDir ".well-known/matrix/server" (builtins.toJSON {
|
||||||
|
"m.server" = "${instance.host}:443";
|
||||||
|
}))
|
||||||
|
];
|
||||||
|
};
|
||||||
|
# Enable CORS from anywhere since we want all clients to find us out
|
||||||
|
extraConfig = ''
|
||||||
|
add_header 'Access-Control-Allow-Origin' "*";
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
cfg.instances;
|
||||||
|
};
|
||||||
|
|
||||||
config.cloud.traefik.hosts = mkIf cfg.enable (
|
config.cloud.traefik.hosts = mkIf cfg.enable (
|
||||||
(lib.attrsets.mapAttrs' (
|
(lib.attrsets.mapAttrs'
|
||||||
name: instance:
|
(name: instance: lib.attrsets.nameValuePair "conduit-${name}" ({
|
||||||
lib.attrsets.nameValuePair "conduit-${name}" ({
|
inherit (instance) host port;
|
||||||
inherit (instance) host port noCloudflare;
|
}))
|
||||||
})
|
cfg.instances)
|
||||||
) cfg.instances)
|
// (lib.attrsets.mapAttrs'
|
||||||
|
(name: instance: lib.attrsets.nameValuePair "conduit-${name}-well-known" (
|
||||||
|
let
|
||||||
|
server_name = if instance.server_name == "" then instance.host else instance.server_name;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
port = instance.well-known_port;
|
||||||
|
filter = "Host(`${server_name}`) && PathPrefix(`/.well-known`)";
|
||||||
|
}
|
||||||
|
))
|
||||||
|
cfg.instances)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,9 @@
|
||||||
{
|
{ pkgs, lib, config, ... }:
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
let
|
||||||
cfg = config.cloud.conduit.heisenbridge;
|
cfg = config.cloud.conduit.heisenbridge;
|
||||||
cfgConduit = config.cloud.conduit;
|
cfgConduit = config.cloud.conduit;
|
||||||
in
|
in
|
||||||
with lib;
|
with lib; {
|
||||||
{
|
|
||||||
options.cloud.conduit.heisenbridge = {
|
options.cloud.conduit.heisenbridge = {
|
||||||
enable = mkEnableOption "Enable heisenbridge for conduit";
|
enable = mkEnableOption "Enable heisenbridge for conduit";
|
||||||
package = mkPackageOption pkgs "heisenbridge" { };
|
package = mkPackageOption pkgs "heisenbridge" { };
|
||||||
|
@ -29,26 +23,17 @@ with lib;
|
||||||
};
|
};
|
||||||
config = mkIf cfg.enable (
|
config = mkIf cfg.enable (
|
||||||
let
|
let
|
||||||
cfgFile =
|
cfgFile = if cfg.port == null then cfg.appserviceFile else
|
||||||
if cfg.port == null then
|
|
||||||
cfg.appserviceFile
|
|
||||||
else
|
|
||||||
pkgs.runCommand "heisenbridge-config" { } ''
|
pkgs.runCommand "heisenbridge-config" { } ''
|
||||||
cp ${cfg.appserviceFile} $out
|
cp ${cfg.appserviceFile} $out
|
||||||
${pkgs.sd}/bin/sd '^url: .*$' "url: http://127.0.0.1:${cfg.port}"
|
${pkgs.sd}/bin/sd '^url: .*$' "url: http://127.0.0.1:${cfg.port}"
|
||||||
'';
|
'';
|
||||||
listenArgs = lists.optionals (cfg.port != null) [
|
listenArgs = lists.optionals (cfg.port != null) [ "--listen-port" (toString cfg.port) ];
|
||||||
"--listen-port"
|
|
||||||
(toString cfg.port)
|
|
||||||
];
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
systemd.services.heisenbridge = {
|
systemd.services.heisenbridge = {
|
||||||
description = "Matrix<->IRC bridge";
|
description = "Matrix<->IRC bridge";
|
||||||
requires = [
|
before = [ "matrix-synapse.service" ]; # So the registration file can be used by Synapse
|
||||||
"matrix-conduit-nkagami.service"
|
|
||||||
"matrix-synapse.service"
|
|
||||||
]; # So the registration file can be used by Synapse
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
serviceConfig = rec {
|
serviceConfig = rec {
|
||||||
|
@ -92,18 +77,12 @@ with lib;
|
||||||
RemoveIPC = true;
|
RemoveIPC = true;
|
||||||
UMask = "0077";
|
UMask = "0077";
|
||||||
|
|
||||||
CapabilityBoundingSet = [
|
CapabilityBoundingSet = [ "CAP_CHOWN" ] ++ optional (cfg.port != null && cfg.port < 1024) "CAP_NET_BIND_SERVICE";
|
||||||
"CAP_CHOWN"
|
|
||||||
] ++ optional (cfg.port != null && cfg.port < 1024) "CAP_NET_BIND_SERVICE";
|
|
||||||
AmbientCapabilities = CapabilityBoundingSet;
|
AmbientCapabilities = CapabilityBoundingSet;
|
||||||
NoNewPrivileges = true;
|
NoNewPrivileges = true;
|
||||||
LockPersonality = true;
|
LockPersonality = true;
|
||||||
RestrictRealtime = true;
|
RestrictRealtime = true;
|
||||||
SystemCallFilter = [
|
SystemCallFilter = [ "@system-service" "~@privileged" "@chown" ];
|
||||||
"@system-service"
|
|
||||||
"~@privileged"
|
|
||||||
"@chown"
|
|
||||||
];
|
|
||||||
SystemCallArchitectures = "native";
|
SystemCallArchitectures = "native";
|
||||||
RestrictAddressFamilies = "AF_INET AF_INET6";
|
RestrictAddressFamilies = "AF_INET AF_INET6";
|
||||||
};
|
};
|
||||||
|
@ -118,3 +97,4 @@ with lib;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.cloud.firezone;
|
cfg = config.cloud.firezone;
|
||||||
|
|
||||||
mkImage = { imageName, imageDigest, ... }: "${imageName}@${imageDigest}";
|
mkImage =
|
||||||
|
{ imageName, imageDigest, ... }: "${imageName}@${imageDigest}";
|
||||||
# If we can pullImage we can just do
|
# If we can pullImage we can just do
|
||||||
# mkImage = pkgs.dockerTools.pullImage;
|
# mkImage = pkgs.dockerTools.pullImage;
|
||||||
|
|
||||||
|
@ -52,10 +48,7 @@ in
|
||||||
image = images.postgresql;
|
image = images.postgresql;
|
||||||
restart = "unless-stopped";
|
restart = "unless-stopped";
|
||||||
healthcheck = {
|
healthcheck = {
|
||||||
test = [
|
test = [ "CMD-SHELL" "pg_isready -d $\${POSTGRES_DB} -U $\${POSTGRES_USER}" ];
|
||||||
"CMD-SHELL"
|
|
||||||
"pg_isready -d $\${POSTGRES_DB} -U $\${POSTGRES_USER}"
|
|
||||||
];
|
|
||||||
start_period = "20s";
|
start_period = "20s";
|
||||||
interval = "30s";
|
interval = "30s";
|
||||||
retries = 5;
|
retries = 5;
|
||||||
|
@ -96,10 +89,7 @@ in
|
||||||
driver = "bridge";
|
driver = "bridge";
|
||||||
ipam.config = [
|
ipam.config = [
|
||||||
{ subnet = "172.25.0.0/16"; }
|
{ subnet = "172.25.0.0/16"; }
|
||||||
{
|
{ subnet = "2001:3990:3990::/64"; gateway = "2001:3990:3990::1"; }
|
||||||
subnet = "2001:3990:3990::/64";
|
|
||||||
gateway = "2001:3990:3990::1";
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,20 +1,37 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.cloud.gotosocial;
|
cfg = config.cloud.gotosocial;
|
||||||
|
|
||||||
dbUser = "gotosocial";
|
dbUser = "gotosocial";
|
||||||
storageLocation = "/mnt/data/gotosocial";
|
|
||||||
|
configFile = pkgs.writeText "config.yml" (generators.toYAML { } {
|
||||||
|
# General
|
||||||
|
host = cfg.host;
|
||||||
|
account-domain = cfg.accountDomain;
|
||||||
|
bind-address = "localhost";
|
||||||
|
port = cfg.port;
|
||||||
|
# Database
|
||||||
|
db-port = 0; # Use socket
|
||||||
|
db-user = dbUser;
|
||||||
|
db-database = dbUser;
|
||||||
|
# Web
|
||||||
|
web-template-base-dir = "${cfg.package}/share/web/template";
|
||||||
|
web-asset-base-dir = "${cfg.package}/share/web/assets";
|
||||||
|
# OIDC
|
||||||
|
oidc-enabled = true;
|
||||||
|
oidc-idp-name = "DTTH";
|
||||||
|
oidc-scopes = [ "openid" "email" "profile" ];
|
||||||
|
# HTTP Client
|
||||||
|
http-client.block-ips = [ "11.0.0.0/24" ];
|
||||||
|
# Advanced
|
||||||
|
advanced-rate-limit-requests = 0;
|
||||||
|
});
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.cloud.gotosocial = {
|
options.cloud.gotosocial = {
|
||||||
enable = mkEnableOption "Enable our local GtS server";
|
enable = mkEnableOption "Enable our local GtS server";
|
||||||
package = mkPackageOption pkgs "gotosocial" { };
|
package = mkPackageOption pkgs "gotosocial-bin" { };
|
||||||
host = mkOption {
|
host = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
description = "The GtS host";
|
description = "The GtS host";
|
||||||
|
@ -46,92 +63,56 @@ in
|
||||||
# Postgres
|
# Postgres
|
||||||
cloud.postgresql.databases = [ dbUser ];
|
cloud.postgresql.databases = [ dbUser ];
|
||||||
# Traefik
|
# Traefik
|
||||||
cloud.traefik.hosts =
|
cloud.traefik.hosts = { gotosocial = { inherit (cfg) host port; }; } //
|
||||||
{
|
(if cfg.accountDomain != cfg.host && cfg.accountDomain != "" then {
|
||||||
gotosocial = { inherit (cfg) host port; };
|
|
||||||
}
|
|
||||||
// (
|
|
||||||
if cfg.accountDomain != cfg.host && cfg.accountDomain != "" then
|
|
||||||
{
|
|
||||||
gotosocial-wellknown = {
|
gotosocial-wellknown = {
|
||||||
inherit (cfg) port;
|
inherit (cfg) port;
|
||||||
filter = "Host(`${cfg.accountDomain}`) && (PathPrefix(`/.well-known/webfinger`) || PathPrefix(`/.well-known/nodeinfo`) || PathPrefix(`/.well-known/host-meta`))";
|
filter = "Host(`${cfg.accountDomain}`) && (PathPrefix(`/.well-known/webfinger`) || PathPrefix(`/.well-known/nodeinfo`) || PathPrefix(`/.well-known/host-meta`))";
|
||||||
};
|
};
|
||||||
}
|
} else { });
|
||||||
else
|
|
||||||
{ }
|
|
||||||
);
|
|
||||||
# The service itself
|
# The service itself
|
||||||
services.gotosocial = {
|
systemd.services.gotosocial = {
|
||||||
enable = true;
|
after = [ "network.target" ];
|
||||||
package = cfg.package;
|
serviceConfig = {
|
||||||
environmentFile = cfg.envFile;
|
User = dbUser;
|
||||||
settings = {
|
Group = dbUser;
|
||||||
# General
|
ExecStart = "${cfg.package}/bin/gotosocial --config-path ${configFile} server start";
|
||||||
host = cfg.host;
|
EnvironmentFile = cfg.envFile;
|
||||||
account-domain = cfg.accountDomain;
|
# Sandboxing options to harden security
|
||||||
bind-address = "localhost";
|
# Details for these options: https://www.freedesktop.org/software/systemd/man/systemd.exec.html
|
||||||
port = cfg.port;
|
NoNewPrivileges = "yes";
|
||||||
# Instance
|
PrivateTmp = "yes";
|
||||||
instance-languages = [
|
PrivateDevices = "yes";
|
||||||
"en-ca"
|
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
|
||||||
"vi"
|
RestrictNamespaces = "yes";
|
||||||
|
RestrictRealtime = "yes";
|
||||||
|
DevicePolicy = "closed";
|
||||||
|
ProtectSystem = "full";
|
||||||
|
ProtectControlGroups = "yes";
|
||||||
|
ProtectKernelModules = "yes";
|
||||||
|
ProtectKernelTunables = "yes";
|
||||||
|
LockPersonality = "yes";
|
||||||
|
SystemCallFilter = "~@clock @debug @module @mount @obsolete @reboot @setuid @swap";
|
||||||
|
|
||||||
|
# Denying access to capabilities that should not be relevant
|
||||||
|
# Doc: https://man7.org/linux/man-pages/man7/capabilities.7.html
|
||||||
|
CapabilityBoundingSet = strings.concatStringsSep " " [
|
||||||
|
"CAP_RAWIO CAP_MKNOD"
|
||||||
|
"CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_AUDIT_WRITE"
|
||||||
|
"CAP_SYS_BOOT CAP_SYS_TIME CAP_SYS_MODULE CAP_SYS_PACCT"
|
||||||
|
"CAP_LEASE CAP_LINUX_IMMUTABLE CAP_IPC_LOCK"
|
||||||
|
"CAP_BLOCK_SUSPEND CAP_WAKE_ALARM"
|
||||||
|
"CAP_SYS_TTY_CONFIG"
|
||||||
|
"CAP_MAC_ADMIN CAP_MAC_OVERRIDE"
|
||||||
|
"CAP_NET_ADMIN CAP_NET_BROADCAST CAP_NET_RAW"
|
||||||
|
"CAP_SYS_ADMIN CAP_SYS_PTRACE CAP_SYSLOG "
|
||||||
];
|
];
|
||||||
# Accounts
|
# You might need this if you are running as non-root on a privileged port (below 1024)
|
||||||
accounts-registration-open = false;
|
#AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||||
accounts-allow-custom-css = true;
|
StateDirectory = "gotosocial";
|
||||||
# Database
|
WorkingDirectory = "/var/lib/gotosocial";
|
||||||
db-type = "postgres";
|
|
||||||
db-address = "/run/postgresql"; # Use socket
|
|
||||||
db-user = dbUser;
|
|
||||||
db-database = dbUser;
|
|
||||||
# Web
|
|
||||||
web-template-base-dir = "${cfg.package}/share/gotosocial/web/template";
|
|
||||||
web-asset-base-dir = "${cfg.package}/share/gotosocial/web/assets";
|
|
||||||
# Media
|
|
||||||
media-emoji-remote-max-size =
|
|
||||||
256 * 1024 # bytes
|
|
||||||
;
|
|
||||||
media-emoji-local-max-size =
|
|
||||||
256 * 1024 # bytes
|
|
||||||
;
|
|
||||||
media-remote-cache-days = 7;
|
|
||||||
media-cleanup-from = "00:00";
|
|
||||||
media-cleanup-every = "24h";
|
|
||||||
# OIDC
|
|
||||||
oidc-enabled = true;
|
|
||||||
oidc-idp-name = "DTTH";
|
|
||||||
oidc-scopes = [
|
|
||||||
"openid"
|
|
||||||
"email"
|
|
||||||
"profile"
|
|
||||||
];
|
|
||||||
# HTTP Client
|
|
||||||
http-client.block-ips = [ "11.0.0.0/24" ];
|
|
||||||
# Advanced
|
|
||||||
advanced-rate-limit-requests = 0;
|
|
||||||
# Storage
|
|
||||||
storage-backend = "local";
|
|
||||||
storage-local-base-path = "${storageLocation}/storage";
|
|
||||||
# instance-inject-mastodon-version = true;
|
|
||||||
};
|
};
|
||||||
};
|
wantedBy = [ "multi-user.target" ];
|
||||||
systemd.services.gotosocial.requires = mkAfter [
|
|
||||||
"postgresql.service"
|
|
||||||
"arion-authentik.service"
|
|
||||||
];
|
|
||||||
systemd.services.gotosocial.after = mkAfter [
|
|
||||||
"postgresql.service"
|
|
||||||
"arion-authentik.service"
|
|
||||||
];
|
|
||||||
systemd.services.gotosocial.unitConfig = {
|
|
||||||
RequiresMountsFor = [ storageLocation ];
|
|
||||||
ReadWritePaths = [ storageLocation ];
|
|
||||||
};
|
|
||||||
systemd.tmpfiles.settings."10-gotosocial".${storageLocation}.d = {
|
|
||||||
user = dbUser;
|
|
||||||
group = dbUser;
|
|
||||||
mode = "0700";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ config, pkgs, lib, ... }:
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
|
@ -243,12 +238,7 @@ in
|
||||||
# MTA-STS server
|
# MTA-STS server
|
||||||
services.nginx.enable = true;
|
services.nginx.enable = true;
|
||||||
services.nginx.virtualHosts.maddy-mta-sts = {
|
services.nginx.virtualHosts.maddy-mta-sts = {
|
||||||
listen = [
|
listen = [{ addr = "127.0.0.1"; port = mtaStsPort; }];
|
||||||
{
|
|
||||||
addr = "127.0.0.1";
|
|
||||||
port = mtaStsPort;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
root = mtaStsDir;
|
root = mtaStsDir;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -278,17 +268,12 @@ in
|
||||||
cloud.traefik.hosts.maddy-mta-sts = {
|
cloud.traefik.hosts.maddy-mta-sts = {
|
||||||
port = mtaStsPort;
|
port = mtaStsPort;
|
||||||
host = "mta-sts.nkagami.me";
|
host = "mta-sts.nkagami.me";
|
||||||
noCloudflare = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# maddy itself
|
# maddy itself
|
||||||
systemd.services."${name}" = {
|
systemd.services."${name}" = {
|
||||||
after = [
|
after = [ "network.target" "traefik-certs-dumper.service" ];
|
||||||
"network.target"
|
|
||||||
"traefik-certs-dumper.service"
|
|
||||||
];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
requires = [ "postgresql.service" ];
|
|
||||||
|
|
||||||
description = "maddy mail server";
|
description = "maddy mail server";
|
||||||
documentation = [
|
documentation = [
|
||||||
|
@ -340,6 +325,7 @@ in
|
||||||
KillMode = "mixed";
|
KillMode = "mixed";
|
||||||
KillSignal = "SIGTERM";
|
KillSignal = "SIGTERM";
|
||||||
|
|
||||||
|
|
||||||
# Required to bind on ports lower than 1024.
|
# Required to bind on ports lower than 1024.
|
||||||
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
|
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
|
||||||
CapabilityBoundingSet = "CAP_NET_BIND_SERVICE";
|
CapabilityBoundingSet = "CAP_NET_BIND_SERVICE";
|
||||||
|
|
788
modules/cloud/outline.nix
Normal file
788
modules/cloud/outline.nix
Normal file
|
@ -0,0 +1,788 @@
|
||||||
|
# Stub until 0.69.2 lands in stable
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
defaultUser = "outline";
|
||||||
|
cfg = config.cloud.services.outline;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# See here for a reference of all the options:
|
||||||
|
# https://github.com/outline/outline/blob/v0.67.0/.env.sample
|
||||||
|
# https://github.com/outline/outline/blob/v0.67.0/app.json
|
||||||
|
# https://github.com/outline/outline/blob/v0.67.0/server/env.ts
|
||||||
|
# https://github.com/outline/outline/blob/v0.67.0/shared/types.ts
|
||||||
|
# The order is kept the same here to make updating easier.
|
||||||
|
options.cloud.services.outline = {
|
||||||
|
enable = lib.mkEnableOption (lib.mdDoc "outline");
|
||||||
|
|
||||||
|
package = lib.mkOption {
|
||||||
|
default = pkgs.unstable.outline;
|
||||||
|
defaultText = lib.literalExpression "pkgs.unstable.outline";
|
||||||
|
type = lib.types.package;
|
||||||
|
example = lib.literalExpression ''
|
||||||
|
pkgs.outline.overrideAttrs (super: {
|
||||||
|
# Ignore the domain part in emails that come from OIDC. This is might
|
||||||
|
# be helpful if you want multiple users with different email providers
|
||||||
|
# to still land in the same team. Note that this effectively makes
|
||||||
|
# Outline a single-team instance.
|
||||||
|
patchPhase = ${"''"}
|
||||||
|
sed -i 's/const domain = parts\.length && parts\[1\];/const domain = "example.com";/g' server/routes/auth/providers/oidc.ts
|
||||||
|
${"''"};
|
||||||
|
})
|
||||||
|
'';
|
||||||
|
description = lib.mdDoc "Outline package to use.";
|
||||||
|
};
|
||||||
|
|
||||||
|
user = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = defaultUser;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
User under which the service should run. If this is the default value,
|
||||||
|
the user will be created, with the specified group as the primary
|
||||||
|
group.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
group = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = defaultUser;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Group under which the service should run. If this is the default value,
|
||||||
|
the group will be created.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
sequelizeArguments = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "";
|
||||||
|
example = "--env=production-ssl-disabled";
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Optional arguments to pass to `sequelize` calls.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
#
|
||||||
|
# Required options
|
||||||
|
#
|
||||||
|
|
||||||
|
secretKeyFile = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "/var/lib/outline/secret_key";
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
File path that contains the application secret key. It must be 32
|
||||||
|
bytes long and hex-encoded. If the file does not exist, a new key will
|
||||||
|
be generated and saved here.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
utilsSecretFile = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "/var/lib/outline/utils_secret";
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
File path that contains the utility secret key. If the file does not
|
||||||
|
exist, a new key will be generated and saved here.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
databaseUrl = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "local";
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
URI to use for the main PostgreSQL database. If this needs to include
|
||||||
|
credentials that shouldn't be world-readable in the Nix store, set an
|
||||||
|
environment file on the systemd service and override the
|
||||||
|
`DATABASE_URL` entry. Pass the string
|
||||||
|
`local` to setup a database on the local server.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
redisUrl = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "local";
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Connection to a redis server. If this needs to include credentials
|
||||||
|
that shouldn't be world-readable in the Nix store, set an environment
|
||||||
|
file on the systemd service and override the
|
||||||
|
`REDIS_URL` entry. Pass the string
|
||||||
|
`local` to setup a local Redis database.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
publicUrl = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "http://localhost:3000";
|
||||||
|
description = lib.mdDoc "The fully qualified, publicly accessible URL";
|
||||||
|
};
|
||||||
|
|
||||||
|
port = lib.mkOption {
|
||||||
|
type = lib.types.port;
|
||||||
|
default = 3000;
|
||||||
|
description = lib.mdDoc "Listening port.";
|
||||||
|
};
|
||||||
|
|
||||||
|
storage = lib.mkOption {
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
To support uploading of images for avatars and document attachments an
|
||||||
|
s3-compatible storage must be provided. AWS S3 is recommended for
|
||||||
|
redundancy however if you want to keep all file storage local an
|
||||||
|
alternative such as [minio](https://github.com/minio/minio)
|
||||||
|
can be used.
|
||||||
|
|
||||||
|
A more detailed guide on setting up S3 is available
|
||||||
|
[here](https://wiki.generaloutline.com/share/125de1cc-9ff6-424b-8415-0d58c809a40f).
|
||||||
|
'';
|
||||||
|
example = lib.literalExpression ''
|
||||||
|
{
|
||||||
|
accessKey = "...";
|
||||||
|
secretKeyFile = "/somewhere";
|
||||||
|
uploadBucketUrl = "https://minio.example.com";
|
||||||
|
uploadBucketName = "outline";
|
||||||
|
region = "us-east-1";
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
type = lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
accessKey = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc "S3 access key.";
|
||||||
|
};
|
||||||
|
secretKeyFile = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
description = lib.mdDoc "File path that contains the S3 secret key.";
|
||||||
|
};
|
||||||
|
region = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "xx-xxxx-x";
|
||||||
|
description = lib.mdDoc "AWS S3 region name.";
|
||||||
|
};
|
||||||
|
uploadBucketUrl = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
URL endpoint of an S3-compatible API where uploads should be
|
||||||
|
stored.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
uploadBucketName = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc "Name of the bucket where uploads should be stored.";
|
||||||
|
};
|
||||||
|
uploadMaxSize = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = 26214400;
|
||||||
|
description = lib.mdDoc "Maxmium file size for uploads.";
|
||||||
|
};
|
||||||
|
forcePathStyle = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = lib.mdDoc "Force S3 path style.";
|
||||||
|
};
|
||||||
|
acl = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "private";
|
||||||
|
description = lib.mdDoc "ACL setting.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#
|
||||||
|
# Authentication
|
||||||
|
#
|
||||||
|
|
||||||
|
slackAuthentication = lib.mkOption {
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
To configure Slack auth, you'll need to create an Application at
|
||||||
|
https://api.slack.com/apps
|
||||||
|
|
||||||
|
When configuring the Client ID, add a redirect URL under "OAuth & Permissions"
|
||||||
|
to `https://[publicUrl]/auth/slack.callback`.
|
||||||
|
'';
|
||||||
|
default = null;
|
||||||
|
type = lib.types.nullOr (lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
clientId = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc "Authentication key.";
|
||||||
|
};
|
||||||
|
secretFile = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc "File path containing the authentication secret.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
googleAuthentication = lib.mkOption {
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
To configure Google auth, you'll need to create an OAuth Client ID at
|
||||||
|
https://console.cloud.google.com/apis/credentials
|
||||||
|
|
||||||
|
When configuring the Client ID, add an Authorized redirect URI to
|
||||||
|
`https://[publicUrl]/auth/google.callback`.
|
||||||
|
'';
|
||||||
|
default = null;
|
||||||
|
type = lib.types.nullOr (lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
clientId = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc "Authentication client identifier.";
|
||||||
|
};
|
||||||
|
clientSecretFile = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc "File path containing the authentication secret.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
azureAuthentication = lib.mkOption {
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
To configure Microsoft/Azure auth, you'll need to create an OAuth
|
||||||
|
Client. See
|
||||||
|
[the guide](https://wiki.generaloutline.com/share/dfa77e56-d4d2-4b51-8ff8-84ea6608faa4)
|
||||||
|
for details on setting up your Azure App.
|
||||||
|
'';
|
||||||
|
default = null;
|
||||||
|
type = lib.types.nullOr (lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
clientId = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc "Authentication client identifier.";
|
||||||
|
};
|
||||||
|
clientSecretFile = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc "File path containing the authentication secret.";
|
||||||
|
};
|
||||||
|
resourceAppId = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc "Authentication application resource ID.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
oidcAuthentication = lib.mkOption {
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
To configure generic OIDC auth, you'll need some kind of identity
|
||||||
|
provider. See the documentation for whichever IdP you use to fill out
|
||||||
|
all the fields. The redirect URL is
|
||||||
|
`https://[publicUrl]/auth/oidc.callback`.
|
||||||
|
'';
|
||||||
|
default = null;
|
||||||
|
type = lib.types.nullOr (lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
clientId = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc "Authentication client identifier.";
|
||||||
|
};
|
||||||
|
clientSecretFile = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc "File path containing the authentication secret.";
|
||||||
|
};
|
||||||
|
authUrl = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc "OIDC authentication URL endpoint.";
|
||||||
|
};
|
||||||
|
tokenUrl = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc "OIDC token URL endpoint.";
|
||||||
|
};
|
||||||
|
userinfoUrl = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc "OIDC userinfo URL endpoint.";
|
||||||
|
};
|
||||||
|
usernameClaim = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Specify which claims to derive user information from. Supports any
|
||||||
|
valid JSON path with the JWT payload
|
||||||
|
'';
|
||||||
|
default = "preferred_username";
|
||||||
|
};
|
||||||
|
displayName = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc "Display name for OIDC authentication.";
|
||||||
|
default = "OpenID";
|
||||||
|
};
|
||||||
|
scopes = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
description = lib.mdDoc "OpenID authentication scopes.";
|
||||||
|
default = [ "openid" "profile" "email" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
#
|
||||||
|
# Optional configuration
|
||||||
|
#
|
||||||
|
|
||||||
|
sslKeyFile = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = null;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
File path that contains the Base64-encoded private key for HTTPS
|
||||||
|
termination. This is only required if you do not use an external reverse
|
||||||
|
proxy. See
|
||||||
|
[the documentation](https://wiki.generaloutline.com/share/dfa77e56-d4d2-4b51-8ff8-84ea6608faa4).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
sslCertFile = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = null;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
File path that contains the Base64-encoded certificate for HTTPS
|
||||||
|
termination. This is only required if you do not use an external reverse
|
||||||
|
proxy. See
|
||||||
|
[the documentation](https://wiki.generaloutline.com/share/dfa77e56-d4d2-4b51-8ff8-84ea6608faa4).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
cdnUrl = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "";
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
If using a Cloudfront/Cloudflare distribution or similar it can be set
|
||||||
|
using this option. This will cause paths to JavaScript files,
|
||||||
|
stylesheets and images to be updated to the hostname defined here. In
|
||||||
|
your CDN configuration the origin server should be set to public URL.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
forceHttps = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Auto-redirect to HTTPS in production. The default is
|
||||||
|
`true` but you may set this to `false`
|
||||||
|
if you can be sure that SSL is terminated at an external loadbalancer.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
enableUpdateCheck = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Have the installation check for updates by sending anonymized statistics
|
||||||
|
to the maintainers.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
concurrency = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = 1;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
How many processes should be spawned. For a rough estimate, divide your
|
||||||
|
server's available memory by 512.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
maximumImportSize = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = 5120000;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
The maximum size of document imports. Overriding this could be required
|
||||||
|
if you have especially large Word documents with embedded imagery.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
debugOutput = lib.mkOption {
|
||||||
|
type = lib.types.nullOr (lib.types.enum [ "http" ]);
|
||||||
|
default = null;
|
||||||
|
description = lib.mdDoc "Set this to `http` log HTTP requests.";
|
||||||
|
};
|
||||||
|
|
||||||
|
slackIntegration = lib.mkOption {
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
For a complete Slack integration with search and posting to channels
|
||||||
|
this configuration is also needed. See here for details:
|
||||||
|
https://wiki.generaloutline.com/share/be25efd1-b3ef-4450-b8e5-c4a4fc11e02a
|
||||||
|
'';
|
||||||
|
default = null;
|
||||||
|
type = lib.types.nullOr (lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
verificationTokenFile = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc "File path containing the verification token.";
|
||||||
|
};
|
||||||
|
appId = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc "Application ID.";
|
||||||
|
};
|
||||||
|
messageActions = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = lib.mdDoc "Whether to enable message actions.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
googleAnalyticsId = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = null;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Optionally enable Google Analytics to track page views in the knowledge
|
||||||
|
base.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
sentryDsn = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = null;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Optionally enable [Sentry](https://sentry.io/) to
|
||||||
|
track errors and performance.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
sentryTunnel = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = null;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Optionally add a
|
||||||
|
[Sentry proxy tunnel](https://docs.sentry.io/platforms/javascript/troubleshooting/#using-the-tunnel-option)
|
||||||
|
for bypassing ad blockers in the UI.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
logo = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = null;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Custom logo displayed on the authentication screen. This will be scaled
|
||||||
|
to a height of 60px.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
smtp = lib.mkOption {
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
To support sending outgoing transactional emails such as
|
||||||
|
"document updated" or "you've been invited" you'll need to provide
|
||||||
|
authentication for an SMTP server.
|
||||||
|
'';
|
||||||
|
default = null;
|
||||||
|
type = lib.types.nullOr (lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
host = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc "Host name or IP address of the SMTP server.";
|
||||||
|
};
|
||||||
|
port = lib.mkOption {
|
||||||
|
type = lib.types.port;
|
||||||
|
description = lib.mdDoc "TCP port of the SMTP server.";
|
||||||
|
};
|
||||||
|
username = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc "Username to authenticate with.";
|
||||||
|
};
|
||||||
|
passwordFile = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
File path containing the password to authenticate with.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
fromEmail = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc "Sender email in outgoing mail.";
|
||||||
|
};
|
||||||
|
replyEmail = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = lib.mdDoc "Reply address in outgoing mail.";
|
||||||
|
};
|
||||||
|
tlsCiphers = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "";
|
||||||
|
description = lib.mdDoc "Override SMTP cipher configuration.";
|
||||||
|
};
|
||||||
|
secure = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = lib.mdDoc "Use a secure SMTP connection.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
defaultLanguage = lib.mkOption {
|
||||||
|
type = lib.types.enum [
|
||||||
|
"da_DK"
|
||||||
|
"de_DE"
|
||||||
|
"en_US"
|
||||||
|
"es_ES"
|
||||||
|
"fa_IR"
|
||||||
|
"fr_FR"
|
||||||
|
"it_IT"
|
||||||
|
"ja_JP"
|
||||||
|
"ko_KR"
|
||||||
|
"nl_NL"
|
||||||
|
"pl_PL"
|
||||||
|
"pt_BR"
|
||||||
|
"pt_PT"
|
||||||
|
"ru_RU"
|
||||||
|
"sv_SE"
|
||||||
|
"th_TH"
|
||||||
|
"vi_VN"
|
||||||
|
"zh_CN"
|
||||||
|
"zh_TW"
|
||||||
|
];
|
||||||
|
default = "en_US";
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
The default interface language. See
|
||||||
|
[translate.getoutline.com](https://translate.getoutline.com/)
|
||||||
|
for a list of available language codes and their rough percentage
|
||||||
|
translated.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
rateLimiter.enable = lib.mkEnableOption (lib.mdDoc "rate limiter for the application web server");
|
||||||
|
rateLimiter.requests = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = 5000;
|
||||||
|
description = lib.mdDoc "Maximum number of requests in a throttling window.";
|
||||||
|
};
|
||||||
|
rateLimiter.durationWindow = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = 60;
|
||||||
|
description = lib.mdDoc "Length of a throttling window.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
{ assertion = pkgs.outline.version == "0.68.1"; message = "Please use the nixpkgs module for outline > 0.68.1"; }
|
||||||
|
];
|
||||||
|
users.users = lib.optionalAttrs (cfg.user == defaultUser) {
|
||||||
|
${defaultUser} = {
|
||||||
|
isSystemUser = true;
|
||||||
|
group = cfg.group;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
users.groups = lib.optionalAttrs (cfg.group == defaultUser) {
|
||||||
|
${defaultUser} = { };
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"f ${cfg.secretKeyFile} 0600 ${cfg.user} ${cfg.group} -"
|
||||||
|
"f ${cfg.utilsSecretFile} 0600 ${cfg.user} ${cfg.group} -"
|
||||||
|
"f ${cfg.storage.secretKeyFile} 0600 ${cfg.user} ${cfg.group} -"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.postgresql = lib.mkIf (cfg.databaseUrl == "local") {
|
||||||
|
enable = true;
|
||||||
|
ensureUsers = [{
|
||||||
|
name = "outline";
|
||||||
|
ensurePermissions."DATABASE outline" = "ALL PRIVILEGES";
|
||||||
|
}];
|
||||||
|
ensureDatabases = [ "outline" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.redis.servers.outline = lib.mkIf (cfg.redisUrl == "local") {
|
||||||
|
enable = true;
|
||||||
|
user = config.services.outline.user;
|
||||||
|
port = 0; # Disable the TCP listener
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.outline =
|
||||||
|
let
|
||||||
|
localRedisUrl = "redis+unix:///run/redis-outline/redis.sock";
|
||||||
|
localPostgresqlUrl = "postgres://localhost/outline?host=/run/postgresql";
|
||||||
|
|
||||||
|
# Create an outline-sequalize wrapper (a wrapper around the wrapper) that
|
||||||
|
# has the config file's path baked in. This is necessary because there is
|
||||||
|
# at least two occurrences of outline calling this from its own code.
|
||||||
|
sequelize = pkgs.writeShellScriptBin "outline-sequelize" ''
|
||||||
|
exec ${cfg.package}/bin/outline-sequelize \
|
||||||
|
--config $RUNTIME_DIRECTORY/database.json \
|
||||||
|
${cfg.sequelizeArguments} \
|
||||||
|
"$@"
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
description = "Outline wiki and knowledge base";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "networking.target" ]
|
||||||
|
++ lib.optional (cfg.databaseUrl == "local") "postgresql.service"
|
||||||
|
++ lib.optional (cfg.redisUrl == "local") "redis-outline.service";
|
||||||
|
requires = lib.optional (cfg.databaseUrl == "local") "postgresql.service"
|
||||||
|
++ lib.optional (cfg.redisUrl == "local") "redis-outline.service";
|
||||||
|
path = [
|
||||||
|
pkgs.openssl # Required by the preStart script
|
||||||
|
sequelize
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
environment = lib.mkMerge [
|
||||||
|
{
|
||||||
|
NODE_ENV = "production";
|
||||||
|
|
||||||
|
REDIS_URL = if cfg.redisUrl == "local" then localRedisUrl else cfg.redisUrl;
|
||||||
|
URL = cfg.publicUrl;
|
||||||
|
PORT = builtins.toString cfg.port;
|
||||||
|
|
||||||
|
AWS_ACCESS_KEY_ID = cfg.storage.accessKey;
|
||||||
|
AWS_REGION = cfg.storage.region;
|
||||||
|
AWS_S3_UPLOAD_BUCKET_URL = cfg.storage.uploadBucketUrl;
|
||||||
|
AWS_S3_UPLOAD_BUCKET_NAME = cfg.storage.uploadBucketName;
|
||||||
|
AWS_S3_UPLOAD_MAX_SIZE = builtins.toString cfg.storage.uploadMaxSize;
|
||||||
|
AWS_S3_FORCE_PATH_STYLE = builtins.toString cfg.storage.forcePathStyle;
|
||||||
|
AWS_S3_ACL = cfg.storage.acl;
|
||||||
|
|
||||||
|
CDN_URL = cfg.cdnUrl;
|
||||||
|
FORCE_HTTPS = builtins.toString cfg.forceHttps;
|
||||||
|
ENABLE_UPDATES = builtins.toString cfg.enableUpdateCheck;
|
||||||
|
WEB_CONCURRENCY = builtins.toString cfg.concurrency;
|
||||||
|
MAXIMUM_IMPORT_SIZE = builtins.toString cfg.maximumImportSize;
|
||||||
|
DEBUG = cfg.debugOutput;
|
||||||
|
GOOGLE_ANALYTICS_ID = lib.optionalString (cfg.googleAnalyticsId != null) cfg.googleAnalyticsId;
|
||||||
|
SENTRY_DSN = lib.optionalString (cfg.sentryDsn != null) cfg.sentryDsn;
|
||||||
|
SENTRY_TUNNEL = lib.optionalString (cfg.sentryTunnel != null) cfg.sentryTunnel;
|
||||||
|
TEAM_LOGO = lib.optionalString (cfg.logo != null) cfg.logo;
|
||||||
|
DEFAULT_LANGUAGE = cfg.defaultLanguage;
|
||||||
|
|
||||||
|
RATE_LIMITER_ENABLED = builtins.toString cfg.rateLimiter.enable;
|
||||||
|
RATE_LIMITER_REQUESTS = builtins.toString cfg.rateLimiter.requests;
|
||||||
|
RATE_LIMITER_DURATION_WINDOW = builtins.toString cfg.rateLimiter.durationWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
(lib.mkIf (cfg.slackAuthentication != null) {
|
||||||
|
SLACK_CLIENT_ID = cfg.slackAuthentication.clientId;
|
||||||
|
})
|
||||||
|
|
||||||
|
(lib.mkIf (cfg.googleAuthentication != null) {
|
||||||
|
GOOGLE_CLIENT_ID = cfg.googleAuthentication.clientId;
|
||||||
|
})
|
||||||
|
|
||||||
|
(lib.mkIf (cfg.azureAuthentication != null) {
|
||||||
|
AZURE_CLIENT_ID = cfg.azureAuthentication.clientId;
|
||||||
|
AZURE_RESOURCE_APP_ID = cfg.azureAuthentication.resourceAppId;
|
||||||
|
})
|
||||||
|
|
||||||
|
(lib.mkIf (cfg.oidcAuthentication != null) {
|
||||||
|
OIDC_CLIENT_ID = cfg.oidcAuthentication.clientId;
|
||||||
|
OIDC_AUTH_URI = cfg.oidcAuthentication.authUrl;
|
||||||
|
OIDC_TOKEN_URI = cfg.oidcAuthentication.tokenUrl;
|
||||||
|
OIDC_USERINFO_URI = cfg.oidcAuthentication.userinfoUrl;
|
||||||
|
OIDC_USERNAME_CLAIM = cfg.oidcAuthentication.usernameClaim;
|
||||||
|
OIDC_DISPLAY_NAME = cfg.oidcAuthentication.displayName;
|
||||||
|
OIDC_SCOPES = lib.concatStringsSep " " cfg.oidcAuthentication.scopes;
|
||||||
|
})
|
||||||
|
|
||||||
|
(lib.mkIf (cfg.slackIntegration != null) {
|
||||||
|
SLACK_APP_ID = cfg.slackIntegration.appId;
|
||||||
|
SLACK_MESSAGE_ACTIONS = builtins.toString cfg.slackIntegration.messageActions;
|
||||||
|
})
|
||||||
|
|
||||||
|
(lib.mkIf (cfg.smtp != null) {
|
||||||
|
SMTP_HOST = cfg.smtp.host;
|
||||||
|
SMTP_PORT = builtins.toString cfg.smtp.port;
|
||||||
|
SMTP_USERNAME = cfg.smtp.username;
|
||||||
|
SMTP_FROM_EMAIL = cfg.smtp.fromEmail;
|
||||||
|
SMTP_REPLY_EMAIL = cfg.smtp.replyEmail;
|
||||||
|
SMTP_TLS_CIPHERS = cfg.smtp.tlsCiphers;
|
||||||
|
SMTP_SECURE = builtins.toString cfg.smtp.secure;
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
preStart = ''
|
||||||
|
if [ ! -s ${lib.escapeShellArg cfg.secretKeyFile} ]; then
|
||||||
|
openssl rand -hex 32 > ${lib.escapeShellArg cfg.secretKeyFile}
|
||||||
|
fi
|
||||||
|
if [ ! -s ${lib.escapeShellArg cfg.utilsSecretFile} ]; then
|
||||||
|
openssl rand -hex 32 > ${lib.escapeShellArg cfg.utilsSecretFile}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# The config file is required for the sequelize CLI.
|
||||||
|
${if (cfg.databaseUrl == "local") then ''
|
||||||
|
cat <<EOF > $RUNTIME_DIRECTORY/database.json
|
||||||
|
{
|
||||||
|
"production-ssl-disabled": {
|
||||||
|
"host": "/run/postgresql",
|
||||||
|
"username": null,
|
||||||
|
"password": null,
|
||||||
|
"dialect": "postgres"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
'' else ''
|
||||||
|
cat <<EOF > $RUNTIME_DIRECTORY/database.json
|
||||||
|
{
|
||||||
|
"production": {
|
||||||
|
"use_env_variable": "DATABASE_URL",
|
||||||
|
"dialect": "postgres",
|
||||||
|
"dialectOptions": {
|
||||||
|
"ssl": {
|
||||||
|
"rejectUnauthorized": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"production-ssl-disabled": {
|
||||||
|
"use_env_variable": "DATABASE_URL",
|
||||||
|
"dialect": "postgres"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
''}
|
||||||
|
'';
|
||||||
|
|
||||||
|
script = ''
|
||||||
|
export SECRET_KEY="$(head -n1 ${lib.escapeShellArg cfg.secretKeyFile})"
|
||||||
|
export UTILS_SECRET="$(head -n1 ${lib.escapeShellArg cfg.utilsSecretFile})"
|
||||||
|
export AWS_SECRET_ACCESS_KEY="$(head -n1 ${lib.escapeShellArg cfg.storage.secretKeyFile})"
|
||||||
|
${lib.optionalString (cfg.slackAuthentication != null) ''
|
||||||
|
export SLACK_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.slackAuthentication.secretFile})"
|
||||||
|
''}
|
||||||
|
${lib.optionalString (cfg.googleAuthentication != null) ''
|
||||||
|
export GOOGLE_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.googleAuthentication.clientSecretFile})"
|
||||||
|
''}
|
||||||
|
${lib.optionalString (cfg.azureAuthentication != null) ''
|
||||||
|
export AZURE_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.azureAuthentication.clientSecretFile})"
|
||||||
|
''}
|
||||||
|
${lib.optionalString (cfg.oidcAuthentication != null) ''
|
||||||
|
export OIDC_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.oidcAuthentication.clientSecretFile})"
|
||||||
|
''}
|
||||||
|
${lib.optionalString (cfg.sslKeyFile != null) ''
|
||||||
|
export SSL_KEY="$(head -n1 ${lib.escapeShellArg cfg.sslKeyFile})"
|
||||||
|
''}
|
||||||
|
${lib.optionalString (cfg.sslCertFile != null) ''
|
||||||
|
export SSL_CERT="$(head -n1 ${lib.escapeShellArg cfg.sslCertFile})"
|
||||||
|
''}
|
||||||
|
${lib.optionalString (cfg.slackIntegration != null) ''
|
||||||
|
export SLACK_VERIFICATION_TOKEN="$(head -n1 ${lib.escapeShellArg cfg.slackIntegration.verificationTokenFile})"
|
||||||
|
''}
|
||||||
|
${lib.optionalString (cfg.smtp != null) ''
|
||||||
|
export SMTP_PASSWORD="$(head -n1 ${lib.escapeShellArg cfg.smtp.passwordFile})"
|
||||||
|
''}
|
||||||
|
|
||||||
|
${if (cfg.databaseUrl == "local") then ''
|
||||||
|
export DATABASE_URL=${lib.escapeShellArg localPostgresqlUrl}
|
||||||
|
export PGSSLMODE=disable
|
||||||
|
'' else ''
|
||||||
|
export DATABASE_URL=${lib.escapeShellArg cfg.databaseUrl}
|
||||||
|
''}
|
||||||
|
|
||||||
|
${cfg.package}/bin/outline-server
|
||||||
|
'';
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
User = cfg.user;
|
||||||
|
Group = cfg.group;
|
||||||
|
Restart = "always";
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
PrivateHome = true;
|
||||||
|
PrivateTmp = true;
|
||||||
|
UMask = "0007";
|
||||||
|
|
||||||
|
StateDirectory = "outline";
|
||||||
|
StateDirectoryMode = "0750";
|
||||||
|
RuntimeDirectory = "outline";
|
||||||
|
RuntimeDirectoryMode = "0750";
|
||||||
|
# This working directory is required to find stuff like the set of
|
||||||
|
# onboarding files:
|
||||||
|
WorkingDirectory = "${cfg.package}/share/outline";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ index d218dbc1f..24c0505e3 100644
|
||||||
/**
|
/**
|
||||||
* The product name
|
* The product name
|
||||||
*/
|
*/
|
||||||
@Public
|
|
||||||
- public APP_NAME = "Outline";
|
- public APP_NAME = "Outline";
|
||||||
+ public APP_NAME = "DTTH Wiki";
|
+ public APP_NAME = "DTTH Wiki";
|
||||||
|
|
||||||
|
|
|
@ -1,178 +0,0 @@
|
||||||
diff --git a/.env.sample b/.env.sample
|
|
||||||
index 51046501d..6daf60347 100644
|
|
||||||
--- a/.env.sample
|
|
||||||
+++ b/.env.sample
|
|
||||||
@@ -66,6 +66,8 @@ AWS_S3_UPLOAD_BUCKET_URL=http://s3:4569
|
|
||||||
AWS_S3_UPLOAD_BUCKET_NAME=bucket_name_here
|
|
||||||
AWS_S3_FORCE_PATH_STYLE=true
|
|
||||||
AWS_S3_ACL=private
|
|
||||||
+AWS_S3_R2=true
|
|
||||||
+AWS_S3_R2_PUBLIC_URL=http://s3:4569
|
|
||||||
|
|
||||||
# –––––––––––––– AUTHENTICATION ––––––––––––––
|
|
||||||
|
|
||||||
diff --git a/app/utils/files.ts b/app/utils/files.ts
|
|
||||||
index 16b66a2c4..c56ffd2b2 100644
|
|
||||||
--- a/app/utils/files.ts
|
|
||||||
+++ b/app/utils/files.ts
|
|
||||||
@@ -88,8 +88,13 @@ export const uploadFile = async (
|
|
||||||
xhr.addEventListener("loadend", () => {
|
|
||||||
resolve(xhr.readyState === 4 && xhr.status >= 200 && xhr.status < 400);
|
|
||||||
});
|
|
||||||
- xhr.open("POST", data.uploadUrl, true);
|
|
||||||
- xhr.send(formData);
|
|
||||||
+ xhr.open(data.method, data.uploadUrl, true);
|
|
||||||
+ xhr.setRequestHeader("Content-Type", file.type);
|
|
||||||
+ if (data.method === "POST") {
|
|
||||||
+ xhr.send(formData);
|
|
||||||
+ } else {
|
|
||||||
+ xhr.send(file);
|
|
||||||
+ }
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!success) {
|
|
||||||
diff --git a/server/env.ts b/server/env.ts
|
|
||||||
index 5b420f2e1..4ea1e8d3c 100644
|
|
||||||
--- a/server/env.ts
|
|
||||||
+++ b/server/env.ts
|
|
||||||
@@ -519,6 +519,14 @@ export class Environment {
|
|
||||||
environment.AWS_S3_UPLOAD_BUCKET_NAME
|
|
||||||
);
|
|
||||||
|
|
||||||
+ @IsOptional()
|
|
||||||
+ public AWS_S3_R2 = this.toBoolean(environment.AWS_S3_R2 ?? "false");
|
|
||||||
+
|
|
||||||
+ @IsOptional()
|
|
||||||
+ public AWS_S3_R2_PUBLIC_URL = this.toOptionalString(
|
|
||||||
+ environment.AWS_S3_R2_PUBLIC_URL
|
|
||||||
+ );
|
|
||||||
+
|
|
||||||
/**
|
|
||||||
* Whether to force path style URLs for S3 objects, this is required for some
|
|
||||||
* S3-compatible storage providers.
|
|
||||||
diff --git a/server/routes/api/attachments/attachments.ts b/server/routes/api/attachments/attachments.ts
|
|
||||||
index d2288c215..72251962c 100644
|
|
||||||
--- a/server/routes/api/attachments/attachments.ts
|
|
||||||
+++ b/server/routes/api/attachments/attachments.ts
|
|
||||||
@@ -3,6 +3,7 @@ import { v4 as uuidv4 } from "uuid";
|
|
||||||
import { AttachmentPreset } from "@shared/types";
|
|
||||||
import { bytesToHumanReadable, getFileNameFromUrl } from "@shared/utils/files";
|
|
||||||
import { AttachmentValidation } from "@shared/validations";
|
|
||||||
+import env from "@server/env";
|
|
||||||
import { createContext } from "@server/context";
|
|
||||||
import {
|
|
||||||
AuthorizationError,
|
|
||||||
@@ -83,16 +84,30 @@ router.post(
|
|
||||||
userId: user.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
- const presignedPost = await FileStorage.getPresignedPost(
|
|
||||||
- key,
|
|
||||||
- acl,
|
|
||||||
- maxUploadSize,
|
|
||||||
- contentType
|
|
||||||
- );
|
|
||||||
+ let uploadUrl;
|
|
||||||
+ let method;
|
|
||||||
+ let presignedPost = {
|
|
||||||
+ fields: {},
|
|
||||||
+ };
|
|
||||||
+ if (env.AWS_S3_R2) {
|
|
||||||
+ uploadUrl = await FileStorage.getPresignedPut(key);
|
|
||||||
+ method = "PUT";
|
|
||||||
+ } else {
|
|
||||||
+ uploadUrl = FileStorage.getUploadUrl();
|
|
||||||
+ method = "POST";
|
|
||||||
+
|
|
||||||
+ presignedPost = await FileStorage.getPresignedPost(
|
|
||||||
+ key,
|
|
||||||
+ acl,
|
|
||||||
+ maxUploadSize,
|
|
||||||
+ contentType
|
|
||||||
+ );
|
|
||||||
+ }
|
|
||||||
|
|
||||||
ctx.body = {
|
|
||||||
data: {
|
|
||||||
- uploadUrl: FileStorage.getUploadUrl(),
|
|
||||||
+ uploadUrl,
|
|
||||||
+ method,
|
|
||||||
form: {
|
|
||||||
"Cache-Control": "max-age=31557600",
|
|
||||||
"Content-Type": contentType,
|
|
||||||
diff --git a/server/storage/files/BaseStorage.ts b/server/storage/files/BaseStorage.ts
|
|
||||||
index 339262cc5..03f658271 100644
|
|
||||||
--- a/server/storage/files/BaseStorage.ts
|
|
||||||
+++ b/server/storage/files/BaseStorage.ts
|
|
||||||
@@ -26,6 +26,8 @@ export default abstract class BaseStorage {
|
|
||||||
contentType: string
|
|
||||||
): Promise<Partial<PresignedPost>>;
|
|
||||||
|
|
||||||
+ public abstract getPresignedPut(key: string): Promise<string>;
|
|
||||||
+
|
|
||||||
/**
|
|
||||||
* Returns a promise that resolves with a stream for reading a file from the storage provider.
|
|
||||||
*
|
|
||||||
diff --git a/server/storage/files/LocalStorage.ts b/server/storage/files/LocalStorage.ts
|
|
||||||
index 83cf98c50..324e60dd9 100644
|
|
||||||
--- a/server/storage/files/LocalStorage.ts
|
|
||||||
+++ b/server/storage/files/LocalStorage.ts
|
|
||||||
@@ -30,6 +30,10 @@ export default class LocalStorage extends BaseStorage {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
+ public async getPresignedPut(key: string) {
|
|
||||||
+ return this.getUrlForKey(key);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
public getUploadUrl() {
|
|
||||||
return "/api/files.create";
|
|
||||||
}
|
|
||||||
diff --git a/server/storage/files/S3Storage.ts b/server/storage/files/S3Storage.ts
|
|
||||||
index beba39ab2..4f0fe09a9 100644
|
|
||||||
--- a/server/storage/files/S3Storage.ts
|
|
||||||
+++ b/server/storage/files/S3Storage.ts
|
|
||||||
@@ -4,6 +4,7 @@ import {
|
|
||||||
S3Client,
|
|
||||||
DeleteObjectCommand,
|
|
||||||
GetObjectCommand,
|
|
||||||
+ PutObjectCommand,
|
|
||||||
ObjectCannedACL,
|
|
||||||
} from "@aws-sdk/client-s3";
|
|
||||||
import { Upload } from "@aws-sdk/lib-storage";
|
|
||||||
@@ -58,6 +59,16 @@ export default class S3Storage extends BaseStorage {
|
|
||||||
return createPresignedPost(this.client, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ public async getPresignedPut(key: string) {
|
|
||||||
+ const params = {
|
|
||||||
+ Bucket: env.AWS_S3_UPLOAD_BUCKET_NAME,
|
|
||||||
+ Key: key,
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ const command = new PutObjectCommand(params);
|
|
||||||
+ return await getSignedUrl(this.client, command, { expiresIn: 3600 });
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
private getPublicEndpoint(isServerUpload?: boolean) {
|
|
||||||
if (env.AWS_S3_ACCELERATE_URL) {
|
|
||||||
return env.AWS_S3_ACCELERATE_URL;
|
|
||||||
@@ -137,10 +148,17 @@ export default class S3Storage extends BaseStorage {
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ public getR2ObjectUrl = async (key: string) =>
|
|
||||||
+ env.AWS_S3_R2_PUBLIC_URL + "/" + key;
|
|
||||||
+
|
|
||||||
public getSignedUrl = async (
|
|
||||||
key: string,
|
|
||||||
expiresIn = S3Storage.defaultSignedUrlExpires
|
|
||||||
) => {
|
|
||||||
+ if (env.AWS_S3_R2) {
|
|
||||||
+ return this.getR2ObjectUrl(key);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
const isDocker = env.AWS_S3_UPLOAD_BUCKET_URL.match(/http:\/\/s3:/);
|
|
||||||
const params = {
|
|
||||||
Bucket: this.getBucket(),
|
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
|
@ -14,7 +9,9 @@ let
|
||||||
# to that database.
|
# to that database.
|
||||||
userFromDatabase = databaseName: {
|
userFromDatabase = databaseName: {
|
||||||
name = databaseName;
|
name = databaseName;
|
||||||
ensureDBOwnership = true;
|
ensurePermissions = {
|
||||||
|
"DATABASE \"${databaseName}\"" = "ALL PRIVILEGES";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
@ -35,14 +32,10 @@ in
|
||||||
|
|
||||||
ensureDatabases = cfg.databases;
|
ensureDatabases = cfg.databases;
|
||||||
|
|
||||||
ensureUsers = (map userFromDatabase cfg.databases);
|
ensureUsers = (map userFromDatabase cfg.databases) ++ [{
|
||||||
|
name = "root";
|
||||||
dataDir = "/mnt/data/postgresql/${config.services.postgresql.package.psqlSchema}";
|
ensurePermissions = { "ALL TABLES IN SCHEMA public" = "ALL PRIVILEGES"; };
|
||||||
};
|
}];
|
||||||
|
|
||||||
config.systemd.services.postgresql.serviceConfig = {
|
|
||||||
StateDirectory = "postgresql postgresql ${config.services.postgresql.dataDir}";
|
|
||||||
StateDirectoryMode = "0750";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Backup settings
|
# Backup settings
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ pkgs, lib, config, ... }:
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
|
@ -14,28 +9,24 @@ let
|
||||||
};
|
};
|
||||||
|
|
||||||
# Copied from traefik.nix
|
# Copied from traefik.nix
|
||||||
jsonValue =
|
jsonValue = with types;
|
||||||
with types;
|
|
||||||
let
|
let
|
||||||
valueType =
|
valueType = nullOr
|
||||||
nullOr (oneOf [
|
(oneOf [
|
||||||
bool
|
bool
|
||||||
int
|
int
|
||||||
float
|
float
|
||||||
str
|
str
|
||||||
(lazyAttrsOf valueType)
|
(lazyAttrsOf valueType)
|
||||||
(listOf valueType)
|
(listOf valueType)
|
||||||
])
|
]) // {
|
||||||
// {
|
|
||||||
description = "JSON value";
|
description = "JSON value";
|
||||||
emptyValue.value = { };
|
emptyValue.value = { };
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
valueType;
|
valueType;
|
||||||
|
|
||||||
hostType =
|
hostType = with types; submodule {
|
||||||
with types;
|
|
||||||
submodule {
|
|
||||||
options = {
|
options = {
|
||||||
host = mkOption {
|
host = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
|
@ -61,14 +52,7 @@ let
|
||||||
description = "The port that the service is listening on";
|
description = "The port that the service is listening on";
|
||||||
};
|
};
|
||||||
entrypoints = mkOption {
|
entrypoints = mkOption {
|
||||||
type = listOf (enum [
|
type = listOf (enum [ "http" "https" "smtp-submission" "smtp-submission-ssl" "imap" "wireguard" ]);
|
||||||
"http"
|
|
||||||
"https"
|
|
||||||
"smtp-submission"
|
|
||||||
"smtp-submission-ssl"
|
|
||||||
"imap"
|
|
||||||
"wireguard"
|
|
||||||
]);
|
|
||||||
default = [ "https" ];
|
default = [ "https" ];
|
||||||
description = "The entrypoints that will serve the host";
|
description = "The entrypoints that will serve the host";
|
||||||
};
|
};
|
||||||
|
@ -78,11 +62,7 @@ let
|
||||||
description = "The middlewares to be used with the host.";
|
description = "The middlewares to be used with the host.";
|
||||||
};
|
};
|
||||||
protocol = mkOption {
|
protocol = mkOption {
|
||||||
type = enum [
|
type = enum [ "http" "tcp" "udp" ];
|
||||||
"http"
|
|
||||||
"tcp"
|
|
||||||
"udp"
|
|
||||||
];
|
|
||||||
default = "http";
|
default = "http";
|
||||||
description = "The protocol of the router and service";
|
description = "The protocol of the router and service";
|
||||||
};
|
};
|
||||||
|
@ -100,83 +80,55 @@ let
|
||||||
};
|
};
|
||||||
|
|
||||||
# Returns the filter given a host configuration
|
# Returns the filter given a host configuration
|
||||||
filterOfHost =
|
filterOfHost = host:
|
||||||
host:
|
|
||||||
let
|
let
|
||||||
hostFilter = if host.protocol == "http" then "Host" else "HostSNI";
|
hostFilter = if host.protocol == "http" then "Host" else "HostSNI";
|
||||||
in
|
in
|
||||||
if host.filter != null then
|
if host.filter != null then host.filter
|
||||||
host.filter
|
else if host.path == null then "${hostFilter}(`${host.host}`)"
|
||||||
else if host.path == null then
|
else "${hostFilter}(`${host.host}`) && Path(`${host.path}`)";
|
||||||
"${hostFilter}(`${host.host}`)"
|
|
||||||
else
|
|
||||||
"${hostFilter}(`${host.host}`) && Path(`${host.path}`)";
|
|
||||||
|
|
||||||
# Turns a host configuration into dynamic traefik configuration
|
# Turns a host configuration into dynamic traefik configuration
|
||||||
hostToConfig = name: host: {
|
hostToConfig = name: host: {
|
||||||
"${host.protocol}" =
|
"${host.protocol}" = {
|
||||||
{
|
routers."${name}-router" = (if (host.protocol != "udp") then {
|
||||||
routers."${name}-router" =
|
|
||||||
(
|
|
||||||
if (host.protocol != "udp") then
|
|
||||||
{
|
|
||||||
rule = filterOfHost host;
|
rule = filterOfHost host;
|
||||||
tls =
|
tls = { certResolver = "le"; }
|
||||||
{
|
// (if host.protocol == "tcp" then { passthrough = if (host ? tlsPassthrough) then host.tlsPassthrough else true; } else { })
|
||||||
certResolver = "le";
|
|
||||||
}
|
|
||||||
// (
|
|
||||||
if host.protocol == "tcp" then
|
|
||||||
{ passthrough = if (host ? tlsPassthrough) then host.tlsPassthrough else true; }
|
|
||||||
else
|
|
||||||
{ }
|
|
||||||
)
|
|
||||||
// (if host.noCloudflare then tlsNoCloudflare else { });
|
// (if host.noCloudflare then tlsNoCloudflare else { });
|
||||||
}
|
} else { }) // {
|
||||||
else
|
|
||||||
{ }
|
|
||||||
)
|
|
||||||
// {
|
|
||||||
entryPoints = host.entrypoints;
|
entryPoints = host.entrypoints;
|
||||||
service = "${name}-service";
|
service = "${name}-service";
|
||||||
}
|
} // (
|
||||||
// (
|
|
||||||
if host.protocol == "http" then
|
if host.protocol == "http" then
|
||||||
{ middlewares = lists.imap0 (id: m: "${name}-middleware-${toString id}") host.middlewares; }
|
{ middlewares = lists.imap0 (id: m: "${name}-middleware-${toString id}") host.middlewares; }
|
||||||
else if host.middlewares == [ ] then
|
else if host.middlewares == [ ] then
|
||||||
{ }
|
{ }
|
||||||
else
|
else abort "Cannot have middlewares on non-http routers"
|
||||||
abort "Cannot have middlewares on non-http routers"
|
|
||||||
);
|
);
|
||||||
services."${name}-service".loadBalancer.servers = [
|
services."${name}-service".loadBalancer.servers = [
|
||||||
(
|
(
|
||||||
let
|
let
|
||||||
localhost =
|
localhost =
|
||||||
if isNull host.localHost then
|
if isNull host.localHost then
|
||||||
(if host.protocol == "http" then "localhost" else "127.0.0.1")
|
(
|
||||||
else
|
if host.protocol == "http" then "localhost"
|
||||||
host.localHost;
|
else "127.0.0.1"
|
||||||
|
) else host.localHost;
|
||||||
in
|
in
|
||||||
if host.protocol == "http" then
|
if host.protocol == "http" then
|
||||||
{ url = "http://${localhost}:${toString host.port}"; }
|
{ url = "http://${localhost}:${toString host.port}"; }
|
||||||
else
|
else { address = "${localhost}:${toString host.port}"; }
|
||||||
{ address = "${localhost}:${toString host.port}"; }
|
|
||||||
)
|
)
|
||||||
];
|
];
|
||||||
}
|
} // (if (host.middlewares != [ ]) then {
|
||||||
// (
|
middlewares = builtins.listToAttrs (lists.imap0
|
||||||
if (host.middlewares != [ ]) then
|
(id: v: {
|
||||||
{
|
|
||||||
middlewares = builtins.listToAttrs (
|
|
||||||
lists.imap0 (id: v: {
|
|
||||||
name = "${name}-middleware-${toString id}";
|
name = "${name}-middleware-${toString id}";
|
||||||
value = v;
|
value = v;
|
||||||
}) host.middlewares
|
})
|
||||||
);
|
host.middlewares);
|
||||||
}
|
} else { });
|
||||||
else
|
|
||||||
{ }
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
tlsConfig = {
|
tlsConfig = {
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
|
@ -33,8 +28,7 @@ in
|
||||||
# Dynamic configuration
|
# Dynamic configuration
|
||||||
# ---------------------
|
# ---------------------
|
||||||
## Middleware
|
## Middleware
|
||||||
services.traefik.dynamicConfigOptions.http.middlewares.dashboard-auth.basicAuth.usersFile =
|
services.traefik.dynamicConfigOptions.http.middlewares.dashboard-auth.basicAuth.usersFile = cfg.usersFile;
|
||||||
cfg.usersFile;
|
|
||||||
## Router
|
## Router
|
||||||
services.traefik.dynamicConfigOptions.http.routers.dashboard = {
|
services.traefik.dynamicConfigOptions.http.routers.dashboard = {
|
||||||
rule = "Host(`${cfg.host}`)";
|
rule = "Host(`${cfg.host}`)";
|
||||||
|
|
|
@ -1,58 +1,29 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
# Copied from traefik.nix
|
# Copied from traefik.nix
|
||||||
jsonValue =
|
jsonValue = with types;
|
||||||
with types;
|
|
||||||
let
|
let
|
||||||
valueType =
|
valueType = nullOr
|
||||||
nullOr (oneOf [
|
(oneOf [
|
||||||
bool
|
bool
|
||||||
int
|
int
|
||||||
float
|
float
|
||||||
str
|
str
|
||||||
(lazyAttrsOf valueType)
|
(lazyAttrsOf valueType)
|
||||||
(listOf valueType)
|
(listOf valueType)
|
||||||
])
|
]) // {
|
||||||
// {
|
|
||||||
description = "JSON value";
|
description = "JSON value";
|
||||||
emptyValue.value = { };
|
emptyValue.value = { };
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
valueType;
|
valueType;
|
||||||
|
|
||||||
# https://www.cloudflare.com/ips/
|
|
||||||
trustedIPs =
|
|
||||||
let
|
|
||||||
files = [
|
|
||||||
(pkgs.fetchurl {
|
|
||||||
url = "https://www.cloudflare.com/ips-v4";
|
|
||||||
hash = "sha256-8Cxtg7wBqwroV3Fg4DbXAMdFU1m84FTfiE5dfZ5Onns=";
|
|
||||||
})
|
|
||||||
(pkgs.fetchurl {
|
|
||||||
url = "https://www.cloudflare.com/ips-v6";
|
|
||||||
hash = "sha256-np054+g7rQDE3sr9U8Y/piAp89ldto3pN9K+KCNMoKk=";
|
|
||||||
})
|
|
||||||
];
|
|
||||||
|
|
||||||
readLines = path: lib.splitString "\n" (builtins.readFile path);
|
|
||||||
in
|
|
||||||
lib.concatMap readLines files;
|
|
||||||
|
|
||||||
cfg = config.cloud.traefik;
|
cfg = config.cloud.traefik;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [ ./config.nix ./dashboard.nix ./certs-dumper.nix ];
|
||||||
./config.nix
|
|
||||||
./dashboard.nix
|
|
||||||
./certs-dumper.nix
|
|
||||||
];
|
|
||||||
options.cloud.traefik = {
|
options.cloud.traefik = {
|
||||||
cloudflareKeyFile = mkOption {
|
cloudflareKeyFile = mkOption {
|
||||||
type = types.path;
|
type = types.path;
|
||||||
|
@ -86,7 +57,6 @@ in
|
||||||
};
|
};
|
||||||
## HTTPS entrypoint: ok!
|
## HTTPS entrypoint: ok!
|
||||||
entrypoints.https.address = ":443";
|
entrypoints.https.address = ":443";
|
||||||
entrypoints.https.forwardedHeaders.trustedIPs = trustedIPs;
|
|
||||||
## IMAP and SMTP
|
## IMAP and SMTP
|
||||||
entrypoints.imap.address = ":993";
|
entrypoints.imap.address = ":993";
|
||||||
entrypoints.smtp-submission.address = ":587";
|
entrypoints.smtp-submission.address = ":587";
|
||||||
|
@ -115,12 +85,7 @@ in
|
||||||
config.systemd.services.traefik.environment.CF_DNS_API_TOKEN_FILE = cfg.cloudflareKeyFile;
|
config.systemd.services.traefik.environment.CF_DNS_API_TOKEN_FILE = cfg.cloudflareKeyFile;
|
||||||
|
|
||||||
# Set up firewall to allow traefik traffic.
|
# Set up firewall to allow traefik traffic.
|
||||||
config.networking.firewall.allowedTCPPorts = [
|
config.networking.firewall.allowedTCPPorts = [ 443 993 587 465 ];
|
||||||
443
|
|
||||||
993
|
|
||||||
587
|
|
||||||
465
|
|
||||||
];
|
|
||||||
config.networking.firewall.allowedUDPPorts = [
|
config.networking.firewall.allowedUDPPorts = [
|
||||||
443 # QUIC
|
443 # QUIC
|
||||||
51820 # Wireguard
|
51820 # Wireguard
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ config, pkgs, lib, ... }:
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.cloud.writefreely;
|
cfg = config.cloud.writefreely;
|
||||||
|
@ -18,6 +13,7 @@ in
|
||||||
};
|
};
|
||||||
host = mkOption {
|
host = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
|
default = "write.nkagami.me";
|
||||||
description = "The hostname for the instance";
|
description = "The hostname for the instance";
|
||||||
};
|
};
|
||||||
site.title = mkOption {
|
site.title = mkOption {
|
||||||
|
@ -67,3 +63,4 @@ in
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
|
@ -11,203 +6,46 @@ let
|
||||||
|
|
||||||
# Modules
|
# Modules
|
||||||
modules = {
|
modules = {
|
||||||
adb =
|
adb = { config, ... }: mkIf config.common.linux.enable {
|
||||||
{ config, ... }:
|
|
||||||
mkIf config.common.linux.enable {
|
|
||||||
services.udev.packages = with pkgs; [ android-udev-rules ];
|
services.udev.packages = with pkgs; [ android-udev-rules ];
|
||||||
programs.adb.enable = true;
|
programs.adb.enable = true;
|
||||||
users.users.${config.common.linux.username}.extraGroups = [ "adbusers" ];
|
users.users.${config.common.linux.username}.extraGroups = [ "adbusers" ];
|
||||||
};
|
};
|
||||||
ios =
|
ios = { config, ... }: mkIf config.common.linux.enable {
|
||||||
{ config, pkgs, ... }:
|
|
||||||
mkIf config.common.linux.enable {
|
|
||||||
services.usbmuxd.enable = true;
|
services.usbmuxd.enable = true;
|
||||||
services.usbmuxd.package = pkgs.usbmuxd2;
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
libimobiledevice
|
|
||||||
ifuse
|
|
||||||
];
|
|
||||||
users.users.${config.common.linux.username}.extraGroups = [ config.services.usbmuxd.group ];
|
users.users.${config.common.linux.username}.extraGroups = [ config.services.usbmuxd.group ];
|
||||||
systemd.network.networks."05-ios-tethering" = {
|
systemd.network.networks."05-ios-tethering" = {
|
||||||
matchConfig.Driver = "ipheth";
|
matchConfig.Driver = "ipheth";
|
||||||
networkConfig.DHCP = "yes";
|
networkConfig.DHCP = "yes";
|
||||||
linkConfig.RequiredForOnline = "no";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
graphics =
|
wlr = { ... }: mkIf config.common.linux.enable {
|
||||||
{ config, pkgs, ... }:
|
|
||||||
{
|
|
||||||
hardware.graphics.enable = true;
|
|
||||||
hardware.graphics.enable32Bit = true;
|
|
||||||
# Monitor backlight
|
|
||||||
hardware.i2c.enable = true;
|
|
||||||
services.ddccontrol.enable = true;
|
|
||||||
environment.systemPackages = [
|
|
||||||
pkgs.luminance
|
|
||||||
pkgs.ddcutil
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
accounts =
|
|
||||||
{ pkgs, ... }:
|
|
||||||
mkIf (config.common.linux.enable && !pkgs.stdenv.isAarch64) {
|
|
||||||
environment.systemPackages = [
|
|
||||||
pkgs.glib
|
|
||||||
(pkgs.gnome-control-center or pkgs.gnome.gnome-control-center)
|
|
||||||
];
|
|
||||||
services.accounts-daemon.enable = true;
|
|
||||||
services.gnome.gnome-online-accounts.enable = true;
|
|
||||||
# programs.evolution.enable = true;
|
|
||||||
# programs.evolution.plugins = with pkgs; [ evolution-ews ];
|
|
||||||
# services.gnome.evolution-data-server.enable = true;
|
|
||||||
# services.gnome.evolution-data-server.plugins = with pkgs; [ evolution-ews ];
|
|
||||||
};
|
|
||||||
|
|
||||||
wlr =
|
|
||||||
{ lib, config, ... }:
|
|
||||||
mkIf config.common.linux.enable {
|
|
||||||
# swaync disable notifications on screencast
|
# swaync disable notifications on screencast
|
||||||
xdg.portal.wlr.settings.screencast = {
|
xdg.portal.wlr.settings.screencast = {
|
||||||
exec_before = ''which swaync-client && swaync-client --inhibitor-add "xdg-desktop-portal-wlr" || true'';
|
exec_before = ''which swaync-client && swaync-client --inhibitor-add "xdg-desktop-portal-wlr" || true'';
|
||||||
exec_after = ''which swaync-client && swaync-client --inhibitor-remove "xdg-desktop-portal-wlr" || true'';
|
exec_after = ''which swaync-client && swaync-client --inhibitor-remove "xdg-desktop-portal-wlr" || true'';
|
||||||
};
|
};
|
||||||
|
|
||||||
# Niri stuff
|
|
||||||
# https://github.com/sodiboo/niri-flake/blob/main/docs.md
|
|
||||||
programs.niri.enable = true;
|
|
||||||
programs.niri.package = pkgs.niri-stable;
|
|
||||||
# Override gnome-keyring disabling
|
|
||||||
services.gnome.gnome-keyring.enable = lib.mkForce false;
|
|
||||||
# ydotool
|
|
||||||
programs.ydotool.enable = true;
|
|
||||||
users.extraGroups.${config.programs.ydotool.group}.members = [ cfg.username ];
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
logitech =
|
logitech = { pkgs, ... }: mkIf cfg.enable {
|
||||||
{ pkgs, ... }:
|
|
||||||
mkIf cfg.enable {
|
|
||||||
services.ratbagd.enable = true;
|
services.ratbagd.enable = true;
|
||||||
environment.systemPackages = with pkgs; [ piper ];
|
environment.systemPackages = with pkgs; [ piper ];
|
||||||
};
|
};
|
||||||
|
|
||||||
kwallet =
|
virtualisation = { pkgs, ... }: mkIf cfg.enable {
|
||||||
{ pkgs, lib, ... }:
|
|
||||||
mkIf cfg.enable {
|
|
||||||
environment.systemPackages = [ pkgs.kdePackages.kwallet ];
|
|
||||||
services.dbus.packages = [ pkgs.kdePackages.kwallet ];
|
|
||||||
xdg.portal = {
|
|
||||||
extraPortals = [ pkgs.kdePackages.kwallet ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
virtualisation =
|
|
||||||
{ pkgs, ... }:
|
|
||||||
mkIf cfg.enable {
|
|
||||||
virtualisation.podman = {
|
virtualisation.podman = {
|
||||||
enable = true;
|
enable = true;
|
||||||
extraPackages = [ pkgs.slirp4netns ];
|
|
||||||
dockerCompat = true;
|
dockerCompat = true;
|
||||||
defaultNetwork.settings.dns_enabled = true;
|
# defaultNetwork.settings.dns_enabled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtualisation.oci-containers.backend = "podman";
|
virtualisation.oci-containers.backend = "podman";
|
||||||
|
|
||||||
virtualisation.virtualbox.host.enable = false;
|
|
||||||
users.extraGroups.vboxusers.members = [ cfg.username ];
|
|
||||||
};
|
|
||||||
|
|
||||||
nix-ld =
|
|
||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
programs.nix-ld = {
|
|
||||||
enable = true;
|
|
||||||
libraries = with pkgs; [
|
|
||||||
ncurses
|
|
||||||
llvmPackages.libcxx
|
|
||||||
glibc
|
|
||||||
sqlite
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
rt-audio =
|
|
||||||
{ pkgs, ... }:
|
|
||||||
mkIf cfg.enable {
|
|
||||||
services.pipewire.lowLatency = {
|
|
||||||
# enable this module
|
|
||||||
enable = true;
|
|
||||||
# defaults (no need to be set unless modified)
|
|
||||||
quantum = 32;
|
|
||||||
rate = 44100;
|
|
||||||
};
|
|
||||||
security.rtkit.enable = true;
|
|
||||||
|
|
||||||
# Real time configurations
|
|
||||||
boot.kernel.sysctl = {
|
|
||||||
"vm.swappiness" = 10;
|
|
||||||
"fs.inotify.max_user_watches" = 524288;
|
|
||||||
};
|
|
||||||
security.pam.loginLimits = [
|
|
||||||
{
|
|
||||||
domain = "@audio";
|
|
||||||
item = "rtprio";
|
|
||||||
type = "-";
|
|
||||||
value = "90";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
domain = "@audio";
|
|
||||||
item = "memlock";
|
|
||||||
type = "-";
|
|
||||||
value = "unlimited";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
tailscale =
|
|
||||||
{ config, ... }:
|
|
||||||
{
|
|
||||||
options.common.linux = {
|
|
||||||
tailscale = {
|
|
||||||
firewall.allowPorts = mkOption {
|
|
||||||
type = types.listOf types.port;
|
|
||||||
description = "List of ports to allow tailscale to pass through";
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
config =
|
|
||||||
let
|
|
||||||
cfg = config.common.linux.tailscale;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# Enable tailscale
|
|
||||||
services.tailscale.enable = true;
|
|
||||||
networking.firewall.interfaces."tailscale0" = {
|
|
||||||
allowedUDPPorts = cfg.firewall.allowPorts;
|
|
||||||
allowedTCPPorts = cfg.firewall.allowPorts;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = with modules; [
|
imports = with modules; [ adb ios wlr logitech virtualisation ] ++ [ ./networking.nix ];
|
||||||
./sops.nix
|
|
||||||
|
|
||||||
adb
|
|
||||||
ios
|
|
||||||
graphics
|
|
||||||
wlr
|
|
||||||
logitech
|
|
||||||
kwallet
|
|
||||||
virtualisation
|
|
||||||
accounts
|
|
||||||
rt-audio
|
|
||||||
nix-ld
|
|
||||||
tailscale
|
|
||||||
];
|
|
||||||
|
|
||||||
options.common.linux = {
|
options.common.linux = {
|
||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
|
@ -230,14 +68,10 @@ in
|
||||||
dnsServers = mkOption {
|
dnsServers = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
description = "DNS server list";
|
description = "DNS server list";
|
||||||
default = [
|
default = [ "8.8.8.8" "8.8.4.4" ];
|
||||||
"1.1.1.1"
|
|
||||||
"2606:4700:4700:1111"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
networks = mkOption {
|
networks = mkOption {
|
||||||
type = types.attrsOf (
|
type = types.attrsOf (types.submodule {
|
||||||
types.submodule {
|
|
||||||
options.match = mkOption {
|
options.match = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
description = "The interface name to match";
|
description = "The interface name to match";
|
||||||
|
@ -247,13 +81,10 @@ in
|
||||||
description = "Require this interface to be connected for network-online.target";
|
description = "Require this interface to be connected for network-online.target";
|
||||||
default = false;
|
default = false;
|
||||||
};
|
};
|
||||||
}
|
});
|
||||||
);
|
|
||||||
description = "Network configuration";
|
description = "Network configuration";
|
||||||
default = {
|
default = {
|
||||||
default = {
|
default = { match = "*"; };
|
||||||
match = "*";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -271,14 +102,16 @@ in
|
||||||
boot.kernelPackages = mkDefault pkgs.linuxPackages_latest;
|
boot.kernelPackages = mkDefault pkgs.linuxPackages_latest;
|
||||||
# Use the systemd-boot EFI boot loader.
|
# Use the systemd-boot EFI boot loader.
|
||||||
boot = {
|
boot = {
|
||||||
|
plymouth.enable = true;
|
||||||
loader.timeout = 60;
|
loader.timeout = 60;
|
||||||
loader.systemd-boot.enable = true;
|
loader.systemd-boot.enable = true;
|
||||||
loader.efi.canTouchEfiVariables = true;
|
loader.efi.canTouchEfiVariables = true;
|
||||||
supportedFilesystems.ntfs = true;
|
supportedFilesystems = [ "ntfs" ];
|
||||||
};
|
};
|
||||||
boot.initrd.systemd.enable = builtins.length (builtins.attrNames (cfg.luksDevices)) > 0;
|
boot.initrd.systemd.enable = builtins.length (builtins.attrNames (cfg.luksDevices)) > 0;
|
||||||
# LUKS devices
|
# LUKS devices
|
||||||
boot.initrd.luks.devices = builtins.mapAttrs (name: path: {
|
boot.initrd.luks.devices = builtins.mapAttrs
|
||||||
|
(name: path: {
|
||||||
device = path;
|
device = path;
|
||||||
preLVM = true;
|
preLVM = true;
|
||||||
allowDiscards = true;
|
allowDiscards = true;
|
||||||
|
@ -287,14 +120,12 @@ in
|
||||||
"tpm2-device=auto"
|
"tpm2-device=auto"
|
||||||
"fido2-device=auto"
|
"fido2-device=auto"
|
||||||
];
|
];
|
||||||
}) cfg.luksDevices;
|
})
|
||||||
|
cfg.luksDevices;
|
||||||
|
|
||||||
## Hardware-related
|
## Hardware-related
|
||||||
|
|
||||||
# Firmware stuff
|
|
||||||
services.fwupd.enable = true;
|
|
||||||
|
|
||||||
# Enable sound.
|
# Enable sound.
|
||||||
|
sound.enable = true;
|
||||||
services.pipewire = {
|
services.pipewire = {
|
||||||
enable = true;
|
enable = true;
|
||||||
# alsa is optional
|
# alsa is optional
|
||||||
|
@ -303,20 +134,15 @@ in
|
||||||
|
|
||||||
pulse.enable = true;
|
pulse.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
# udev configurations
|
# udev configurations
|
||||||
services.udev.packages = with pkgs; [
|
services.udev.packages = with pkgs; [
|
||||||
qmk-udev-rules # For keyboards
|
qmk-udev-rules # For keyboards
|
||||||
];
|
];
|
||||||
# udisks
|
|
||||||
services.udisks2.enable = true;
|
|
||||||
# Bluetooth: just enable
|
# Bluetooth: just enable
|
||||||
hardware.bluetooth.enable = true;
|
hardware.bluetooth.enable = true;
|
||||||
hardware.bluetooth.package = pkgs.bluez5-experimental; # Why do we need experimental...?
|
hardware.bluetooth.package = pkgs.bluez5-experimental; # Why do we need experimental...?
|
||||||
hardware.bluetooth.settings.General.Experimental = true;
|
hardware.bluetooth.settings.General.Experimental = true;
|
||||||
services.blueman.enable = true; # For a GUI
|
services.blueman.enable = true; # For a GUI
|
||||||
# ZRAM
|
|
||||||
zramSwap.enable = true;
|
|
||||||
|
|
||||||
## Users
|
## Users
|
||||||
users.users.${cfg.username} = {
|
users.users.${cfg.username} = {
|
||||||
|
@ -325,125 +151,87 @@ in
|
||||||
extraGroups = [
|
extraGroups = [
|
||||||
"wheel" # Enable ‘sudo’ for the user.
|
"wheel" # Enable ‘sudo’ for the user.
|
||||||
"plugdev" # Enable openrazer-daemon privileges
|
"plugdev" # Enable openrazer-daemon privileges
|
||||||
"audio"
|
|
||||||
"video"
|
|
||||||
"input"
|
|
||||||
];
|
];
|
||||||
shell = pkgs.fish;
|
|
||||||
};
|
};
|
||||||
nix.settings.trusted-users = [
|
|
||||||
"root"
|
|
||||||
cfg.username
|
|
||||||
];
|
|
||||||
|
|
||||||
## Network configuration
|
## Network configuration
|
||||||
systemd.network.enable = true;
|
systemd.network.enable = true;
|
||||||
networking.dhcpcd.enable = lib.mkForce false;
|
|
||||||
networking.useDHCP = false;
|
|
||||||
networking.useNetworkd = true;
|
|
||||||
systemd.network.wait-online.enable = false;
|
|
||||||
networking.hostName = cfg.networking.hostname;
|
networking.hostName = cfg.networking.hostname;
|
||||||
networking.wireless.iwd.enable = true;
|
networking.wireless.iwd.enable = true;
|
||||||
networking.wireless.iwd.settings.General.EnableNetworkConfiguration = true;
|
systemd.network.networks = builtins.mapAttrs
|
||||||
systemd.network.networks = builtins.mapAttrs (name: cfg: {
|
(name: cfg: {
|
||||||
matchConfig.Name = cfg.match;
|
matchConfig.Name = cfg.match;
|
||||||
networkConfig.DHCP = "yes";
|
networkConfig.DHCP = "yes";
|
||||||
linkConfig.RequiredForOnline = if cfg.isRequired then "yes" else "no";
|
linkConfig.RequiredForOnline = if cfg.isRequired then "yes" else "no";
|
||||||
}) cfg.networking.networks;
|
})
|
||||||
|
cfg.networking.networks;
|
||||||
# Leave DNS to systemd-resolved
|
# Leave DNS to systemd-resolved
|
||||||
services.resolved.enable = true;
|
services.resolved.enable = true;
|
||||||
services.resolved.domains = cfg.networking.dnsServers;
|
services.resolved.domains = cfg.networking.dnsServers;
|
||||||
services.resolved.fallbackDns = cfg.networking.dnsServers;
|
services.resolved.fallbackDns = cfg.networking.dnsServers;
|
||||||
# Firewall: only open to SSH now
|
# Firewall: only open to SSH now
|
||||||
|
networking.nftables.enable = true;
|
||||||
networking.firewall.allowedTCPPorts = [ 22 ];
|
networking.firewall.allowedTCPPorts = [ 22 ];
|
||||||
networking.firewall.allowedUDPPorts = [ 22 ];
|
networking.firewall.allowedUDPPorts = [ 22 ];
|
||||||
# Network namespaces management
|
# Enable tailscale
|
||||||
systemd.services."netns@" = {
|
services.tailscale.enable = true;
|
||||||
description = "Network namespace %I";
|
|
||||||
before = [ "network.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
RemainAfterExit = true;
|
|
||||||
ExecStart = "${pkgs.iproute2}/bin/ip netns add %I";
|
|
||||||
ExecStop = "${pkgs.iproute2}/bin/ip netns del %I";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
## Time and Region
|
## Time and Region
|
||||||
time.timeZone = lib.mkDefault "Europe/Zurich";
|
time.timeZone = "Europe/Zurich";
|
||||||
# Select internationalisation properties.
|
# Select internationalisation properties.
|
||||||
console.keyMap = "jp106"; # Console key layout
|
console.keyMap = "jp106"; # Console key layout
|
||||||
i18n.defaultLocale = "ja_JP.UTF-8";
|
i18n.defaultLocale = "ja_JP.UTF-8";
|
||||||
# Input methods (only fcitx5 works reliably on Wayland)
|
# Input methods (only fcitx5 works reliably on Wayland)
|
||||||
i18n.inputMethod =
|
i18n.inputMethod = {
|
||||||
{
|
enabled = "fcitx5";
|
||||||
fcitx5.waylandFrontend = true;
|
|
||||||
fcitx5.addons = with pkgs; [
|
fcitx5.addons = with pkgs; [
|
||||||
fcitx5-mozc
|
fcitx5-mozc
|
||||||
fcitx5-unikey
|
fcitx5-unikey
|
||||||
fcitx5-gtk
|
fcitx5-gtk
|
||||||
];
|
];
|
||||||
}
|
};
|
||||||
// (
|
|
||||||
if config.system.nixos.release == "24.05" then
|
|
||||||
{
|
|
||||||
enabled = "fcitx5";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
type = "fcitx5";
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
# Default packages
|
# Default packages
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
kakoune # An editor
|
kakoune # An editor
|
||||||
wget # A simple fetcher
|
wget # A simple fetcher
|
||||||
|
fish # Good shell
|
||||||
|
|
||||||
## System monitoring tools
|
## System monitoring tools
|
||||||
usbutils # lsusb and friends
|
usbutils # lsusb and friends
|
||||||
pciutils # lspci and friends
|
pciutils # lspci and friends
|
||||||
psmisc # killall, pstree, ...
|
psmisc # killall, pstree, ...
|
||||||
lm_sensors # sensors
|
|
||||||
|
|
||||||
## Security stuff
|
## Security stuff
|
||||||
libsForQt5.qtkeychain
|
libsForQt5.qtkeychain
|
||||||
|
|
||||||
## Wayland
|
## Wayland
|
||||||
kdePackages.qtwayland
|
qt5.qtwayland
|
||||||
];
|
];
|
||||||
# Add a reliable terminal
|
# Add a reliable terminal
|
||||||
programs.fish.enable = true;
|
|
||||||
# programs.gnome-terminal.enable = true;
|
# programs.gnome-terminal.enable = true;
|
||||||
# KDEConnect is just based
|
# KDEConnect is just based
|
||||||
programs.kdeconnect.enable = true;
|
programs.kdeconnect.enable = true;
|
||||||
# Flatpaks are useful... sometimes...
|
# Flatpaks are useful... sometimes...
|
||||||
services.flatpak.enable = true;
|
services.flatpak.enable = true;
|
||||||
# AppImages should run
|
|
||||||
programs.appimage = {
|
|
||||||
enable = true;
|
|
||||||
binfmt = true;
|
|
||||||
};
|
|
||||||
# DConf for GNOME configurations
|
# DConf for GNOME configurations
|
||||||
programs.dconf.enable = true;
|
programs.dconf.enable = true;
|
||||||
# Gaming! (not for ARM64)
|
# Gaming! (not for ARM64)
|
||||||
programs.steam.enable = true;
|
programs.steam.enable = !pkgs.stdenv.isAarch64;
|
||||||
programs.gamescope = {
|
hardware.opengl.enable = true;
|
||||||
enable = true;
|
hardware.opengl.driSupport = true;
|
||||||
# capSysNice = true; # https://github.com/NixOS/nixpkgs/issues/351516
|
hardware.opengl.driSupport32Bit = !pkgs.stdenv.isAarch64; # For 32 bit applications
|
||||||
args = [
|
|
||||||
"--adaptive-sync"
|
|
||||||
"--rt"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
## Services
|
## Services
|
||||||
|
# gnome-keyring for storing keys
|
||||||
|
services.gnome.gnome-keyring.enable = true;
|
||||||
# OpenSSH so you can SSH to me
|
# OpenSSH so you can SSH to me
|
||||||
services.openssh.enable = true;
|
services.openssh.enable = true;
|
||||||
# PAM
|
# PAM
|
||||||
security.pam.services.login.enableKwallet = true;
|
security.pam.services.login.enableKwallet = true;
|
||||||
|
security.pam.services.login.enableGnomeKeyring = true;
|
||||||
security.pam.services.lightdm.enableKwallet = true;
|
security.pam.services.lightdm.enableKwallet = true;
|
||||||
|
security.pam.services.lightdm.enableGnomeKeyring = true;
|
||||||
security.pam.services.swaylock = { };
|
security.pam.services.swaylock = { };
|
||||||
# Printers
|
# Printers
|
||||||
services.printing.enable = true;
|
services.printing.enable = true;
|
||||||
|
@ -451,30 +239,8 @@ in
|
||||||
xdg.portal = {
|
xdg.portal = {
|
||||||
enable = true;
|
enable = true;
|
||||||
wlr.enable = true;
|
wlr.enable = true;
|
||||||
xdgOpenUsePortal = true;
|
|
||||||
# gtk portal needed to make gtk apps happy
|
# gtk portal needed to make gtk apps happy
|
||||||
extraPortals = [
|
extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
|
||||||
pkgs.kdePackages.xdg-desktop-portal-kde
|
|
||||||
pkgs.xdg-desktop-portal-gtk
|
|
||||||
];
|
|
||||||
|
|
||||||
config.sway.default = [
|
|
||||||
"wlr"
|
|
||||||
"kde"
|
|
||||||
"kwallet"
|
|
||||||
];
|
|
||||||
config.niri = {
|
|
||||||
default = [
|
|
||||||
"kde"
|
|
||||||
"gnome"
|
|
||||||
"gtk"
|
|
||||||
];
|
|
||||||
# "org.freedesktop.impl.portal.Access" = "gtk";
|
|
||||||
# "org.freedesktop.impl.portal.Notification" = "gtk";
|
|
||||||
"org.freedesktop.impl.portal.ScreenCast" = "gnome";
|
|
||||||
"org.freedesktop.impl.portal.Secret" = "kwallet";
|
|
||||||
"org.freedesktop.impl.portal.FileChooser" = "kde";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
# D-Bus
|
# D-Bus
|
||||||
services.dbus.packages = with pkgs; [ gcr ];
|
services.dbus.packages = with pkgs; [ gcr ];
|
||||||
|
@ -485,8 +251,5 @@ in
|
||||||
EDITOR = "kak";
|
EDITOR = "kak";
|
||||||
VISUAL = "kak";
|
VISUAL = "kak";
|
||||||
};
|
};
|
||||||
|
|
||||||
# Trust my own cert
|
|
||||||
security.pki.certificateFiles = [ ../../../nki-home/cert.pem ];
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
47
modules/common/linux/networking.nix
Normal file
47
modules/common/linux/networking.nix
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
let
|
||||||
|
localNetworks = { config, lib, pkgs, ... }: with lib; {
|
||||||
|
# Default local networks
|
||||||
|
options.nki.networking = {
|
||||||
|
localNetworks = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
description = "A list of known IPv4 local networks";
|
||||||
|
};
|
||||||
|
allowLocalPorts = mkOption {
|
||||||
|
type = types.listOf types.port;
|
||||||
|
default = [ ];
|
||||||
|
description = "Open the following ports in all local networks";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
options.nki.networking.ipv6.localNetworks = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
description = "A list of known IPv6 local networks";
|
||||||
|
};
|
||||||
|
|
||||||
|
config.nki.networking.localNetworks = [
|
||||||
|
"11.0.0.0/24" # tinc
|
||||||
|
"100.64.0.0/10" # Headscale
|
||||||
|
];
|
||||||
|
|
||||||
|
config.nki.networking.ipv6.localNetworks = [
|
||||||
|
"fd7a:115c:a1e0::/48" # Headscale
|
||||||
|
];
|
||||||
|
|
||||||
|
config.networking = mkIf (config.nki.networking.allowLocalPorts != [ ]) {
|
||||||
|
nftables.enable = true;
|
||||||
|
firewall.extraInputRules =
|
||||||
|
let
|
||||||
|
portsStr = concatMapStringsSep ", " toString config.nki.networking.allowLocalPorts;
|
||||||
|
ip4Str = concatStringsSep ", " config.nki.networking.localNetworks;
|
||||||
|
ip6Str = concatStringsSep ", " config.nki.networking.ipv6.localNetworks;
|
||||||
|
in
|
||||||
|
''
|
||||||
|
${if ip4Str == "" then "" else "ip saddr { ${ip4Str} } dport { ${portsStr} } accept"}
|
||||||
|
${if ip6Str == "" then "" else "ip6 saddr { ${ip6Str} } dport { ${portsStr} } accept"}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{ ... }: {
|
||||||
|
imports = [ localNetworks ];
|
||||||
|
}
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
{ config, lib, ... }:
|
|
||||||
with { inherit (lib) types mkOption mkEnableOption; };
|
|
||||||
let
|
|
||||||
cfg = config.common.linux.sops;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.common.linux.sops = {
|
|
||||||
enable = mkEnableOption "Enable sops configuration";
|
|
||||||
file = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
description = "Path to the default sops file";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
sops.defaultSopsFile = cfg.file;
|
|
||||||
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ config, pkgs, lib, ... }:
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
|
@ -39,13 +34,15 @@ in
|
||||||
default = 655;
|
default = 655;
|
||||||
description = "The port to listen on";
|
description = "The port to listen on";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
meshIp = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The mesh ip to be assigned by hostname";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable (
|
config = mkIf cfg.enable (builtins.seq
|
||||||
builtins.seq
|
(mkIf (isNull cfg.rsaPrivateKey && isNull cfg.ed25519PrivateKey) (builtins.abort "one of the keys must be defined"))
|
||||||
(mkIf (isNull cfg.rsaPrivateKey && isNull cfg.ed25519PrivateKey) (
|
|
||||||
builtins.abort "one of the keys must be defined"
|
|
||||||
))
|
|
||||||
(
|
(
|
||||||
let
|
let
|
||||||
networkName = "my-tinc";
|
networkName = "my-tinc";
|
||||||
|
@ -54,6 +51,7 @@ in
|
||||||
myMeshIp = myHost.subnetAddr;
|
myMeshIp = myHost.subnetAddr;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
services.my-tinc.meshIp = myMeshIp;
|
||||||
# Scripts that set up the tinc services
|
# Scripts that set up the tinc services
|
||||||
environment.etc = {
|
environment.etc = {
|
||||||
"tinc/${networkName}/tinc-up".source = pkgs.writeScript "tinc-up-${networkName}" ''
|
"tinc/${networkName}/tinc-up".source = pkgs.writeScript "tinc-up-${networkName}" ''
|
||||||
|
@ -81,30 +79,11 @@ in
|
||||||
|
|
||||||
# simple interface setup
|
# simple interface setup
|
||||||
# ----------------------
|
# ----------------------
|
||||||
networking.interfaces."tinc.${networkName}".ipv4.addresses = [
|
networking.interfaces."tinc.${networkName}".ipv4.addresses = [{ address = myMeshIp; prefixLength = 24; }];
|
||||||
{
|
|
||||||
address = myMeshIp;
|
|
||||||
prefixLength = 24;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
# firewall
|
# firewall
|
||||||
networking.firewall.allowedUDPPorts = [ 655 ];
|
networking.firewall.allowedUDPPorts = [ 655 ];
|
||||||
networking.firewall.allowedTCPPorts = [ 655 ];
|
networking.firewall.allowedTCPPorts = [ 655 ];
|
||||||
networking.firewall.interfaces."tinc.${networkName}" = {
|
|
||||||
allowedUDPPortRanges = [
|
|
||||||
{
|
|
||||||
from = 0;
|
|
||||||
to = 65535;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
allowedTCPPortRanges = [
|
|
||||||
{
|
|
||||||
from = 0;
|
|
||||||
to = 65535;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# configure tinc service
|
# configure tinc service
|
||||||
# ----------------------
|
# ----------------------
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ config, pkgs, lib, ... }:
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
|
@ -11,34 +6,27 @@ let
|
||||||
|
|
||||||
cfg = config.services.my-tinc;
|
cfg = config.services.my-tinc;
|
||||||
|
|
||||||
mapAttrs =
|
mapAttrs = f: attrs: builtins.listToAttrs (
|
||||||
f: attrs:
|
map (name: { inherit name; value = f name (builtins.getAttr name attrs); }) (builtins.attrNames attrs)
|
||||||
builtins.listToAttrs (
|
|
||||||
map (name: {
|
|
||||||
inherit name;
|
|
||||||
value = f name (builtins.getAttr name attrs);
|
|
||||||
}) (builtins.attrNames attrs)
|
|
||||||
);
|
);
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
# All hosts we know of
|
# All hosts we know of
|
||||||
services.tinc.networks.my-tinc.hostSettings = mapAttrs (name: host: {
|
services.tinc.networks.my-tinc.hostSettings = mapAttrs
|
||||||
|
(name: host: {
|
||||||
addresses = if (host ? address) then [{ address = host.address; }] else [ ];
|
addresses = if (host ? address) then [{ address = host.address; }] else [ ];
|
||||||
subnets = [{ address = host.subnetAddr; }];
|
subnets = [{ address = host.subnetAddr; }];
|
||||||
rsaPublicKey = mkIf (host ? "rsaPublicKey") host.rsaPublicKey;
|
rsaPublicKey = mkIf (host ? "rsaPublicKey") host.rsaPublicKey;
|
||||||
settings.Ed25519PublicKey = mkIf (host ? "ed25519PublicKey") host.ed25519PublicKey;
|
settings.Ed25519PublicKey = mkIf (host ? "ed25519PublicKey") host.ed25519PublicKey;
|
||||||
}) hosts;
|
})
|
||||||
|
hosts;
|
||||||
|
|
||||||
# Add all of them to host
|
# Add all of them to host
|
||||||
nki.services.edns = {
|
networking.extraHosts = lib.strings.concatStringsSep
|
||||||
enable = true;
|
"\n"
|
||||||
cloaking-rules = (
|
(lib.attrsets.mapAttrsToList
|
||||||
lib.attrsets.mapAttrs' (name: host: {
|
(name: host: "${host.subnetAddr} ${name}.tinc")
|
||||||
name = "${name}.tinc";
|
hosts);
|
||||||
value = host.subnetAddr;
|
|
||||||
}) hosts
|
|
||||||
);
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,14 +22,4 @@
|
||||||
subnetAddr = "11.0.0.4";
|
subnetAddr = "11.0.0.4";
|
||||||
ed25519PublicKey = "6MN5LVE4juavv8qJW2dTN4t/haKCADWquAQj/ADF7iN";
|
ed25519PublicKey = "6MN5LVE4juavv8qJW2dTN4t/haKCADWquAQj/ADF7iN";
|
||||||
};
|
};
|
||||||
|
|
||||||
yoga = {
|
|
||||||
subnetAddr = "11.0.0.5";
|
|
||||||
ed25519PublicKey = "n+gIZjuuTPxi0OBqw2oOcmXd3loOHG+GQHBMXNlgyqI";
|
|
||||||
};
|
|
||||||
|
|
||||||
framework = {
|
|
||||||
subnetAddr = "11.0.0.6";
|
|
||||||
ed25519PublicKey = "YL7NA6Ydv/3FBfSzOPvyHlGweAViPvsG3b0Zh8L0NzF";
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,63 +1,43 @@
|
||||||
{
|
{ pkgs, lib, config, ... }:
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
nerd-fonts =
|
noto-fonts-emoji-blob-bin =
|
||||||
if builtins.hasAttr "nerd-fonts" pkgs then
|
let
|
||||||
pkgs.nerd-fonts.symbols-only
|
pname = "noto-fonts-emoji-blob-bin";
|
||||||
else
|
version = "15.0";
|
||||||
pkgs.nerdfonts.override { fonts = [ "NerdFontsSymbolsOnly" ]; };
|
in
|
||||||
|
pkgs.fetchurl {
|
||||||
|
name = "${pname}-${version}";
|
||||||
|
url = "https://github.com/C1710/blobmoji/releases/download/v${version}/Blobmoji.ttf";
|
||||||
|
sha256 = "sha256-n5yVk2w9x7UVrMe0Ho6nwu1Z9E/ktjo1UHdHKStoJWc=";
|
||||||
|
|
||||||
|
downloadToTemp = true;
|
||||||
|
recursiveHash = true;
|
||||||
|
postFetch = ''
|
||||||
|
install -Dm 444 $downloadedFile $out/share/fonts/blobmoji/Blobmoji.ttf
|
||||||
|
'';
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ ./mounting.nix ];
|
|
||||||
# Fonts
|
# Fonts
|
||||||
config.fonts =
|
config.fonts = {
|
||||||
{
|
fonts = with pkgs; [
|
||||||
packages =
|
|
||||||
with pkgs;
|
|
||||||
mkForce [
|
|
||||||
noto-fonts-emoji-blob-bin
|
noto-fonts-emoji-blob-bin
|
||||||
ibm-plex
|
ibm-plex
|
||||||
nerd-fonts
|
(nerdfonts.override { fonts = [ "NerdFontsSymbolsOnly" ]; })
|
||||||
noto-fonts
|
noto-fonts
|
||||||
(pkgs.noto-fonts-cjk-sans or pkgs.noto-fonts-cjk)
|
noto-fonts-cjk
|
||||||
merriweather
|
merriweather
|
||||||
corefonts
|
|
||||||
font-awesome
|
|
||||||
hack-font # for Plasma
|
|
||||||
];
|
];
|
||||||
}
|
} // (if pkgs.stdenv.isLinux then {
|
||||||
// (
|
enableDefaultFonts = false;
|
||||||
if pkgs.stdenv.isLinux then
|
|
||||||
{
|
|
||||||
enableDefaultPackages = false;
|
|
||||||
fontconfig = {
|
fontconfig = {
|
||||||
defaultFonts = {
|
defaultFonts = {
|
||||||
emoji = lib.mkBefore [ "Blobmoji" ];
|
emoji = lib.mkBefore [ "Blobmoji" ];
|
||||||
serif = lib.mkBefore [
|
serif = lib.mkBefore [ "IBM Plex Serif" "IBM Plex Sans JP" "IBM Plex Sans KR" ];
|
||||||
"IBM Plex Serif"
|
sansSerif = lib.mkBefore [ "IBM Plex Sans" "IBM Plex Sans JP" "IBM Plex Sans KR" ];
|
||||||
"IBM Plex Sans JP"
|
monospace = lib.mkBefore [ "IBM Plex Mono" ];
|
||||||
"IBM Plex Sans KR"
|
|
||||||
"Blobmoji"
|
|
||||||
];
|
|
||||||
sansSerif = lib.mkBefore [
|
|
||||||
"IBM Plex Sans"
|
|
||||||
"IBM Plex Sans JP"
|
|
||||||
"IBM Plex Sans KR"
|
|
||||||
"Blobmoji"
|
|
||||||
];
|
|
||||||
monospace = lib.mkBefore [
|
|
||||||
"IBM Plex Mono"
|
|
||||||
"Font Awesome 6 Free"
|
|
||||||
"Symbols Nerd Font"
|
|
||||||
"Blobmoji"
|
|
||||||
"IBM Plex Sans JP"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
localConf = ''
|
localConf = ''
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
|
@ -69,23 +49,14 @@ in
|
||||||
<family>IBM Plex Sans</family>
|
<family>IBM Plex Sans</family>
|
||||||
<family>IBM Plex Sans JP</family>
|
<family>IBM Plex Sans JP</family>
|
||||||
<family>IBM Plex Sans KR</family>
|
<family>IBM Plex Sans KR</family>
|
||||||
<family>Blobmoji</family>
|
|
||||||
</prefer>
|
</prefer>
|
||||||
</alias>
|
</alias>
|
||||||
</fontconfig>
|
</fontconfig>
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
fontDir.enable = true;
|
fontDir.enable = true;
|
||||||
}
|
} else { }) // (if pkgs.stdenv.isDarwin then {
|
||||||
else
|
|
||||||
{ }
|
|
||||||
)
|
|
||||||
// (
|
|
||||||
if pkgs.stdenv.isDarwin then
|
|
||||||
{
|
|
||||||
fontDir.enable = true;
|
fontDir.enable = true;
|
||||||
|
} else { });
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{ }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
{
|
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
lib.mkIf pkgs.stdenv.isLinux {
|
|
||||||
system.fsPackages = [ pkgs.bindfs ];
|
|
||||||
fileSystems =
|
|
||||||
let
|
|
||||||
mkRoSymBind = path: {
|
|
||||||
device = path;
|
|
||||||
fsType = "fuse.bindfs";
|
|
||||||
options = [
|
|
||||||
"ro"
|
|
||||||
"resolve-symlinks"
|
|
||||||
"x-gvfs-hide"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
aggregatedIcons = pkgs.buildEnv {
|
|
||||||
name = "system-icons";
|
|
||||||
paths = with pkgs; [
|
|
||||||
#libsForQt5.breeze-qt5 # for plasma
|
|
||||||
(pkgs.gnome-themes-extra or gnome.gnome-themes-extra) # Until 24.11
|
|
||||||
];
|
|
||||||
pathsToLink = [ "/share/icons" ];
|
|
||||||
};
|
|
||||||
aggregatedFonts = pkgs.buildEnv {
|
|
||||||
name = "system-fonts";
|
|
||||||
paths = config.fonts.packages;
|
|
||||||
pathsToLink = [ "/share/fonts" ];
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
"/usr/share/icons" = mkRoSymBind "${aggregatedIcons}/share/icons";
|
|
||||||
"/usr/local/share/fonts" = mkRoSymBind "${aggregatedFonts}/share/fonts";
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ config, pkgs, lib, ... }:
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
|
@ -21,7 +16,7 @@ in
|
||||||
security.pam = mkIf pkgs.stdenv.isLinux {
|
security.pam = mkIf pkgs.stdenv.isLinux {
|
||||||
u2f = {
|
u2f = {
|
||||||
enable = true;
|
enable = true;
|
||||||
settings.cue = true;
|
cue = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Services
|
# Services
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ pkgs, config, lib, ... }:
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
|
@ -13,11 +8,6 @@ in
|
||||||
options.nki.services.edns = {
|
options.nki.services.edns = {
|
||||||
enable = mkEnableOption "Enable encrypted DNS";
|
enable = mkEnableOption "Enable encrypted DNS";
|
||||||
ipv6 = mkEnableOption "Enable ipv6";
|
ipv6 = mkEnableOption "Enable ipv6";
|
||||||
cloaking-rules = mkOption {
|
|
||||||
type = types.attrsOf types.str;
|
|
||||||
default = { };
|
|
||||||
description = "A set of domain -> ip mapping for cloaking_rules";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
@ -39,10 +29,7 @@ in
|
||||||
|
|
||||||
# Sources
|
# Sources
|
||||||
sources.public_resolvers = {
|
sources.public_resolvers = {
|
||||||
urls = [
|
urls = [ "https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/public-resolvers.md" "https://download.dnscrypt.info/resolvers-list/v3/public-resolvers.md" ];
|
||||||
"https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/public-resolvers.md"
|
|
||||||
"https://download.dnscrypt.info/resolvers-list/v3/public-resolvers.md"
|
|
||||||
];
|
|
||||||
cache_file = "/var/lib/dnscrypt-proxy/public_resolvers.md";
|
cache_file = "/var/lib/dnscrypt-proxy/public_resolvers.md";
|
||||||
minisign_key = "RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3";
|
minisign_key = "RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3";
|
||||||
};
|
};
|
||||||
|
@ -52,22 +39,9 @@ in
|
||||||
|
|
||||||
# Anonymized DNS
|
# Anonymized DNS
|
||||||
anonymized_dns.routes = [
|
anonymized_dns.routes = [
|
||||||
{
|
{ server_name = "*"; via = [ "anon-plan9-dns" "anon-v.dnscrypt.up-ipv4" ]; }
|
||||||
server_name = "*";
|
|
||||||
via = [
|
|
||||||
"anon-plan9-dns"
|
|
||||||
"anon-v.dnscrypt.up-ipv4"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
anonymized_dns.skip_incompatible = true;
|
anonymized_dns.skip_incompatible = true;
|
||||||
|
|
||||||
# Cloaking rules
|
|
||||||
cloaking_rules = pkgs.writeText "cloaking_rules.txt" (
|
|
||||||
lib.strings.concatStringsSep "\n" (
|
|
||||||
lib.attrsets.mapAttrsToList (name: ip: "${name} ${ip}") cfg.cloaking-rules
|
|
||||||
)
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
{ config, lib, ... }:
|
|
||||||
with { inherit (lib) mkOption types mkIf; };
|
|
||||||
let
|
|
||||||
cfg = config.services.nix-build-farm;
|
|
||||||
hosts = import ./hosts.nix;
|
|
||||||
|
|
||||||
build-user = "nix-builder";
|
|
||||||
|
|
||||||
isBuilder = host: host ? "builder";
|
|
||||||
allBuilders = lib.filterAttrs (_: isBuilder) hosts;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.services.nix-build-farm = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = "Whether to enable nix-build-farm as a client";
|
|
||||||
};
|
|
||||||
hostname = mkOption {
|
|
||||||
type = types.enum (builtins.attrNames hosts);
|
|
||||||
description = "The hostname as listed in ./hosts.nix file";
|
|
||||||
};
|
|
||||||
privateKeyFile = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
description = "The path to the private SSH key file";
|
|
||||||
};
|
|
||||||
|
|
||||||
ipAddrs = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = "The ip addresses to limit access to";
|
|
||||||
default = "11.0.0.*";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable (
|
|
||||||
let
|
|
||||||
host = hosts.${cfg.hostname};
|
|
||||||
otherHosts = lib.filterAttrs (name: _: name != cfg.hostname) hosts;
|
|
||||||
otherBuilders = lib.filterAttrs (name: _: name != cfg.hostname) allBuilders;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
nix.distributedBuilds = true;
|
|
||||||
nix.buildMachines = lib.mapAttrsToList (
|
|
||||||
name: host:
|
|
||||||
{
|
|
||||||
hostName = host.host;
|
|
||||||
sshUser = build-user;
|
|
||||||
sshKey = cfg.privateKeyFile;
|
|
||||||
}
|
|
||||||
// host.builder
|
|
||||||
) otherBuilders;
|
|
||||||
|
|
||||||
users = mkIf (isBuilder host) {
|
|
||||||
users.${build-user} = {
|
|
||||||
description = "Nix build farm user";
|
|
||||||
group = build-user;
|
|
||||||
isNormalUser = true;
|
|
||||||
openssh.authorizedKeys.keys = lib.mapAttrsToList (
|
|
||||||
_: host: ''from="${cfg.ipAddrs}" ${host.pubKey}''
|
|
||||||
) otherHosts;
|
|
||||||
};
|
|
||||||
groups.${build-user} = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
nix.settings.trusted-users = mkIf (isBuilder host) [ build-user ];
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
{
|
|
||||||
cloud = {
|
|
||||||
host = "cloud.tinc";
|
|
||||||
pubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE87ddj0fTH0NuvJz0dT5ln7v7zbafXqDVdM2A4ddOb0 root@nki-personal-do";
|
|
||||||
};
|
|
||||||
|
|
||||||
home = {
|
|
||||||
host = "home.tinc";
|
|
||||||
pubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK6N1uTxnbo73tyzD9X7d7OgPeoOpY7JmQaHASjSWFPI nki@kagamiPC";
|
|
||||||
|
|
||||||
builder = {
|
|
||||||
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUhiVTh2NlNBa0kyOTBCc1QzVG1IRVVJQWdXcVFyNm9jRmpjakRRczRoT2ggcm9vdEBrYWdhbWlQQwo=";
|
|
||||||
systems = [
|
|
||||||
"x86_64-linux"
|
|
||||||
"aarch64-linux"
|
|
||||||
];
|
|
||||||
maxJobs = 16;
|
|
||||||
speedFactor = 2;
|
|
||||||
supportedFeatures = [
|
|
||||||
"nixos-test"
|
|
||||||
"benchmark"
|
|
||||||
"big-parallel"
|
|
||||||
"kvm"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
yoga = {
|
|
||||||
host = "yoga.tinc";
|
|
||||||
pubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE6ZrO/xIdmwBCUx80cscBSpJBBTp55OHGrXYBGRXKAw nki@nki-yoga-g8";
|
|
||||||
};
|
|
||||||
|
|
||||||
framework = {
|
|
||||||
host = "framework.tinc";
|
|
||||||
pubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH/g472MaT7YySUhBjxClfmMjpn98qYnKXDKlzWHYwuO nki@nki-framework";
|
|
||||||
|
|
||||||
builder = {
|
|
||||||
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUdOUlBCVFRkNTVVMXY1U1Jac0FjYVdhS3JGZTY0ZjIxOVViODVTQ2NWd28gcm9vdEBua2ktZnJhbWV3b3JrCg==";
|
|
||||||
systems = [
|
|
||||||
"x86_64-linux"
|
|
||||||
"aarch64-linux"
|
|
||||||
];
|
|
||||||
maxJobs = 16;
|
|
||||||
speedFactor = 3;
|
|
||||||
supportedFeatures = [
|
|
||||||
"nixos-test"
|
|
||||||
"benchmark"
|
|
||||||
"big-parallel"
|
|
||||||
"kvm"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
nix.home.tinc:zG2uDy0MbLY0wLuoVH/qKzTD6hTfKZufA2cWDSTCZMA=
|
|
|
@ -1,83 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with {
|
|
||||||
inherit (lib)
|
|
||||||
mkEnableOption
|
|
||||||
mkOption
|
|
||||||
types
|
|
||||||
mkIf
|
|
||||||
;
|
|
||||||
};
|
|
||||||
let
|
|
||||||
cfg = config.nki.services.nix-cache;
|
|
||||||
|
|
||||||
bindAddr = "127.0.0.1:5000";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.nki.services.nix-cache = {
|
|
||||||
enableClient = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = !cfg.enableServer;
|
|
||||||
description = "Enable nix-cache client";
|
|
||||||
};
|
|
||||||
enableServer = mkEnableOption "Enable nix-cache server";
|
|
||||||
|
|
||||||
host = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "nix.home.tinc";
|
|
||||||
};
|
|
||||||
|
|
||||||
publicKey = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = builtins.readFile ./cache-pub-key.pem;
|
|
||||||
};
|
|
||||||
|
|
||||||
privateKeyFile = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
description = "Path to the private key .pem file";
|
|
||||||
};
|
|
||||||
sslCertificate = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
description = "Path to the private key .pem file";
|
|
||||||
};
|
|
||||||
sslCertificateKey = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
description = "Path to the private key .pem file";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
nix.settings = mkIf cfg.enableClient {
|
|
||||||
substituters = lib.mkAfter [ "https://${cfg.host}" ];
|
|
||||||
trusted-public-keys = [ cfg.publicKey ];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.harmonia = mkIf cfg.enableServer {
|
|
||||||
enable = true;
|
|
||||||
signKeyPaths = [ cfg.privateKeyFile ];
|
|
||||||
settings = {
|
|
||||||
bind = bindAddr;
|
|
||||||
priority = 45;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.nginx = mkIf cfg.enableServer {
|
|
||||||
enable = true;
|
|
||||||
recommendedProxySettings = true;
|
|
||||||
virtualHosts = {
|
|
||||||
# ... existing hosts config etc. ...
|
|
||||||
"${cfg.host}" = {
|
|
||||||
forceSSL = true;
|
|
||||||
sslCertificate = cfg.sslCertificate;
|
|
||||||
sslCertificateKey = cfg.sslCertificateKey;
|
|
||||||
locations."/".proxyPass = "http://${bindAddr}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
12
modules/services/pam/gnome-keyring.nix
Normal file
12
modules/services/pam/gnome-keyring.nix
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.nki.services.pam;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.nki.services.pam.enableGnomeKeyring = mkEnableOption "Enable gnome-keyring on login";
|
||||||
|
config = mkIf cfg.enableGnomeKeyring {
|
||||||
|
security.pam.services.login.enableGnomeKeyring = true;
|
||||||
|
# security.pam.services.login.gnupg.enable = true;
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ config, pkgs, lib, ... }:
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.services.swaylock;
|
cfg = config.services.swaylock;
|
||||||
|
|
|
@ -1,141 +0,0 @@
|
||||||
# Edit this configuration file to define what should be installed on
|
|
||||||
# your system. Help is available in the configuration.nix(5) man page
|
|
||||||
# and in the NixOS manual (accessible by running ‘nixos-help’).
|
|
||||||
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
# Include the results of the hardware scan.
|
|
||||||
./hardware-configuration.nix
|
|
||||||
# Fonts
|
|
||||||
../modules/personal/fonts
|
|
||||||
# Encrypted DNS
|
|
||||||
../modules/services/edns
|
|
||||||
# Wireless card
|
|
||||||
./wireless.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
time.timeZone = lib.mkForce "America/Toronto";
|
|
||||||
|
|
||||||
# Sops
|
|
||||||
common.linux.sops.enable = true;
|
|
||||||
common.linux.sops.file = ./secrets.yaml;
|
|
||||||
|
|
||||||
sops.secrets."nix-build-farm/private-key" = {
|
|
||||||
mode = "0400";
|
|
||||||
};
|
|
||||||
services.nix-build-farm.hostname = "framework";
|
|
||||||
services.nix-build-farm.privateKeyFile = config.sops.secrets."nix-build-farm/private-key".path;
|
|
||||||
|
|
||||||
# services.xserver.enable = true;
|
|
||||||
# services.xserver.displayManager.sddm.enable = true;
|
|
||||||
# services.xserver.displayManager.sddm.wayland.enable = true;
|
|
||||||
services.desktopManager.plasma6.enable = true;
|
|
||||||
|
|
||||||
# Power Management
|
|
||||||
services.upower = {
|
|
||||||
enable = true;
|
|
||||||
criticalPowerAction = "Hibernate";
|
|
||||||
|
|
||||||
usePercentageForPolicy = true;
|
|
||||||
percentageCritical = 3;
|
|
||||||
percentageLow = 10;
|
|
||||||
};
|
|
||||||
services.power-profiles-daemon.enable = true;
|
|
||||||
# powerManagement.enable = true;
|
|
||||||
# powerManagement.powertop.enable = true;
|
|
||||||
services.logind.lidSwitch = "suspend-then-hibernate";
|
|
||||||
|
|
||||||
# Printing
|
|
||||||
services.printing.drivers = with pkgs; [ epfl-cups-drivers ];
|
|
||||||
|
|
||||||
# Enable touchpad support (enabled default in most desktopManager).
|
|
||||||
services.libinput.enable = true;
|
|
||||||
# Keyboard
|
|
||||||
services.input-remapper.enable = true;
|
|
||||||
services.input-remapper.serviceWantedBy = [ "multi-user.target" ];
|
|
||||||
hardware.uinput.enable = true;
|
|
||||||
|
|
||||||
# Define a user account. Don't forget to set a password with ‘passwd’.
|
|
||||||
common.linux.username = "nki";
|
|
||||||
|
|
||||||
# Networking
|
|
||||||
common.linux.networking = {
|
|
||||||
hostname = "nki-framework";
|
|
||||||
networks."10-wired".match = "enp*";
|
|
||||||
networks."20-wireless".match = "wlan*";
|
|
||||||
dnsServers = [ "127.0.0.1" ];
|
|
||||||
};
|
|
||||||
nki.services.edns.enable = true;
|
|
||||||
nki.services.edns.ipv6 = true;
|
|
||||||
|
|
||||||
# Backup home
|
|
||||||
services.btrbk.extraPackages = with pkgs; [ sudo ];
|
|
||||||
services.btrbk.instances.home = {
|
|
||||||
onCalendar = "hourly";
|
|
||||||
settings = {
|
|
||||||
snapshot_preserve = "24h 30d 6m 1y";
|
|
||||||
snapshot_preserve_min = "7d";
|
|
||||||
volume."/" = {
|
|
||||||
subvolume.home.snapshot_name = ".backups-home";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Enable fingerprint auth for some stuff
|
|
||||||
security.pam.services.sudo.fprintAuth = true;
|
|
||||||
security.pam.services.swaylock.fprintAuth = true;
|
|
||||||
security.pam.services.login.fprintAuth = true;
|
|
||||||
|
|
||||||
# tinc network
|
|
||||||
sops.secrets."tinc-private-key" = { };
|
|
||||||
services.my-tinc = {
|
|
||||||
enable = true;
|
|
||||||
hostName = "framework";
|
|
||||||
ed25519PrivateKey = config.sops.secrets."tinc-private-key".path;
|
|
||||||
bindPort = 6565;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Secrets
|
|
||||||
# sops.defaultSopsFile = ./secrets.yaml;
|
|
||||||
# sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
|
||||||
|
|
||||||
## tinc
|
|
||||||
# sops.secrets."tinc/ed25519-private-key" = { };
|
|
||||||
# services.my-tinc = {
|
|
||||||
# enable = true;
|
|
||||||
# hostName = "macbooknix";
|
|
||||||
# ed25519PrivateKey = config.sops.secrets."tinc/ed25519-private-key".path;
|
|
||||||
# bindPort = 6565;
|
|
||||||
# };
|
|
||||||
|
|
||||||
services.dbus.packages = with pkgs; [ gcr ];
|
|
||||||
|
|
||||||
services.avahi.enable = true;
|
|
||||||
networking.firewall.allowedTCPPorts = [ 8010 ];
|
|
||||||
|
|
||||||
# Open ports in the firewall.
|
|
||||||
# networking.firewall.allowedTCPPorts = [ ... ];
|
|
||||||
# networking.firewall.allowedUDPPorts = [ ... ];
|
|
||||||
# Or disable the firewall altogether.
|
|
||||||
# networking.firewall.enable = false;
|
|
||||||
|
|
||||||
# Copy the NixOS configuration file and link it from the resulting system
|
|
||||||
# (/run/current-system/configuration.nix). This is useful in case you
|
|
||||||
# accidentally delete configuration.nix.
|
|
||||||
# system.copySystemConfiguration = true;
|
|
||||||
|
|
||||||
# This value determines the NixOS release from which the default
|
|
||||||
# settings for stateful data, like file locations and database versions
|
|
||||||
# on your system were taken. It‘s perfectly fine and recommended to leave
|
|
||||||
# this value at the release version of the first install of this system.
|
|
||||||
# Before changing this value read the documentation for this option
|
|
||||||
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
|
||||||
system.stateVersion = "22.05"; # Did you read the comment?
|
|
||||||
}
|
|
|
@ -1,93 +0,0 @@
|
||||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
|
||||||
# and may be overwritten by future invocations. Please make changes
|
|
||||||
# to /etc/nixos/configuration.nix instead.
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
modulesPath,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
(modulesPath + "/installer/scan/not-detected.nix")
|
|
||||||
];
|
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [
|
|
||||||
"nvme"
|
|
||||||
"xhci_pci"
|
|
||||||
"thunderbolt"
|
|
||||||
"usb_storage"
|
|
||||||
"sd_mod"
|
|
||||||
];
|
|
||||||
boot.initrd.kernelModules = [ ];
|
|
||||||
boot.kernelModules = [ "kvm-amd" ];
|
|
||||||
boot.kernelParams = [
|
|
||||||
# Hibernation
|
|
||||||
"resume=UUID=fa8aaf51-b99f-4fb4-9230-8c0957d8af3f"
|
|
||||||
"resume_offset=5776640" # btrfs inspect-internal map-swapfile -r /var/swapfile
|
|
||||||
];
|
|
||||||
|
|
||||||
fileSystems."/" = {
|
|
||||||
device = "/dev/disk/by-uuid/fa8aaf51-b99f-4fb4-9230-8c0957d8af3f";
|
|
||||||
fsType = "btrfs";
|
|
||||||
options = [
|
|
||||||
"subvol=root"
|
|
||||||
"compress=zstd"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
services.btrfs.autoScrub = {
|
|
||||||
enable = true;
|
|
||||||
interval = "monthly";
|
|
||||||
};
|
|
||||||
|
|
||||||
common.linux.luksDevices."cryptroot" = "/dev/disk/by-uuid/94226aae-6d1c-401a-bfad-3aa5f371a365";
|
|
||||||
|
|
||||||
fileSystems."/home" = {
|
|
||||||
device = "/dev/disk/by-uuid/fa8aaf51-b99f-4fb4-9230-8c0957d8af3f";
|
|
||||||
fsType = "btrfs";
|
|
||||||
options = [
|
|
||||||
"subvol=home"
|
|
||||||
"compress=zstd"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems."/nix" = {
|
|
||||||
device = "/dev/disk/by-uuid/fa8aaf51-b99f-4fb4-9230-8c0957d8af3f";
|
|
||||||
fsType = "btrfs";
|
|
||||||
options = [
|
|
||||||
"subvol=nix"
|
|
||||||
"compress=zstd"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems."/boot" = {
|
|
||||||
device = "/dev/disk/by-uuid/6A0E-4D23";
|
|
||||||
fsType = "vfat";
|
|
||||||
};
|
|
||||||
|
|
||||||
swapDevices = [
|
|
||||||
{
|
|
||||||
device = "/var/swapfile";
|
|
||||||
size = 32 * 1024;
|
|
||||||
priority = 10;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
|
||||||
# (the default) this is the recommended approach. When using systemd-networkd it's
|
|
||||||
# still possible to use this option, but it's recommended to use it in conjunction
|
|
||||||
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
|
||||||
networking.useDHCP = lib.mkDefault true;
|
|
||||||
# networking.interfaces.wlp1s0.useDHCP = lib.mkDefault true;
|
|
||||||
|
|
||||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
|
||||||
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
|
||||||
environment.systemPackages = with pkgs; [ vulkan-validation-layers ];
|
|
||||||
|
|
||||||
# Fingerprint
|
|
||||||
services.fprintd.enable = true;
|
|
||||||
|
|
||||||
hardware.sensor.iio.enable = true; # Orientaion and ambient light sensors
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
tinc-private-key: ENC[AES256_GCM,data:cKtOFrF5FRSHWxe/QxH5O9GAba1WcWeCwW1IOzmbgdtFufRoWbCtYeaLP+WQhQ70z6xobiY9DN8Jrh7mDptKSsfKrrx2SH5JrdpsoINhLMbetXq7E29+q6CkS8NlLgE/KyV8eFjQySNsYiA/+Efq9xj9e1wOmHBDsND/jgiJDkA1qsEIFZg/vuv8LdoRY3TV/oKJ4pao9+70G4H+8Ef1sMZHGNe9qJ94Wa71nNX2fTSjKH5YBbRijMAePWr/IeCpZ9Phs7RqjBs=,iv:l0iB136X7nLVblQjFi7K4f42JKSxdsiLIRy5GPzK1nc=,tag:HAgkvWkl0Rx62ejGZckdKA==,type:str]
|
|
||||||
nix-build-farm:
|
|
||||||
private-key: ENC[AES256_GCM,data:w56sobHrhvVcKbuK15Yj20EqgFrR/5pNy/rcQjlZCiFEfgPC6ZrbsxziIdMTOX+Q4DyllKCKo+g/MIKm5S+s+nIff509ODlILhTtXlZvZlnT9+wvm5oN3WQCdkkqOr1gNnErPupfMxA6V35tNvNBCeomYuM8Xb7TuH4I1fXa5GFeT0Tnp5A2WqWoS1MzXz34CxlKXvoL6i4w7nUngt5zaGr9oMZbSa0pHxEzIhXk6h/lE864QlJid7q/mDok9gh2R80WvArGtNNj9PrT6cNKYIFuXo7vITkSkT3vo9BLflg5sgRxy4+7rBaRla0ziihQvZLtworwo6aNDvEqPqYfiX0TMYPpEWvJpp/HGDJy+Po7b0ZZkwSza+tB0J79vFH2h11Px1XSwXdq757Bn9G4OTb5oKWS5ycBU4xTnnHQBjYTSooFxYyTAvfKNEsB8AHKSuQRZgtVhWoOSPpJ6YL94ClUIT+DTaNmQjwouqNatf/nif+N/FCar8JWZDE+FX1TBu0yLmJie/f0LCdCQx+6IVdyXg7oVCoNiGg0,iv:TeSxlVc0WlOMMUtv/uq3f7JvW/kNCM7LjguhZxL51a4=,tag:m1iuk4pAX/yugM0ObzkJHQ==,type:str]
|
|
||||||
sops:
|
|
||||||
kms: []
|
|
||||||
gcp_kms: []
|
|
||||||
azure_kv: []
|
|
||||||
hc_vault: []
|
|
||||||
age:
|
|
||||||
- recipient: age188tgu3psvywk6shq85mk2q0jdjwd0tcswzwlwu5pa5n3pndx75dq090z59
|
|
||||||
enc: |
|
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmL2Z1RzBWaTI1TDl6WDNa
|
|
||||||
NTNVdEhTSFU5enNlTGVNWTI5anBZb1BtaVhjCm1BRnJDSXl1cWdBRUs1VnREVjBU
|
|
||||||
QWZxdkgzdm9JL0k5WmhDL1RCNTltdm8KLS0tIFhvQTlKMDZiVklTRWd4TzVmc2ll
|
|
||||||
bmpjcWdBV1doZml2NjlzQzdQczJ3alEKBMRP3POxtPIqBWnrvxY/++5jtVE70Uxa
|
|
||||||
EVfhsUO76A/hzyxfzpLEy1QGFE+DB/zlU0CK7HkNGPD2TrBHbzkPJA==
|
|
||||||
-----END AGE ENCRYPTED FILE-----
|
|
||||||
- recipient: age1vgh6kvee8lvxylm7z86fpl3xzjyjs4u3zdfkyf064rjvxk9fpumsew7n27
|
|
||||||
enc: |
|
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2MUxQU0dZOGRaekF4MWdo
|
|
||||||
T0krcERtRTJndFR1RHZmL0t6MjBxMW5PSENNCkR6SUhxQ0FoaEhuaWpiUzJ0MnJE
|
|
||||||
RXRERzVhL0lRVW1iRUlac0c5OHZsckEKLS0tIC9VM1dNZTNzdkFnMWk2YUwvcDNB
|
|
||||||
TDZnVjBaVzZBem5lZDB1MW4xQ0RmZ28K6d7mF+f3ZyilXlSIQGT2pBrTWuYLccE1
|
|
||||||
rYIJjHjFft/2wPX2gAW9VTiwfMT3lKJhJRqNdoie5phV5BZhkb3D9w==
|
|
||||||
-----END AGE ENCRYPTED FILE-----
|
|
||||||
lastmodified: "2024-08-17T14:58:10Z"
|
|
||||||
mac: ENC[AES256_GCM,data:ZCrzXDttLxYUvdLiqM5I17Ys6O3zoOVKq8xP78VaLb3AAoV4RGGQxixKVQ6K9h84e8bFymh512BR7xKa9fqebxTyL1XCqPkRaSZy0aWjbc6QCaK+JD4yqivgO/x5x2xgMpX/ZhPFzKNLpMga61bnm6plvF8ocG+wOqYvj3vL0Ss=,iv:QZ8YJD7h2QD2jqVKo4bg0rwpZSTyyNw6zZDcBfClKPo=,tag:PH2XnTqxV2irymg2+Z+Egg==,type:str]
|
|
||||||
pgp: []
|
|
||||||
unencrypted_suffix: _unencrypted
|
|
||||||
version: 3.9.0
|
|
|
@ -1,14 +0,0 @@
|
||||||
{ pkgs, lib, ... }:
|
|
||||||
{
|
|
||||||
environment.systemPackages = with pkgs; [ iw ];
|
|
||||||
# Disable power_save on boot
|
|
||||||
services.udev.packages = [
|
|
||||||
(pkgs.writeTextFile {
|
|
||||||
name = "udev_disable_wifi_power_save";
|
|
||||||
destination = "/etc/udev/rules.d/10-wifi-power_save.rules";
|
|
||||||
text = ''
|
|
||||||
ACTION=="add", SUBSYSTEM=="net", KERNEL=="wl*", RUN+="${lib.getExe pkgs.iw} dev $name set power_save off"
|
|
||||||
'';
|
|
||||||
})
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
environment.etc = {
|
|
||||||
"wireplumber/wireplumber.conf.d/51-sdac.conf".source = ./sdac.conf.json;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
monitor.alsa.rules = [
|
|
||||||
{
|
|
||||||
matches = [
|
|
||||||
{
|
|
||||||
device.name = "alsa_output.usb-Grace_Design_SDAC-00.*"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
actions = {
|
|
||||||
update-props = {
|
|
||||||
# audio.format = "S24_3LE"
|
|
||||||
audio.rate = 88200
|
|
||||||
api.alsa.period-size = 2
|
|
||||||
api.alsa.headroom = 0
|
|
||||||
api.alsa.disable-batch = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
rule = {
|
|
||||||
matches = {
|
|
||||||
{
|
|
||||||
{ "node.name", "matches", "alsa_output.usb-Grace_Design_SDAC-00.*" },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
apply_properties = {
|
|
||||||
["audio.format"] = "S24_3LE",
|
|
||||||
["audio.rate"] = 44100,
|
|
||||||
["api.alsa.period-size"] = 2,
|
|
||||||
["api.alsa.headroom"] = 0,
|
|
||||||
["api.alsa.disable-batch"] = true
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
table.insert(alsa_monitor.rules, rule)
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue