summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md4
-rw-r--r--nixos/.gitignore1
-rw-r--r--nixos/README.md3
-rw-r--r--nixos/hosts/ev/default.nix1
-rw-r--r--nixos/hosts/ev/kodi.nix5
-rw-r--r--nixos/hosts/ev/metadata.toml1
-rw-r--r--nixos/hosts/hamac/default.nix6
-rw-r--r--nixos/hosts/hamac/metadata.toml1
-rw-r--r--nixos/hosts/tente/default.nix59
-rw-r--r--nixos/hosts/tente/metadata.toml1
-rw-r--r--nixos/hosts/tente/monitoring.nix11
-rw-r--r--nixos/npins/default.nix88
-rw-r--r--nixos/npins/sources.json62
-rw-r--r--nixos/profiles/common/basics.nix3
-rw-r--r--nixos/profiles/common/default.nix2
-rw-r--r--nixos/profiles/common/nixpkgs/overlays.nix33
-rw-r--r--nixos/profiles/common/sanix.nix3
-rw-r--r--nixos/profiles/server/default.nix5
-rw-r--r--nixos/profiles/workstation/create.nix5
-rw-r--r--nixos/profiles/workstation/default.nix16
-rw-r--r--nixos/profiles/workstation/dev.nix12
-rw-r--r--nixos/profiles/workstation/patches/skim-blank.patch73
-rw-r--r--nixos/profiles/workstation/scripts/ed2
-rwxr-xr-xnixos/rebuild17
-rw-r--r--nixos/secrets/secrets.nix3
-rw-r--r--nixos/secrets/vpn-se-presharedKey.age14
-rw-r--r--nixos/secrets/vpn-se-privKey.age21
-rw-r--r--nixos/shared/vpn.nix8
-rw-r--r--user/inkscape/pages.csv47
-rw-r--r--user/sway/config11
-rw-r--r--user/vim/vimrc19
-rw-r--r--user/zed/settings.json22
-rw-r--r--user/zsh/.zshenv1
-rw-r--r--user/zsh/.zshrc1
-rw-r--r--user/zsh/zshrc-workstation.sh2
35 files changed, 446 insertions, 117 deletions
diff --git a/README.md b/README.md
index 74f8cc5..fff89ab 100644
--- a/README.md
+++ b/README.md
@@ -3,6 +3,10 @@
This repository contains my personal config files.
* `nixos/` -- contains my [NixOS](https://nixos.org/) configurations
+ * hosts
+ * ev -- my home server
+ * hamac -- my laptop
+ * tente -- my VPS
* `user/` -- contains my dotfiles
The idea behind this structure is that dotfiles like my
diff --git a/nixos/.gitignore b/nixos/.gitignore
new file mode 100644
index 0000000..c4a847d
--- /dev/null
+++ b/nixos/.gitignore
@@ -0,0 +1 @@
+/result
diff --git a/nixos/README.md b/nixos/README.md
index 67b6cf7..075f812 100644
--- a/nixos/README.md
+++ b/nixos/README.md
@@ -32,7 +32,8 @@ We're assuming that you just installed NixOS by going through the [official inst
nixos-generate-config --dir .
```
3. Rename the `configuration.nix` to `default.nix`.
- Add `# channel="..."` to the start of the `default.nix` file where `...` is the key of a channel pinned in `npins/sources.json`.
+ Create a `metadata.toml` file with a `channel` field
+ where the value is the key of a channel pinned in `npins/sources.json`.
A new channel can be pinned with:
```
diff --git a/nixos/hosts/ev/default.nix b/nixos/hosts/ev/default.nix
index e59ec01..9842f4f 100644
--- a/nixos/hosts/ev/default.nix
+++ b/nixos/hosts/ev/default.nix
@@ -1,4 +1,3 @@
-# channel="nixos-small"
# 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’).
diff --git a/nixos/hosts/ev/kodi.nix b/nixos/hosts/ev/kodi.nix
index 2aea216..3862dfe 100644
--- a/nixos/hosts/ev/kodi.nix
+++ b/nixos/hosts/ev/kodi.nix
@@ -7,7 +7,10 @@ let
in
{
config = {
- users.extraUsers.kodi.isNormalUser = true;
+ users.users.kodi = {
+ isNormalUser = true;
+ extraGroups = ["audio"];
+ };
services = {
cage = {
diff --git a/nixos/hosts/ev/metadata.toml b/nixos/hosts/ev/metadata.toml
new file mode 100644
index 0000000..58f0301
--- /dev/null
+++ b/nixos/hosts/ev/metadata.toml
@@ -0,0 +1 @@
+channel = "nixos-small"
diff --git a/nixos/hosts/hamac/default.nix b/nixos/hosts/hamac/default.nix
index 7085ed3..9c4bde6 100644
--- a/nixos/hosts/hamac/default.nix
+++ b/nixos/hosts/hamac/default.nix
@@ -1,14 +1,8 @@
-# channel="nixos"
# See the configuration.nix(5) man page and the NixOS manual (accessible by running `nixos-help`).
-let
- sources = import ../../npins;
- pkgs-unstable = import sources.nixpkgs-unstable {};
-in
{ config, lib, pkgs, ... }:
{
- _module.args = { inherit pkgs-unstable; };
imports = [
./hardware-configuration.nix
<top/profiles/workstation>
diff --git a/nixos/hosts/hamac/metadata.toml b/nixos/hosts/hamac/metadata.toml
new file mode 100644
index 0000000..fc34e27
--- /dev/null
+++ b/nixos/hosts/hamac/metadata.toml
@@ -0,0 +1 @@
+channel = "nixos"
diff --git a/nixos/hosts/tente/default.nix b/nixos/hosts/tente/default.nix
index 8904ba7..23e94bc 100644
--- a/nixos/hosts/tente/default.nix
+++ b/nixos/hosts/tente/default.nix
@@ -1,4 +1,3 @@
-# channel="nixos-small"
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page, on
# https://search.nixos.org/options and in the NixOS manual (`nixos-help`).
@@ -6,9 +5,9 @@
{ config, lib, pkgs, ... }:
let
- domain = "push-f.com";
+ baseDomain = "push-f.com";
acmeEmail = "martin@push-f.com";
- sources = import ../../npins;
+ sources = import <top/npins>;
helpers = import <top/helpers.nix> { inherit config; };
in
{
@@ -23,29 +22,52 @@ in
./headscale.nix
./matrix.nix
./monitoring.nix
+ "${sources.my-lex-surf}/service.nix"
"${sources.my-osm-proposals}/service.nix"
"${sources.my-geopos-link}/service.nix"
+ "${sources.my-rust-features}/service.nix"
"${sources.my-spec-pub}/service.nix"
];
- web-personal.domain = domain;
+ web-personal.domain = baseDomain;
web-personal.matrixApiDomain = config.matrix.apiDomain;
- git.webUiDomain = "git.${domain}";
- headscale.domain = "tailscale.${domain}";
- matrix.serverName = domain;
- matrix.apiDomain = "matrix.${domain}";
+ git.webUiDomain = "git.${baseDomain}";
+ headscale.domain = "tailscale.${baseDomain}";
+ matrix.serverName = baseDomain;
+ matrix.apiDomain = "matrix.${baseDomain}";
+
+ users.users.www-generator = {
+ isSystemUser = true;
+ group = "www-generator";
+ };
+ users.groups.www-generator = {};
+
+ services.lex-surf =
+ let
+ domain = "lex.surf";
+ in
+ {
+ enable = true;
+ domain = domain;
+ enableACME = true;
+ fetchUser = "www-generator";
+ nginx = {
+ forceSSL = true;
+ extraConfig = helpers.mkNginxConfig domain;
+ };
+ };
services.osm_proposals =
let
- subdomain = "osm-proposals.${domain}";
+ domain = "osm-proposals.${baseDomain}";
in
{
enable = true;
- virtualHost = subdomain;
+ virtualHost = domain;
nginx = {
enableACME = true;
forceSSL = true;
- extraConfig = helpers.mkNginxConfig subdomain;
+ extraConfig = helpers.mkNginxConfig domain;
};
};
@@ -63,6 +85,21 @@ in
};
};
+ services.rust-features =
+ let
+ domain = "rust-features.${baseDomain}";
+ in
+ {
+ enable = true;
+ user = "www-generator";
+ virtualHost = domain;
+ nginx = {
+ enableACME = true;
+ forceSSL = true;
+ extraConfig = helpers.mkNginxConfig domain;
+ };
+ };
+
services.spec-pub =
let
domain = "spec.pub";
diff --git a/nixos/hosts/tente/metadata.toml b/nixos/hosts/tente/metadata.toml
new file mode 100644
index 0000000..58f0301
--- /dev/null
+++ b/nixos/hosts/tente/metadata.toml
@@ -0,0 +1 @@
+channel = "nixos-small"
diff --git a/nixos/hosts/tente/monitoring.nix b/nixos/hosts/tente/monitoring.nix
index 7e92eed..545ae24 100644
--- a/nixos/hosts/tente/monitoring.nix
+++ b/nixos/hosts/tente/monitoring.nix
@@ -57,6 +57,8 @@ in
services.prometheus = {
enable = true;
+ retentionTime = "1y";
+
scrapeConfigs = [
{
job_name = "node";
@@ -180,8 +182,8 @@ in
forward_to = [loki.write.default.receiver]
stage.match {
- // Select messages from systemd services that have LogExtraFields=log_format=logfmt.
- selector = "{__journal_log_format=\"logfmt\"}"
+ // Select messages from systemd services that have LogExtraFields=LOG_FORMAT=logfmt.
+ selector = "{__journal_LOG_FORMAT=\"logfmt\"}"
stage.logfmt {
mapping = { time = "", level = "" }
}
@@ -189,6 +191,11 @@ in
source = "time"
format = "RFC3339"
}
+ stage.template {
+ // The slog package of the Go standard library prints levels as uppercase.
+ source = "level"
+ template = "{{ ToLower .Value }}"
+ }
stage.structured_metadata {
values = { level = "" }
}
diff --git a/nixos/npins/default.nix b/nixos/npins/default.nix
index 5e7d086..6592476 100644
--- a/nixos/npins/default.nix
+++ b/nixos/npins/default.nix
@@ -1,10 +1,53 @@
+/*
+ This file is provided under the MIT licence:
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
# Generated by npins. Do not modify; will be overwritten regularly
let
data = builtins.fromJSON (builtins.readFile ./sources.json);
version = data.version;
+ # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295
+ range =
+ first: last: if first > last then [ ] else builtins.genList (n: first + n) (last - first + 1);
+
+ # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257
+ stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1));
+
+ # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269
+ stringAsChars = f: s: concatStrings (map f (stringToCharacters s));
+ concatMapStrings = f: list: concatStrings (map f list);
+ concatStrings = builtins.concatStringsSep "";
+
+ # If the environment variable NPINS_OVERRIDE_${name} is set, then use
+ # the path directly as opposed to the fetched source.
+ # (Taken from Niv for compatibility)
+ mayOverride =
+ name: path:
+ let
+ envVarName = "NPINS_OVERRIDE_${saneName}";
+ saneName = stringAsChars (c: if (builtins.match "[a-zA-Z0-9]" c) == null then "_" else c) name;
+ ersatz = builtins.getEnv envVarName;
+ in
+ if ersatz == "" then
+ path
+ else
+ # this turns the string into an actual Nix path (for both absolute and
+ # relative paths)
+ builtins.trace "Overriding path of \"${name}\" with \"${ersatz}\" due to set \"${envVarName}\"" (
+ if builtins.substring 0 1 ersatz == "/" then
+ /. + ersatz
+ else
+ /. + builtins.getEnv "PWD" + "/${ersatz}"
+ );
+
mkSource =
- spec:
+ name: spec:
assert spec ? type;
let
path =
@@ -16,16 +59,19 @@ let
mkPyPiSource spec
else if spec.type == "Channel" then
mkChannelSource spec
+ else if spec.type == "Tarball" then
+ mkTarballSource spec
else
builtins.throw "Unknown source type ${spec.type}";
in
- spec // { outPath = path; };
+ spec // { outPath = mayOverride name path; };
mkGitSource =
{
repository,
revision,
url ? null,
+ submodules,
hash,
branch ? null,
...
@@ -33,31 +79,39 @@ let
assert repository ? type;
# At the moment, either it is a plain git repository (which has an url), or it is a GitHub/GitLab repository
# In the latter case, there we will always be an url to the tarball
- if url != null then
- (builtins.fetchTarball {
+ if url != null && !submodules then
+ builtins.fetchTarball {
inherit url;
sha256 = hash; # FIXME: check nix version & use SRI hashes
- })
+ }
else
- assert repository.type == "Git";
let
+ url =
+ if repository.type == "Git" then
+ repository.url
+ else if repository.type == "GitHub" then
+ "https://github.com/${repository.owner}/${repository.repo}.git"
+ else if repository.type == "GitLab" then
+ "${repository.server}/${repository.repo_path}.git"
+ else
+ throw "Unrecognized repository type ${repository.type}";
urlToName =
url: rev:
let
- matched = builtins.match "^.*/([^/]*)(\\.git)?$" repository.url;
+ matched = builtins.match "^.*/([^/]*)(\\.git)?$" url;
short = builtins.substring 0 7 rev;
appendShort = if (builtins.match "[a-f0-9]*" rev) != null then "-${short}" else "";
in
"${if matched == null then "source" else builtins.head matched}${appendShort}";
- name = urlToName repository.url revision;
+ name = urlToName url revision;
in
builtins.fetchGit {
- url = repository.url;
rev = revision;
inherit name;
# hash = hash;
+ inherit url submodules;
};
mkPyPiSource =
@@ -73,8 +127,20 @@ let
inherit url;
sha256 = hash;
};
+
+ mkTarballSource =
+ {
+ url,
+ locked_url ? url,
+ hash,
+ ...
+ }:
+ builtins.fetchTarball {
+ url = locked_url;
+ sha256 = hash;
+ };
in
-if version == 3 then
- builtins.mapAttrs (_: mkSource) data.pins
+if version == 5 then
+ builtins.mapAttrs mkSource data.pins
else
throw "Unsupported format version ${toString version} in sources.json. Try running `npins upgrade`"
diff --git a/nixos/npins/sources.json b/nixos/npins/sources.json
index 5d0d4d9..a633926 100644
--- a/nixos/npins/sources.json
+++ b/nixos/npins/sources.json
@@ -10,6 +10,7 @@
"pre_releases": false,
"version_upper_bound": null,
"release_prefix": null,
+ "submodules": false,
"version": "0.15.0",
"revision": "564595d0ad4be7277e07fa63b5a991b3c645655d",
"url": "https://api.github.com/repos/ryantm/agenix/tarball/0.15.0",
@@ -22,9 +23,22 @@
"url": "https://git.push-f.com/geopos.link"
},
"branch": "master",
- "revision": "ae67ef4f60656557d2408f3a4c2ba01959eef2c5",
+ "submodules": false,
+ "revision": "ab9198d989e0889816e510b66dad1548ce0cfb48",
"url": null,
- "hash": "0r2m5q7zwxms9spbg12gq6q5pc5hz2x6i14qq5s2nxvvf4fsmnnv"
+ "hash": "1xq5sl6rsxk8716ff8hghb3aihdp41ynfwaihllnzqghc6qpigjw"
+ },
+ "my-lex-surf": {
+ "type": "Git",
+ "repository": {
+ "type": "Git",
+ "url": "https://git.push-f.com/lex-surf"
+ },
+ "branch": "master",
+ "submodules": false,
+ "revision": "ef3318a78050ea8aa4f6a65dd4673958c0eadf85",
+ "url": null,
+ "hash": "0v1xmv3slsb965047wi968j3n58dzy227pc5y2g79g2zdppvx94d"
},
"my-osm-proposals": {
"type": "Git",
@@ -33,9 +47,22 @@
"url": "https://git.push-f.com/osm-proposals"
},
"branch": "master",
- "revision": "2ee6afdf3356dea2aebdd48d20dfe9eb07037ba3",
+ "submodules": false,
+ "revision": "0a531bcbd4778ef754583d52d1a6b525ee9702d4",
+ "url": null,
+ "hash": "0phmc0c4di6hial8l5017k03c9zn8iz2zk8cgrzsgypaw1wwsn67"
+ },
+ "my-rust-features": {
+ "type": "Git",
+ "repository": {
+ "type": "Git",
+ "url": "https://git.push-f.com/rust-features"
+ },
+ "branch": "master",
+ "submodules": false,
+ "revision": "60c929acab8bfcd3fdc355288f1a72c1ed303f11",
"url": null,
- "hash": "14j48alysvx4n06my3kspsbplx23sv07nvswrya1x3swmwn4mnnc"
+ "hash": "1vnwhgqqi8ihic6fz6grzikc1dra6myl2b2aly2fgzrcbzrd5390"
},
"my-spec-pub": {
"type": "Git",
@@ -44,28 +71,23 @@
"url": "https://git.push-f.com/spec.pub"
},
"branch": "master",
- "revision": "65610a959cc75482001f14241eb521d7b18c8011",
+ "submodules": false,
+ "revision": "152c8021bef7310ce2501e23de12e892c3ed5032",
"url": null,
- "hash": "0y9wz8kvjc3gv5qf8il5gh9wrx46vinaav1kq0yjiybibhpjskz7"
+ "hash": "1z83lhqzr7yx07qb3icz0pph64aij9a1z17rqxzqmyvjsyyn8nfd"
},
"nixos": {
"type": "Channel",
- "name": "nixos-24.11",
- "url": "https://releases.nixos.org/nixos/24.11/nixos-24.11.714826.04ef94c4c158/nixexprs.tar.xz",
- "hash": "1xfpmwi69c50dbsr00r04v3czh6scccvdai2f5qhr0vi1p1sgvgz"
+ "name": "nixos-25.05",
+ "url": "https://releases.nixos.org/nixos/25.05/nixos-25.05.803751.88331c17ba43/nixexprs.tar.xz",
+ "hash": "1iflm23g9l58m420lm0q7b9ickc7441izzv20726c6h9rryay4md"
},
"nixos-small": {
"type": "Channel",
- "name": "nixos-24.11-small",
- "url": "https://releases.nixos.org/nixos/24.11-small/nixos-24.11.714830.060b03c5d950/nixexprs.tar.xz",
- "hash": "1lxm3y9jqkf8p63xrn6phyp5d763jfwcjxb3vpfqgc8iwq5z4cb9"
- },
- "nixpkgs-unstable": {
- "type": "Channel",
- "name": "nixpkgs-unstable",
- "url": "https://releases.nixos.org/nixpkgs/nixpkgs-25.05pre763845.de0fe301211c/nixexprs.tar.xz",
- "hash": "1iq1a41c1c6i7lr8xpp2bwbm36v8qijisx1jv4126624swr9467l"
+ "name": "nixos-25.05-small",
+ "url": "https://releases.nixos.org/nixos/25.05-small/nixos-25.05.803753.e5cb99555c45/nixexprs.tar.xz",
+ "hash": "028xrxm9ykl7fwdjyy161jaxh3ydngndv8s27x0spws2mwxyckvc"
}
},
- "version": 3
-} \ No newline at end of file
+ "version": 5
+}
diff --git a/nixos/profiles/common/basics.nix b/nixos/profiles/common/basics.nix
index aa6eff9..4ef0c14 100644
--- a/nixos/profiles/common/basics.nix
+++ b/nixos/profiles/common/basics.nix
@@ -3,7 +3,8 @@
{
environment.systemPackages = with pkgs; [
git
- vim
+ # lowPrio because we use vim-full in the workstation profile
+ (lowPrio vim)
file
htop
diff --git a/nixos/profiles/common/default.nix b/nixos/profiles/common/default.nix
index 2b07724..a508a32 100644
--- a/nixos/profiles/common/default.nix
+++ b/nixos/profiles/common/default.nix
@@ -1,7 +1,7 @@
{ config, pkgs, ... }:
let
- sources = import ../../npins;
+ sources = import <top/npins>;
in
{
imports = [
diff --git a/nixos/profiles/common/nixpkgs/overlays.nix b/nixos/profiles/common/nixpkgs/overlays.nix
index 613338f..2834325 100644
--- a/nixos/profiles/common/nixpkgs/overlays.nix
+++ b/nixos/profiles/common/nixpkgs/overlays.nix
@@ -1,4 +1,37 @@
# https://nixos.org/manual/nixpkgs/stable/#sec-overlays-definition
+{ pkgs, ... }:
[
+ # features
+ (final: prev: {
+ scc = prev.scc.overrideAttrs (old: {
+ # https://github.com/boyter/scc/pull/622
+ src = pkgs.fetchFromGitHub {
+ owner = "boyter";
+ repo = "scc";
+ rev = "b73ea06bdc5890821d03502a2cfc4224b19a9b67";
+ hash = "sha256-vcuoKrvludBE0KpXVLkKzB38n0mZJWVB8bYrgJDHKfY=";
+ };
+ });
+ })
+ (final: prev: {
+ skim = prev.skim.overrideAttrs (old: {
+ patches = old.patches ++ [
+ # https://github.com/skim-rs/skim/issues/803
+ ../../workstation/patches/skim-blank.patch
+ ];
+ });
+ })
+ # bug fixes
+ (final: prev: {
+ sway-unwrapped = prev.sway-unwrapped.overrideAttrs (old: {
+ patches = old.patches ++ [
+ # https://github.com/swaywm/sway/pull/8761
+ (pkgs.fetchpatch {
+ url = "https://github.com/swaywm/sway/commit/af7c6ec7b1daeeec67dd17e27fb75f1f1c347327.patch";
+ hash = "sha256-DxN/3IdswZ6q/ksBVr+wgwGe7ScJeg8gFHYQdQAueww=";
+ })
+ ];
+ });
+ })
]
diff --git a/nixos/profiles/common/sanix.nix b/nixos/profiles/common/sanix.nix
index a20db24..626aa73 100644
--- a/nixos/profiles/common/sanix.nix
+++ b/nixos/profiles/common/sanix.nix
@@ -2,14 +2,13 @@
# Use the Nixpkgs config and overlays from the local files for this NixOS build
nixpkgs = {
config = import ./nixpkgs/config.nix;
- overlays = import ./nixpkgs/overlays.nix;
+ overlays = import ./nixpkgs/overlays.nix { inherit pkgs; };
};
# Makes commands default to the same Nixpkgs, config, overlays and NixOS configuration
nix.nixPath = [
"nixpkgs=${pkgs.path}"
"nixos-config=${toString <nixos-config>}"
- "nixpkgs-overlays=${toString ./nixpkgs/overlays.nix}"
];
environment.variables.NIXPKGS_CONFIG = lib.mkForce (toString ./nixpkgs/config.nix);
diff --git a/nixos/profiles/server/default.nix b/nixos/profiles/server/default.nix
index ac24e20..07dcd4b 100644
--- a/nixos/profiles/server/default.nix
+++ b/nixos/profiles/server/default.nix
@@ -13,4 +13,9 @@
};
};
};
+
+ security.sudo.wheelNeedsPassword = false;
+
+ # For remote rebuilds with --target-host.
+ nix.settings.trusted-users = ["@wheel"];
}
diff --git a/nixos/profiles/workstation/create.nix b/nixos/profiles/workstation/create.nix
index 924717f..e902e7b 100644
--- a/nixos/profiles/workstation/create.nix
+++ b/nixos/profiles/workstation/create.nix
@@ -6,6 +6,11 @@
typst
+ (inkscape-with-extensions.override {
+ inkscapeExtensions = [
+ inkscape-extensions.inkstitch
+ ];
+ })
gimp
krita
];
diff --git a/nixos/profiles/workstation/default.nix b/nixos/profiles/workstation/default.nix
index 0332200..052a3c8 100644
--- a/nixos/profiles/workstation/default.nix
+++ b/nixos/profiles/workstation/default.nix
@@ -2,13 +2,7 @@
let
cfg = config.workstation;
- sources = import ../../npins;
- nixGit = import (pkgs.fetchFromGitHub {
- owner = "NixOS";
- repo = "nix";
- rev = "7a8a28629c61c75af010ff0a5a88c16c4ce536c7";
- sha256 = "sha256-oqG9AFPXBneKVmiWa9b9ai0hGZqHVKVFaFLdBZitSUA=";
- });
+ sources = import <top/npins>;
in
{
options.workstation = {
@@ -45,6 +39,10 @@ in
npins
(callPackage "${sources.agenix}/pkgs/agenix.nix" {})
+ vim-full
+ skim
+ (writeShellScriptBin "ed" (builtins.readFile ./scripts/ed))
+
unzip
# Android
@@ -60,9 +58,5 @@ in
# Age defaults to this anyway when openssh is enabled.
# We're setting this here for workstations where openssh is disabled.
age.identityPaths = ["/etc/ssh/ssh_host_ed25519_key"];
-
- # Using nix from git for --raw support in nix-instantiate --eval.
- # FUTURE: remove once upgrading to NixOS 25.05
- nix.package = nixGit.packages.${builtins.currentSystem}.default;
};
}
diff --git a/nixos/profiles/workstation/dev.nix b/nixos/profiles/workstation/dev.nix
index e550a4c..ac9b2f1 100644
--- a/nixos/profiles/workstation/dev.nix
+++ b/nixos/profiles/workstation/dev.nix
@@ -1,19 +1,21 @@
-{ config, pkgs, pkgs-unstable, ... }:
+{ config, pkgs, ... }:
{
environment.systemPackages = with pkgs; [
rustup
go
+ golangci-lint
python313
nodejs_22
# CLI tools
+ skim
docker-compose
gnumake
jq
just
sqlite-interactive
- tokei
+ scc
fastmod
license-generator
@@ -22,10 +24,14 @@
gcc # rustc fails if cc linker isn't found
chromium
- pkgs-unstable.zed-editor
+ zed-editor
vscodium
# I'm installing extensions via my install-imperative script.
platformio
+
+ # language servers
+ # rust-analyzer is installed via rustup
+ nixd
];
virtualisation.podman = {
diff --git a/nixos/profiles/workstation/patches/skim-blank.patch b/nixos/profiles/workstation/patches/skim-blank.patch
new file mode 100644
index 0000000..590515c
--- /dev/null
+++ b/nixos/profiles/workstation/patches/skim-blank.patch
@@ -0,0 +1,73 @@
+commit bd0a387d9a4c6ad2cea1a3270e2897f2b740ece4
+Author: Martin Fischer <martin@push-f.com>
+Date: Sun Jun 15 08:37:25 2025 +0200
+
+ feat: add --blank option
+
+diff --git a/skim/src/model/mod.rs b/skim/src/model/mod.rs
+index ff9ec6c..c3d2966 100644
+--- a/skim/src/model/mod.rs
++++ b/skim/src/model/mod.rs
+@@ -93,6 +93,7 @@ pub struct Model {
+ info: InfoDisplay,
+ no_clear_if_empty: bool,
+ theme: Arc<ColorTheme>,
++ hide_results_for_empty_query: bool,
+
+ // timer thread for scheduled events
+ timer: Timer,
+@@ -177,6 +178,7 @@ impl Model {
+ info: InfoDisplay::Default,
+ no_clear_if_empty: false,
+ theme,
++ hide_results_for_empty_query: false,
+ timer: Timer::new(),
+ hb_timer_guard: None,
+
+@@ -201,6 +203,7 @@ impl Model {
+ } else {
+ options.info.clone()
+ };
++ self.hide_results_for_empty_query = options.blank;
+
+ self.use_regex = options.regex;
+
+@@ -316,7 +319,9 @@ impl Model {
+ }
+ };
+ self.num_options += matched.len();
+- self.selection.append_sorted_items(matched);
++ if !self.hide_results_for_empty_query || !self.query.get_query().is_empty() {
++ self.selection.append_sorted_items(matched);
++ }
+ }
+
+ let items_consumed = self.item_pool.num_not_taken() == 0;
+diff --git a/skim/src/options.rs b/skim/src/options.rs
+index 657130a..b78b3e7 100644
+--- a/skim/src/options.rs
++++ b/skim/src/options.rs
+@@ -650,6 +650,10 @@ pub struct SkimOptions {
+ #[arg(long, default_value = "0", help_heading = "Display")]
+ pub header_lines: usize,
+
++ /// Don't show results if the query is empty.
++ #[arg(long, help_heading = "Display")]
++ pub blank: bool,
++
+ // --- History ---
+ /// History file
+ ///
+diff --git a/skim/src/query.rs b/skim/src/query.rs
+index 7a09091..9e9ff24 100644
+--- a/skim/src/query.rs
++++ b/skim/src/query.rs
+@@ -170,7 +170,7 @@ impl Query {
+ .collect()
+ }
+
+- fn get_query(&mut self) -> String {
++ pub fn get_query(&mut self) -> String {
+ match self.mode {
+ QueryMode::Query => self.get_fz_query(),
+ QueryMode::Cmd => self.get_cmd_query(),
diff --git a/nixos/profiles/workstation/scripts/ed b/nixos/profiles/workstation/scripts/ed
new file mode 100644
index 0000000..a3dd433
--- /dev/null
+++ b/nixos/profiles/workstation/scripts/ed
@@ -0,0 +1,2 @@
+#!/usr/bin/env bash
+$VISUAL $(find . -not -path "*/.*" | sk --no-info "$@")
diff --git a/nixos/rebuild b/nixos/rebuild
index 80a52cd..1bc6c39 100755
--- a/nixos/rebuild
+++ b/nixos/rebuild
@@ -11,19 +11,16 @@ if [ ! -f $configPath ]; then
exit 1
fi
-firstLine=$(head -n1 "$configPath")
-
-if ! echo "$firstLine" | grep -E ^"# channel *=" > /dev/null; then
- echo "aborting: $configPath doesn't start with \`# channel=\"...\"\`, where ... is a pin from sources.json"
- exit 1
-fi
-
nix-eval() {
- nix-instantiate --eval --read-write-mode "$@" \
- | tr -d \" # nix-instantiate has no raw output yet (like the experimental nix eval)
+ nix-instantiate --eval --raw --read-write-mode "$@"
}
-channel=$(nix-eval --argstr line "$(echo $firstLine | tr -d \#)" --expr '{line}: (builtins.fromTOML line).channel')
+channel=$(nix-eval --argstr host "$HOSTNAME" --expr '{host}:
+let
+ toml = builtins.readFile ./hosts/${host}/metadata.toml;
+in
+ (builtins.fromTOML toml).channel
+')
nixpkgsPath=$(nix-eval --argstr channel "$channel" --expr '{channel}: (import ./npins).${channel}.outPath')
# nixos-rebuild always reads Nixpkgs from the NIX_PATH,
diff --git a/nixos/secrets/secrets.nix b/nixos/secrets/secrets.nix
index db19967..6021803 100644
--- a/nixos/secrets/secrets.nix
+++ b/nixos/secrets/secrets.nix
@@ -1,10 +1,9 @@
let
- martin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICRBAAt77GXrDtIp6fSjeMHCV3e1ujCE0meetqX3YZpn";
+ martin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF+moAzcnDJsyUalRVdLeJS1D5wezwMDyHuM+Cyk1nQh";
hamac = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJmjbC0gk2s/qDQ+QR//GJH0ZPld99L0EtX7dPP5h2RN";
ev = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINCSypbTOnAYBO32vUUieOsb6ws32gCsDg8nB8JhuFuI";
in
{
"vpn-se-privKey.age".publicKeys = [ martin hamac ev ];
- "vpn-se-presharedKey.age".publicKeys = [ martin hamac ev ];
}
diff --git a/nixos/secrets/vpn-se-presharedKey.age b/nixos/secrets/vpn-se-presharedKey.age
deleted file mode 100644
index 1f56d86..0000000
--- a/nixos/secrets/vpn-se-presharedKey.age
+++ /dev/null
@@ -1,14 +0,0 @@
-age-encryption.org/v1
--> ssh-ed25519 0iFcGg 33qVwdJ+x5d9ezpvYayjZqrwAZQDb7AxvOjQucyVYgQ
-z5/tRvXEE+xSJ4BKQORu4yI+UG2GNaKdTZe0FkN4VyY
--> ssh-ed25519 zNg/mg 9rug5AzVUH/fIDvtSVA0SZkQ0tR+T59VY2UYPrxZfFM
-g49jKdkf+tz/sl9g/RdfkRv/CKneO04rkXPprQYv9rw
--> ssh-ed25519 PHC5tQ H9j903SKpztlrUN/nP7Q8Io/iJLY8ka6aBlOc4d/+iA
-hfQIpLuvT2D8eo5T0MmydivcQE7DFbHhLO809YET0HI
--> W}8>=-grease
-hy4mn+TGe6QPbZud+cppGmgzyed8SgVcaYBumJdxIRy6NQXW8PH2itg6GTIR6Npb
-Nhj9zeSsQvAq8no7z+Q5DsXI7o6iVUDgvoQ1HcUan7WYGqR5MA0
---- WbaGYSFVrJ8+YgzYeLaLXfOsCDMMruUpmFtKvtym57E
-Ik"a#L!1\:
-=.+$@].Hnd]U/q-~ -T
- \ No newline at end of file
diff --git a/nixos/secrets/vpn-se-privKey.age b/nixos/secrets/vpn-se-privKey.age
index 93de475..ca2a8eb 100644
--- a/nixos/secrets/vpn-se-privKey.age
+++ b/nixos/secrets/vpn-se-privKey.age
@@ -1,11 +1,12 @@
age-encryption.org/v1
--> ssh-ed25519 0iFcGg KyKfFePFWpX9AOPw5Sy9UQkucPsQDwrEwRL66e3wdA4
-7DNSkNroD1HaRld0M5uMWtu7dojKUB7DPU9hdTPCXZ8
--> ssh-ed25519 zNg/mg Y0w7MCgwQKqb8FurFOyEshSmfCNoIKi0OnOJUsDeh14
-xILssj5y6XbZ10b39MqqhN42DRQt1AKIdh/Eidin8dA
--> ssh-ed25519 PHC5tQ nfW6lDN4vrv5EOCZGmfe9LEto5FDbU9Vh1LOvrnpvR0
-KrGBpZh7+DalPFoM0rW6ylehDnrmCz2JAOKqMEN4BoQ
--> k4]AeAV-grease pSemvkw @C;y
-vBW8ETA
---- 8Eel9tqXmZ3s7J1CqXlCMTOPAHWD/ftxB7t2DRtHi4A
-T›{vgm We 5Yxr嶘v} ]MCMbHAZ?\Hl'L, \ No newline at end of file
+-> ssh-ed25519 PMTW+A WNGr/0aVmRRmhZ6P6PaWxPML3VRBi59QTD5kQ2AuqXk
+6ivhC1Cm/DVWdCxx+48U0YzJqhj0rmZ195SmjEX+Y4k
+-> ssh-ed25519 zNg/mg I4MbADHlAgwced5uYaEWXNgKvzfyGxKAWiXtg7rgRCg
+ipQGQn7rCu59gHq5DjQIckvqGO5P/LJTtSP8yViEVdQ
+-> ssh-ed25519 PHC5tQ xsy2ivym+ymHacFJeTwll7aJyypoQTg8h/DyaVp98xs
+rwPb2fCAtHKzUQgZ/0SxKZ37MnVb8u74vesd0o5G7yc
+-> @n>>$-grease @J3N{1sN qN_Oh]I K(#
+dA
+--- P0ZI10bTAqn+OPH84hF1V+Qa/X7gqvMZHkYAZQg5zgo
+v:LՓQ "[YU
+KY?+$Aa?`o[k369U0Ȯ8PH[H*g`w \ No newline at end of file
diff --git a/nixos/shared/vpn.nix b/nixos/shared/vpn.nix
index 59fb225..9cbcf45 100644
--- a/nixos/shared/vpn.nix
+++ b/nixos/shared/vpn.nix
@@ -2,7 +2,6 @@
{
age.secrets.vpn-se-privKey.file = ../secrets/vpn-se-privKey.age;
- age.secrets.vpn-se-presharedKey.file = ../secrets/vpn-se-presharedKey.age;
# We're creating the wireguard interfaces in network namespaces so that
# we can use them on demand:
@@ -14,15 +13,14 @@
interfaces.wg-se = {
interfaceNamespace = "se";
- ips = ["10.148.171.71/32"];
+ ips = ["10.128.241.130/32"];
privateKeyFile = config.age.secrets.vpn-se-privKey.path;
peers = [
{
- publicKey = "PyLCXAQT8KkM4T+dUsOQfn+Ub3pGxfGlxkIApuig+hk=";
- presharedKeyFile = config.age.secrets.vpn-se-presharedKey.path;
+ publicKey = "sb61ho9MhaxhJd6WSrryVmknq0r6oHEW7PP5i4lzAgM=";
allowedIPs = ["0.0.0.0/0"];
- endpoint = "se3.vpn.airdns.org:1637";
+ endpoint = "se.gw.xeovo.com:51820";
}
];
};
diff --git a/user/inkscape/pages.csv b/user/inkscape/pages.csv
new file mode 100644
index 0000000..75f8696
--- /dev/null
+++ b/user/inkscape/pages.csv
@@ -0,0 +1,47 @@
+#Inkscape page sizes
+#NAME, WIDTH, HEIGHT, UNIT
+Big embroidery hoop, 200, 280, mm
+Medium embroidery hoop, 200, 200, mm
+Small embroidery hoop, 140, 200, mm
+A4, 210, 297, mm
+A0, 841, 1189, mm
+A1, 594, 841, mm
+A2, 420, 594, mm
+A3, 297, 420, mm
+A5, 148, 210, mm
+A6, 105, 148, mm
+A7, 74, 105, mm
+A8, 52, 74, mm
+A9, 37, 52, mm
+A10, 26, 37, mm
+B0, 1000, 1414, mm
+B1, 707, 1000, mm
+B2, 500, 707, mm
+B3, 353, 500, mm
+B4, 250, 353, mm
+B5, 176, 250, mm
+B6, 125, 176, mm
+B7, 88, 125, mm
+B8, 62, 88, mm
+B9, 44, 62, mm
+B10, 31, 44, mm
+C0, 917, 1297, mm
+C1, 648, 917, mm
+C2, 458, 648, mm
+C3, 324, 458, mm
+C4, 229, 324, mm
+C5, 162, 229, mm
+C6, 114, 162, mm
+C7, 81, 114, mm
+C8, 57, 81, mm
+C9, 40, 57, mm
+C10, 28, 40, mm
+D1, 545, 771, mm
+D2, 385, 545, mm
+D3, 272, 385, mm
+D4, 192, 272, mm
+D5, 136, 192, mm
+D6, 96, 136, mm
+D7, 68, 96, mm
+ID Card (ISO 7810), 85.60, 53.98, mm
+Business Card (Europe), 85, 55, mm
diff --git a/user/sway/config b/user/sway/config
index 2fafff8..cf9101f 100644
--- a/user/sway/config
+++ b/user/sway/config
@@ -18,7 +18,7 @@ set $term foot
set $menu wmenu-run
### Output configuration
-exec_always <~/repos/pad/roadmap.md sed 's/(.\+)//' | set-wallpaper
+exec_always <~/repos/notes/roadmap.md sed 's/(.\+)//' | set-wallpaper
# Example configuration:
#
@@ -57,6 +57,13 @@ input "type:keyboard" {
xkb_file "~/config/colematik/colematik.xkb"
}
+input "10429:2395:UGTABLET_Artist_Pro_16_(Gen2)" {
+ map_to_output "DP-1"
+}
+input "10429:514:Hanvon_Ugee_Shortcut_Remote_Keyboard" {
+ xkb_layout "us"
+}
+
### Key bindings
#
# Basics:
@@ -82,6 +89,8 @@ input "type:keyboard" {
# Exit sway (logs you out of your Wayland session)
bindsym $mod+Shift+q exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -B 'Yes, exit sway' 'swaymsg exit'
+
+ bindsym $mod+m exec foot zsh -c 'cd ~/repos/notes && ed --blank'
#
# Moving around:
#
diff --git a/user/vim/vimrc b/user/vim/vimrc
index b65deb0..952f863 100644
--- a/user/vim/vimrc
+++ b/user/vim/vimrc
@@ -1,4 +1,23 @@
syntax on
+" Don't break words in the middle.
+set linebreak
+
+" Enable easy copying between different vim instances.
+set clipboard=unnamed
+
+" Wayland clipboard workaround (see https://github.com/vim/vim/issues/5157).
+if !empty($WAYLAND_DISPLAY) && executable('wl-copy') && executable('wl-paste')
+ " enable focus reporting
+ let &t_fe = "\<Esc>[?1004h"
+ let &t_fd = "\<Esc>[?1004l"
+
+ augroup wl-clipboard
+ autocmd!
+ autocmd FocusLost * if @" != '' | call system('wl-copy --trim-newline', @") | endif
+ autocmd FocusGained * let @" = system('wl-paste -n')
+ augroup END
+endif
+
" Enable pasting with middle mouse click in insert mode.
set mouse=
diff --git a/user/zed/settings.json b/user/zed/settings.json
index 8614205..d2945a4 100644
--- a/user/zed/settings.json
+++ b/user/zed/settings.json
@@ -25,6 +25,24 @@
}
]
},
+ // By default Zed autoformats a lot of file formats (e.g. HTML, TOML, SQL) with
+ // formatters that aren't used by most projects. So I'm turning format_on_save
+ // off by default and then on for the programming languages that I use.
+ "format_on_save": "off",
+ "languages": {
+ "Go": {
+ "format_on_save": "on"
+ },
+ "Nix": {
+ "language_servers": ["nixd"]
+ },
+ "Rust": {
+ "format_on_save": "on"
+ },
+ "TypeScript": {
+ "format_on_save": "on"
+ }
+ },
"lsp": {
"rust-analyzer": {
"binary": {
@@ -52,7 +70,7 @@
"features": {
"edit_prediction_provider": "none"
},
- "assistant": {
+ "agent": {
"enabled": false,
"version": "2"
},
@@ -61,7 +79,7 @@
"button": false
},
"chat_panel": {
- "button": false
+ "button": "never"
},
"notification_panel": {
"button": false
diff --git a/user/zsh/.zshenv b/user/zsh/.zshenv
new file mode 100644
index 0000000..56a09b1
--- /dev/null
+++ b/user/zsh/.zshenv
@@ -0,0 +1 @@
+export VISUAL=vim
diff --git a/user/zsh/.zshrc b/user/zsh/.zshrc
index bc9fe0c..aa65059 100644
--- a/user/zsh/.zshrc
+++ b/user/zsh/.zshrc
@@ -48,7 +48,6 @@ SAVEHIST=1000000000
export XDG_CACHE_HOME=$HOME/.cache
export XDG_CONFIG_HOME=$HOME/.config
-export VISUAL=vim
export INPUTRC=$XDG_CONFIG_HOME/readline/inputrc
export PYTHON_BASIC_REPL=1 # use readline (Python >=3.13 defaults to its own REPL which has no vi keybindings)
diff --git a/user/zsh/zshrc-workstation.sh b/user/zsh/zshrc-workstation.sh
index e027208..93ac430 100644
--- a/user/zsh/zshrc-workstation.sh
+++ b/user/zsh/zshrc-workstation.sh
@@ -3,7 +3,7 @@
## Aliases
alias code='codium'
alias zed=zeditor
-alias tokei='tokei -s code -n commas'
+alias scc='scc --no-cocomo --no-size --no-gen --sort code'
## Environment variables
export CARGO_HOME="$HOME/.local/share/cargo"