Compare commits

...

9 commits

Author SHA1 Message Date
d9d4e43c35
finally share with ragdoll
Some checks failed
/ lint (push) Failing after 36s
2026-03-16 10:18:32 +01:00
30f81b2b79
make home configs work 2026-03-15 17:47:59 +01:00
f0c21b2e79
icecube config and new colmena 2026-03-13 10:55:01 +01:00
91ba0212b2
edit fish 2026-03-13 10:55:01 +01:00
5f5daf1047
vim again, and tmux too 2026-03-13 10:55:01 +01:00
397fb19e0b
niri 2026-03-10 09:55:24 +01:00
05928785b0
switch to deploy 2026-03-03 14:38:34 +01:00
1d06352181
kanata 2026-03-03 14:38:31 +01:00
ef29bdf5aa
update some niri 2026-03-03 14:38:21 +01:00
38 changed files with 3198 additions and 2632 deletions

33
; Normal file
View file

@ -0,0 +1,33 @@
{
lib,
options,
machine,
...
}:
with lib;
{
options = {
custom.program = mkOption {
type = types.attrsOf (
types.submodule (
{ config, ... }:
{
options = {
name = mkOption {
type = types.string;
};
home-config = mkOption {
type = types.deferredModule;
};
system-config = mkOption {
type = types.deferredModule;
default = _: { };
};
};
config = if builtins.isNull machine.home-only then config.system-config else config.home-config;
}
)
);
};
};
}

133
config.nix Normal file
View file

@ -0,0 +1,133 @@
inputs@{
nixpkgs,
deploy-rs,
self,
pkgsForSystem,
...
}:
rec {
configs =
configs: builtins.foldl' (acc: val: nixpkgs.lib.recursiveUpdate (config val) acc) { } configs;
config =
{
hostname,
capabilities,
type,
home-only ? null,
extra-modules ? [ ],
system ? "x86_64-linux",
deploy-hostname ? hostname,
deploy-options ? {
user = if builtins.isNull home-only then "root" else home-only;
sshUser = if builtins.isNull home-only then "jana" else home-only;
},
home-manager ? builtins.isNull home-only,
stateVersion ? "26.05",
}:
with nixpkgs.lib;
let
inherit (nixpkgs) lib;
matches-capabilities =
# all requirements are contained in the machine capabilities
requirements: lib.all (req: builtins.elem req capabilities) requirements;
program =
{
inputs,
name,
requirements ? [ ],
home-config,
system-config ? (_: { }),
}:
if (matches-capabilities requirements) then
[ (if builtins.isNull home-only then (system-config inputs) else (home-config inputs)) ]
++
(
if builtins.isNull home-only then
[
(_: {
custom.program.${name}.defered-config = home-config;
})
]
else
[ ]
)
else
[ ];
specialArgsForHomeSystem =
{
system,
type,
capabilities,
}:
home-only: {
pkgs = pkgsForSystem system;
flakes = inputs;
inherit inputs;
inherit (inputs.secrets.packages.${system}) secrets;
machine = {
inherit
type
capabilities
stateVersion
home-only
program
;
};
};
specialArgsForSystem = system: specialArgsForHomeSystem system null;
specialArgs = specialArgsForSystem {
inherit system type capabilities;
};
modules =
extra-modules
++ [ ./hosts/${hostname}/configuration.nix ]
++ (
if builtins.isNull home-only then
[ ./defaults/machine-config.nix ]
else
[ ./defaults/machine-or-home-config.nix ]
)
++ (
if home-manager then
[
inputs.home-manager.nixosModules.default
{
home-manager.extraSpecialArgs = specialArgs;
}
]
else
[ ]
);
in
{
deploy.nodes.${hostname} = {
hostname = deploy-hostname;
fastConnection = true;
profiles.system = {
path =
if (builtins.isNull home-only) then
deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.${hostname}
else
deploy-rs.lib.x86_64-linux.activate.home-manager self.nixosConfigurations.${hostname};
}
// deploy-options;
};
nixosConfigurations.${hostname} =
if builtins.isNull home-only then
(nixosSystem {
inherit system modules specialArgs;
})
else
inputs.home-manager.lib.homeManagerConfiguration {
extraSpecialArgs = specialArgsForHomeSystem {
inherit system type capabilities;
} home-only;
inherit modules;
pkgs = pkgsForSystem system;
};
};
}

View file

@ -1,20 +1,20 @@
{
lib,
pkgs,
inputs,
flakes,
machine,
...
}:
{
imports = [
(inputs.self + /modules/machine-type.nix)
(inputs.self + /modules/program.nix)
(inputs.self + /programs)
./machine-or-home-config.nix
];
system.stateVersion = "26.05";
system.stateVersion = machine.stateVersion;
services.resolved.enable = false;
xdg.mime.enable = lib.mkForce false;
# Enable SSH
services.openssh = {
enable = true;

View file

@ -0,0 +1,9 @@
{ inputs, ... }:
{
imports = [
(../modules/program.nix)
(../programs)
(../users)
];
}

722
flake.lock generated

File diff suppressed because it is too large Load diff

132
flake.nix
View file

@ -2,21 +2,16 @@
description = "jana's server infrastructure";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs";
colmena.url = "github:zhaofengli/colmena";
flake-utils.url = "github:numtide/flake-utils";
sops-nix.url = "github:Mic92/sops-nix";
vpn-confinement.url = "github:Maroka-chan/VPN-Confinement";
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
firefox-addons = {
url = "gitlab:rycee/nur-expressions?dir=pkgs/firefox-addons";
inputs.nixpkgs.follows = "nixpkgs";
};
# deployment
deploy-rs.url = "github:serokell/deploy-rs";
# websites
homepage.url = "github:jdonszelmann/homepage";
totpal.url = "github:jdonszelmann/totpal";
harmonica.url = "git+ssh://git@github.com/jdonszelmann/harmonica-tabs";
@ -25,39 +20,39 @@
compiler-construction-2021.url = "git+ssh://forgejo@git.donsz.nl/jana/eelco-visser-compiler-construction.git";
mifg.url = "git+ssh://forgejo@git.donsz.nl/jana/money.is.fckn.gay.git";
# server
raw-data.url = "git+ssh://forgejo@git.donsz.nl/jana/raw-data.git";
secrets.url = "git+ssh://forgejo@git.donsz.nl/jana/server-secrets.git";
sops-nix.url = "github:Mic92/sops-nix";
vpn-confinement.url = "github:Maroka-chan/VPN-Confinement";
# home
nixvim = {
url = "github:nix-community/nixvim";
inputs.nixpkgs.follows = "nixpkgs";
};
t.url = "github:jdonszelmann/t-rs";
dumpasm.url = "github:jdonszelmann/dumpasm";
kitty-search = {
url = "github:trygveaa/kitty-kitten-search";
flake = false;
};
jujutsu = {
url = "github:martinvonz/jj";
inputs.nixpkgs.follows = "nixpkgs";
};
p1n3appl3 = {
url = "github:p1n3appl3/config";
inputs.rahul-config.follows = "rahul-config";
};
rahul-config.url = "github:jdonszelmann/nix-config";
niri-unstable.url = "github:YaLTeR/niri";
niri = {
url = "github:sodiboo/niri-flake";
inputs.niri-unstable.follows = "niri-unstable";
};
matugen = {
url = "github:/InioX/matugen/main";
url = "github:/InioX/matugen/v4.0.0";
inputs.nixpkgs.follows = "nixpkgs";
};
noctalia = {
@ -65,21 +60,23 @@
inputs.nixpkgs.follows = "nixpkgs";
};
pipethon.url = "git+ssh://forgejo@git.donsz.nl/jana/pipethon.git";
firefox-addons = {
url = "gitlab:rycee/nur-expressions?dir=pkgs/firefox-addons";
inputs.nixpkgs.follows = "nixpkgs";
};
firefox-sidebar-css = {
url = "github:drannex/FirefoxSidebar";
flake = false;
};
raw-data.url = "git+ssh://forgejo@git.donsz.nl/jana/raw-data.git";
};
outputs =
{
self,
nixpkgs,
colmena,
flake-utils,
sops-nix,
vpn-confinement,
home-manager,
deploy-rs,
...
}@inputs:
let
@ -95,61 +92,40 @@
})
];
};
configs = import ./config.nix (inputs // { inherit pkgsForSystem; });
in
(configs.configs [
{
colmenaHive = colmena.lib.makeHive self.outputs.colmena;
colmena = {
meta =
let
system = "x86_64-linux";
in
{
nixpkgs = pkgsForSystem system;
specialArgs = {
flakes = inputs;
inherit inputs;
inherit (inputs.secrets.packages.${system}) secrets;
};
};
fili = {
deployment = {
targetHost = "donsz.nl";
targetPort = 22;
replaceUnknownProfiles = false;
tags = [ "server" ];
# buildOnTarget = true;
targetUser = "jana";
};
imports = [
home-manager.nixosModules.home-manager
./hosts/fili/configuration.nix
./users
./default-machine-config.nix
hostname = "fili";
capabilities = [ "cli" ];
type = "server";
extra-modules = [
sops-nix.nixosModules.sops
vpn-confinement.nixosModules.default
];
};
kili = {
deployment = {
allowLocalDeployment = true;
targetHost = null;
replaceUnknownProfiles = false;
tags = [ "laptop" ];
# buildOnTarget = true;
targetUser = "jana";
};
imports = [
home-manager.nixosModules.home-manager
./hosts/kili/configuration.nix
./users
];
};
};
}
{
hostname = "kili";
deploy-hostname = "localhost";
capabilities = [
"cli"
"graphical"
"work"
"fun"
];
type = "pc";
}
{
hostname = "ragdoll";
deploy-hostname = "ragdoll";
home-only = "jana";
capabilities = [
"cli"
"work"
];
type = "pc";
}
])
// flake-utils.lib.eachDefaultSystem (
system:
let
@ -159,17 +135,27 @@
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
lix
colmena.packages.${system}.colmena
(pkgs.writeShellScriptBin "apply" ''
colmena apply --no-substitute
'')
(pkgs.writeShellScriptBin "apply-local" ''
colmena apply-local --sudo
apply $(hostname)
'')
(pkgs.writeShellScriptBin "apply" ''
set -e
if [ $# -eq 0 ]
then
deploy -s
elif [ $# -eq 1 ]
then
deploy -s ".#$@"
else
echo "too many parameters"
exit 1
fi
'')
deploy-rs.packages.${system}.deploy-rs
];
shellHook = "exec $NIX_BUILD_SHELL";
};
packages = custom pkgs;
custom-packages = custom pkgs;
formatter = pkgs.nixfmt;
}
);

View file

@ -6,13 +6,6 @@ _: {
./services
];
custom.machine = {
type = "server";
capabilities = [
"cli"
];
};
networking.nameservers = [
"1.1.1.1"
"9.9.9.9"
@ -50,4 +43,6 @@ _: {
"media"
"nginx"
];
users.groups.media = { };
}

View file

@ -61,7 +61,7 @@ let
};
privateUsers = "no";
config =
imports =
{
config,
pkgs,

View file

@ -150,7 +150,7 @@
wget
# used in deployments
flakes.colmena.defaultPackage."x86_64-linux"
# flakes.deploy.defaultPackage."x86_64-linux"
lix
openssh
];

View file

@ -68,10 +68,21 @@
settings = {
server.externalDomain = "https://photos.donsz.nl";
logging.level = "verbose";
logging.level = "log";
passwordLogin.enabled = false;
storageTemplate = {
enabled = true;
# year / album name or "Other" / y m d / filename
template = "{{y}}/{{#if album}}{{album}}{{else}}Other{{/if}}/{{y}}-{{MM}}-{{dd}}/{{filename}}";
hashVerificationEnabled = true;
};
reverseGeocoding = {
enabled = true;
};
oauth = {
enabled = true;
@ -84,10 +95,7 @@
roleClaim = "immich_role";
scope = "openid email profile groups";
tokenEndpointAuthMethod = "client_secret_post";
# storageLabelClaim: "",
# "mobileOverrideEnabled": false,
# "mobileRedirectUri": "",
storageLabelClaim = "preferred_username";
};
};
mediaLocation = "/storage/storage/media-server/photos";

View file

@ -259,7 +259,7 @@ in
};
};
services.grafana = {
enable = true;
enable = false;
settings = {
server = {

View file

@ -6,19 +6,9 @@
{
imports = [
./hardware-configuration.nix
../../default-machine-config.nix
./kanata.nix
];
custom.machine = {
type = "pc";
capabilities = [
"cli"
"graphical"
"work"
"fun"
];
};
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
@ -52,6 +42,7 @@
extraGroups = [
"networkmanager"
"wheel"
"docker"
];
packages = with pkgs; [ ];
};
@ -61,6 +52,8 @@
# List packages installed in system profile. To search, run:
# $ nix search wget
environment.systemPackages = with pkgs; [
gcc
docker
firefox
kitty
@ -87,8 +80,13 @@
'';
}
) { })
config.boot.kernelPackages.perf
rr
];
virtualisation.docker.enable = true;
services.xserver.enable = true;
services.displayManager.gdm.enable = true;
services.desktopManager.gnome.enable = true;
@ -157,6 +155,13 @@
};
};
programs.steam = {
enable = true;
remotePlay.openFirewall = true; # Open ports in the firewall for Steam Remote Play
dedicatedServer.openFirewall = true; # Open ports in the firewall for Source Dedicated Server
localNetworkGameTransfers.openFirewall = true; # Open ports in the firewall for Steam Local Network Game Transfers
};
# programs.mtr.enable = true;
# programs.gnupg.agent = {
# enable = true;

View file

@ -1,27 +1,43 @@
# 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, ... }:
{
config,
lib,
modulesPath,
...
}:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "xhci_pci" "thunderbolt" "nvme" "usbhid" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
boot.initrd.availableKernelModules = [
"xhci_pci"
"thunderbolt"
"nvme"
"usbhid"
"usb_storage"
"sd_mod"
"rtsx_pci_sdmmc"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/4919727e-d114-4d57-b206-522b5df5fccc";
fileSystems."/" = {
device = "/dev/disk/by-uuid/4919727e-d114-4d57-b206-522b5df5fccc";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/26CD-373C";
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/26CD-373C";
fsType = "vfat";
options = [ "fmask=0077" "dmask=0077" ];
options = [
"fmask=0077"
"dmask=0077"
];
};
swapDevices = [ ];

13
hosts/kili/kanata.nix Normal file
View file

@ -0,0 +1,13 @@
{ pkgs, ... }:
{
# TODO: make kanata system pkgs only
users.groups.uinput = { };
users.extraUsers.jana.extraGroups = [
"uinput"
"input"
];
environment.systemPackages = [ pkgs.kanata-with-cmd ];
services.udev.extraRules = ''
KERNEL=="uinput", MODE="0660", GROUP="uinput", OPTIONS+="static_node=uinput"
'';
}

View file

@ -0,0 +1,7 @@
{
...
}:
{
imports = [ ];
}

View file

@ -1,16 +0,0 @@
{
lib,
...
}:
with lib;
{
options = {
custom.home-info = mkOption {
type = types.submodule {
options = {
};
};
};
};
}

View file

@ -1,25 +0,0 @@
{
lib,
...
}:
with lib;
{
options = {
custom.machine = mkOption {
type = types.submodule {
options = {
type = mkOption {
type = types.enum [
"server"
"pc"
];
};
capabilities = mkOption {
type = types.listOf (types.enum (import ./capabilities.nix));
default = [ "cli" ];
};
};
};
};
};
}

View file

@ -1,6 +1,7 @@
{
inputs@{
lib,
options,
machine,
...
}:
with lib;
@ -8,28 +9,16 @@ with lib;
options = {
custom.program = mkOption {
type = types.attrsOf (
types.submodule (
{ config, ... }:
{
types.submodule (_: {
options = {
name = mkOption {
type = types.string;
};
requirements = mkOption {
type = types.listOf (types.enum (import ./capabilities.nix));
default = [ "cli" ];
};
home-config = mkOption {
defered-config = mkOption {
type = types.deferredModule;
};
system-config = mkOption {
# type = types.attrs;
type = types.deferredModule;
default = { };
};
};
}
)
})
);
};
};

View file

@ -1,30 +1,31 @@
{
args@{
lib,
pkgs,
config,
machine,
...
}:
with lib;
let
cfg = config.custom.users;
machine = config.custom.machine;
inherit (machine) home-only;
inherit (machine) stateVersion;
valid-on-machine =
on:
# TODO: iterate over possibilities
(
if machine.type == "server" then
on.server
else if machine.type == "pc" then
on.pc
else
false;
matches-capabilities =
# all requirements are contained in the machine capabilities
requirements: lib.all (req: builtins.elem req machine.capabilities) requirements;
false
);
users = lib.filterAttrs (_: value: valid-on-machine value.on) cfg;
home-users = lib.filterAttrs (_: value: value.apply-home-configs) users;
stateVersion = config.system.stateVersion;
programs = lib.attrsets.attrValues config.custom.program;
valid-programs = builtins.filter (program: matches-capabilities program.requirements) programs;
in
{
options =
@ -75,35 +76,47 @@ in
};
};
config = lib.mkMerge ([
config = lib.mkMerge [
(
if (!builtins.isNull home-only) then
lib.mkMerge ([
{
home = {
inherit stateVersion;
username = toString home-only;
homeDirectory = "/home/${toString home-only}";
};
}
]
# ++ map (program: program.home-config) programs
)
else
(lib.mkMerge ([
{
users.extraUsers = lib.mapAttrs (name: value: {
isNormalUser = true;
extraGroups = value.groups;
openssh.authorizedKeys.keys = value.keys;
shell = value.shell;
inherit (value) shell;
description = name;
}) users;
home-manager.users = lib.mapAttrs (
name: value:
(
{ pkgs, lib, ... }:
{
(_: {
imports = (
[
./home-info.nix
]
++ (map (program: program.home-config) valid-programs)
++ (map (program: program.defered-config) programs)
);
home = {
inherit stateVersion;
username = name;
homeDirectory = "/home/${name}";
};
}
)
})
) home-users;
}
]);
]))
)
];
}

View file

@ -1 +0,0 @@
Ptmux;_Gq=2,a=d,d=a\\

View file

@ -1,5 +1,9 @@
_: {
imports = [
{ machine, lib, ... }@inputs:
{
imports = lib.concatLists [
[
./xdg.nix
./nvim
./fish
./kanata
@ -10,9 +14,11 @@ _: {
./niri
./zed
./firefox
];
]
custom.program.graphcial-packages = {
(machine.program {
name = "graphcial-packages";
inherit inputs;
requirements = [ "graphical" ];
home-config =
{ pkgs, ... }:
@ -21,15 +27,20 @@ _: {
spotify
obsidian
element-desktop
chromium
# chromium
bind.dnsutils
mpv
vlc
libreoffice-qt
hunspell
hunspellDicts.en_US
];
};
};
})
custom.program.discord = {
(machine.program {
name = "discord";
inherit inputs;
requirements = [ "graphical" ];
home-config =
{
@ -143,9 +154,11 @@ _: {
})
];
};
};
})
custom.program.fun-packages = {
(machine.program {
name = "fun-packages";
inherit inputs;
requirements = [ "fun" ];
home-config =
{ pkgs, ... }:
@ -155,9 +168,11 @@ _: {
prismlauncher
];
};
};
})
custom.program.cli-packages = {
(machine.program {
name = "cli-packages";
inherit inputs;
requirements = [ "cli" ];
home-config =
{ config, pkgs, ... }:
@ -182,6 +197,7 @@ _: {
comma
unzip
pciutils
difftastic
# dev tools
gdb
@ -220,38 +236,6 @@ _: {
'';
};
};
};
custom.program.homedirs = {
home-config =
{ config, ... }:
{
home.file = {
"dl".source = config.lib.file.mkOutOfStoreSymlink "${config.xdg.userDirs.download}";
"doc".source = config.lib.file.mkOutOfStoreSymlink "${config.xdg.userDirs.documents}";
};
};
};
custom.program.xdg = {
home-config =
{ config, ... }:
{
xdg = {
enable = true;
configHome = "${config.home.homeDirectory}/.config";
userDirs = {
enable = true;
documents = "${config.home.homeDirectory}/Documents";
desktop = "${config.home.homeDirectory}/Documents";
download = "${config.home.homeDirectory}/Downloads";
music = "${config.home.homeDirectory}/Documents/personal/music";
pictures = "${config.home.homeDirectory}/Documents/personal/pictures";
};
mime.enable = true;
};
};
};
})
];
}

View file

@ -1,6 +1,10 @@
_: {
custom.program.firefox.requirements = [ "graphical" ];
custom.program.firefox.home-config =
inputs@{ machine, ... }:
{
imports = machine.program {
name = "firefox";
inherit inputs;
requirements = [ "graphical" ];
home-config =
{
config,
flakes,
@ -162,4 +166,5 @@ _: {
defaultApplications."x-scheme-handler/unknown" = [ "firefox.desktop" ];
};
};
};
}

View file

@ -1,6 +1,10 @@
_: {
custom.program.fish.requirements = [ "cli" ];
custom.program.fish.home-config =
inputs@{ machine, ... }:
{
imports = machine.program {
name = "fish";
inherit inputs;
requirements = [ "cli" ];
home-config =
{
config,
pkgs,
@ -175,6 +179,19 @@ _: {
interactiveShellInit = ''
fish_vi_key_bindings
bind \e\[3\;5~ kill-word
bind \cH backward-kill-word
bind \cV beginning-of-line
bind \f end-of-line
bind -M insert \e\[3\;5~ kill-word
bind -M insert \cH backward-kill-word
bind -M insert \cV beginning-of-line
bind -M insert \f end-of-line
bind \cl 'clear; commandline -f repaint'
bind -M insert \cl 'clear; commandline -f repaint'
set -g sponge_successful_exit_codes 0
set -g sponge_allow_previously_successful false
set -g sponge_delay 10
@ -212,6 +229,7 @@ _: {
function fish_greeting
${pkgs.blahaj}/bin/blahaj -s
echo "welcome to $(uname -n), $(whoami)!"
end
'';
};
@ -238,4 +256,5 @@ _: {
'';
};
};
};
}

View file

@ -1,6 +1,10 @@
_: {
custom.program.git.requirements = [ "cli" ];
custom.program.git.home-config = _: {
inputs@{ machine, ... }:
{
imports = machine.program {
name = "git";
inherit inputs;
requirements = [ "cli" ];
home-config = _: {
programs.git = {
enable = true;
signing.key = "/home/jana/.ssh/id_ed25519.pub";
@ -36,4 +40,5 @@ _: {
enableGitIntegration = true;
};
};
};
}

View file

@ -1,6 +1,10 @@
_: {
custom.program.jujutsu.requirements = [ "cli" ];
custom.program.jujutsu.home-config =
inputs@{ machine, ... }:
{
imports = machine.program {
name = "jujutsu";
inherit inputs;
requirements = [ "cli" ];
home-config =
{ config, pkgs, ... }:
{
programs.jujutsu = {
@ -45,9 +49,9 @@ _: {
fsmonitor.backend = "watchman";
fsmonitor.watchman.register-snapshot-trigger = true;
# revsets.log = "@ | ancestors(trunk()..(visible_heads() & mine()), 2) | trunk()";
revsets.log = "@ | ancestors(trunk()..(visible_heads() & mine()), 2) | trunk()";
# revsets.log = "trunk()..@ | @..trunk() | trunk() | @:: | fork_point(trunk() | @)";
revsets.log = "trunk() | ancestors(trunk()..heads(((trunk()..visible_heads()) & my() | @)::), 2)";
# revsets.log = "trunk() | ancestors(trunk()..heads(((trunk()..visible_heads()) & my() | @)::), 2)";
revset-aliases = {
"my()" = "user(\"${config.programs.jujutsu.settings.user.email}\")";
@ -190,4 +194,5 @@ _: {
};
};
};
};
}

View file

@ -1,4 +1,4 @@
{ pkgs, ... }:
inputs@{ machine, pkgs, ... }:
let
kanata-config = ''
(defcfg
@ -27,24 +27,28 @@ let
(deflayer control
@esc
grv 1 2 3 4 5 6 7 8 9 0 - = bspc
tab q w e @replay t y u i o p @wup @wdown \
@cap a s d f g left down up right ; ' bspc
tab @mcleft @mup @mcright @replay t y u i o p @wup @wdown \
@cap @mleft @mdown @mright f g left down up right ; ' bspc
lsft z x C-c v bspc n @macro , . C-f rsft
lctl lmet lalt spc ralt @rctl
)
(deflayermap (programming)
f (macro f n spc)
w (macro w h e r e spc)
l (macro l o o p { ret)
u (macro u s e spc)
i (macro i m p o r t spc)
s (macro s e l f spc)
(deflayermap (other)
w @mup
a @mleft
s @mdown
d @mright
q @mcleft
e @mcright
[ @wup
] @wdown
)
(defalias
;; hold esc
esc (tap-hold 800 800 esc caps)
esc (tap-hold 200 200 C-k (macro C-f esc))
;; control
cap (tap-hold-release 200 200
@ -58,6 +62,14 @@ let
lmet
)
mup (movemouse-up 1 1)
mleft (movemouse-left 1 1)
mdown (movemouse-down 1 1)
mright (movemouse-right 1 1)
mcleft mlft
mcright mrgt
macro (dynamic-macro-record 0)
replay (dynamic-macro-play 0)
@ -68,15 +80,18 @@ let
rctl (
tap-hold-release
200 200
C-k (layer-while-held programming)
C-k (layer-while-held other)
)
)
'';
in
{
custom.program.kanata.requirements = [ "graphical" ];
custom.program.kanata.home-config =
{ pkgs, config, ... }:
imports = machine.program {
name = "kanata";
inherit inputs;
requirements = [ "graphical" ];
home-config =
{ pkgs, ... }:
{
systemd.user.services.kanata = {
Unit = {
@ -100,6 +115,7 @@ in
text = kanata-config;
};
};
};
# custom.program.kanata.system-config =
# { pkgs, ... }:
@ -111,15 +127,6 @@ in
# reboot or sudo udevadm control --reload-rules && sudo udevadm trigger
# sudo modprobe uinput
users.groups.uinput = { };
users.extraUsers.jana.extraGroups = [
"uinput"
"input"
];
environment.systemPackages = [ pkgs.kanata-with-cmd ];
services.udev.extraRules = ''
KERNEL=="uinput", MODE="0660", GROUP="uinput", OPTIONS+="static_node=uinput"
'';
# };
}

View file

@ -1,6 +1,10 @@
_: {
custom.program.kitty.requirements = [ "graphical" ];
custom.program.kitty.home-config =
inputs@{ machine, ... }:
{
imports = machine.program {
name = "kitty";
inherit inputs;
requirements = [ "graphical" ];
home-config =
{ pkgs, flakes, ... }:
{
home.packages = pkgs.custom.maple-fonts-pack;
@ -9,7 +13,7 @@ _: {
enable = true;
font = {
name = "Maple Mono NF";
size = 13.0;
size = 11.0;
package = pkgs.jetbrains-mono;
};
@ -49,6 +53,10 @@ _: {
"ctrl+0" = "change_font_size all 0";
# "ctrl+/" = "send_text all ";
"super+~" = "no_op";
# required for vim!!
# terminals map ctrl+i to tab. I want them to do different things in vim.
"ctrl+i" = "send_text all \\x01";
};
extraConfig = ''
@ -56,4 +64,5 @@ _: {
'';
};
};
};
}

View file

@ -1,12 +1,15 @@
_: {
custom.program.niri.requirements = [ "graphical" ];
custom.program.niri.home-config =
{
config,
pkgs,
flakes,
lib,
...
inputs@{ machine, ... }:
{
imports = machine.program {
name = "niri";
inherit inputs;
requirements = [ "graphical" ];
home-config =
{ config
, pkgs
, flakes
, lib
, ...
}:
let
noctalia =
@ -45,6 +48,7 @@ _: {
playerctl
# brightness control
brightnessctl
pavucontrol
fira
jetbrains-mono
@ -81,6 +85,21 @@ _: {
# focus the external screen first
focus-at-startup = true;
};
outputs."LG Electronics LG ULTRAWIDE 409NTAB3P496" = {
mode = {
width = 3440;
height = 1440;
refresh = 59.987;
};
position = {
x = -3440;
y = 240;
};
# focus the external screen first
focus-at-startup = true;
};
};
home.sessionVariables = {
@ -112,6 +131,13 @@ _: {
click-method = "clickfinger";
natural-scroll = false;
};
focus-follows-mouse = {
enable = true;
max-scroll-amount = "0%";
};
workspace-auto-back-and-forth = true;
};
debug = {
@ -123,10 +149,10 @@ _: {
size = 10;
};
gestures.hot-corners.enable = false;
gestures.hot-corners.enable = true;
layout = {
gaps = 5;
gaps = 8;
center-focused-column = "never";
always-center-single-column = true;
@ -152,29 +178,29 @@ _: {
focus-ring = {
width = 1;
active.color = "#${config.programs.matugen.theme.colors.primary.default}";
inactive.color = "#${config.programs.matugen.theme.colors.surface.default}";
urgent.color = "#${config.programs.matugen.theme.colors.error.default}";
active.color = "${config.programs.matugen.theme.colors.primary.default.color}";
inactive.color = "${config.programs.matugen.theme.colors.surface.default.color}";
urgent.color = "${config.programs.matugen.theme.colors.error.default.color}";
};
border = {
active.color = "#${config.programs.matugen.theme.colors.primary.default}";
inactive.color = "#${config.programs.matugen.theme.colors.surface.default}";
urgent.color = "#${config.programs.matugen.theme.colors.error.default}";
active.color = "${config.programs.matugen.theme.colors.primary.default.color}";
inactive.color = "${config.programs.matugen.theme.colors.surface.default.color}";
urgent.color = "${config.programs.matugen.theme.colors.error.default.color}";
};
shadow = {
color = "#${config.programs.matugen.theme.colors.shadow.default}70";
color = "${config.programs.matugen.theme.colors.shadow.default.color}70";
};
tab-indicator = {
active.color = "#${config.programs.matugen.theme.colors.primary.default}";
inactive.color = "#${config.programs.matugen.theme.colors.primary_container.default}";
urgent.color = "#${config.programs.matugen.theme.colors.error.default}";
active.color = "${config.programs.matugen.theme.colors.primary.default.color}";
inactive.color = "${config.programs.matugen.theme.colors.primary_container.default.color}";
urgent.color = "${config.programs.matugen.theme.colors.error.default.color}";
};
insert-hint = {
display.color = "#${config.programs.matugen.theme.colors.primary.default}80";
display.color = "${config.programs.matugen.theme.colors.primary.default.color}80";
};
};
@ -194,14 +220,29 @@ _: {
window-rules = [
{
matches = [ { title = "Extension: (Bitwarden Password Manager).*"; } ];
matches = [
{
app-id = "firefox$";
title = "Extension: (Bitwarden Password Manager)";
}
];
open-floating = true;
open-focused = true;
block-out-from = "screen-capture";
}
{
matches = [
{
app-id = "firefox$";
title = "^Picture-in-Picture$";
}
];
open-floating = true;
}
{
matches = [ { app-id = "firefox"; } ];
matches = [{ app-id = "firefox"; }];
open-on-workspace = "browser";
}
@ -215,6 +256,7 @@ _: {
app-id = "steam";
title = "Steam Settings";
}
{ app-id = "pavucontrol"; }
];
open-floating = true;
}
@ -270,7 +312,7 @@ _: {
action.spawn = noctalia "sessionMenu toggle";
};
"Mod+O" = {
"Mod+P" = {
hotkey-overlay.title = "Run an Application";
action.spawn = noctalia "launcher toggle";
};
@ -289,11 +331,11 @@ _: {
"XF86AudioRaiseVolume" = {
allow-when-locked = true;
action.spawn-sh = "wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.1+";
action.spawn-sh = "wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.05+";
};
"XF86AudioLowerVolume" = {
allow-when-locked = true;
action.spawn-sh = "wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.1-";
action.spawn-sh = "wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.05-";
};
"XF86AudioMute" = {
allow-when-locked = true;
@ -321,15 +363,15 @@ _: {
};
"Mod+Period" = {
allow-when-locked = true;
action.spawn-sh = "playerctl previous";
action.spawn-sh = "playerctl nest";
};
"Mod+Comma" = {
allow-when-locked = true;
action.spawn-sh = "playerctl next";
action.spawn-sh = "playerctl previous";
};
"Mod+Slash" = {
allow-when-locked = true;
action.spawn-sh = "playerctl next";
action.spawn-sh = "playerctl play-pause";
};
# TODO
@ -532,9 +574,6 @@ _: {
{
id = "plugin:catwalk";
}
{
id = "plugin:brightness";
}
];
center = [
{
@ -554,8 +593,14 @@ _: {
{
id = "Bluetooth";
}
{
id = "Brightness";
}
{
id = "Volume";
}
]
++ [ { id = "Battery"; } ]
++ [{ id = "Battery"; }]
++ [
{
id = "KeyboardLayout";
@ -613,9 +658,10 @@ _: {
# appearance
"org/gnome/desktop/interface" = {
color-scheme = "prefer-dark";
enable-hot-corners = false;
enable-hot-corners = true;
gtk-enable-primary-paste = false;
};
};
};
};
}

View file

@ -19,134 +19,32 @@ local esc = vim.api.nvim_replace_termcodes(
)
local api = require('Comment.api')
vim.keymap.set("n", "<C-_>", ":lua require('Comment.api').toggle.linewise.current()<CR> j", { remap = true })
vim.keymap.set("n", "<C-_>", ":lua require('Comment.api').toggle.linewise.current()<CR>j", { remap = true })
vim.keymap.set("i", "<C-_>", "<c-o>:lua require('Comment.api').toggle.linewise.current()<CR>", { remap = true })
vim.keymap.set("x", "<C-_>", function()
vim.api.nvim_feedkeys(esc, 'nx', false)
api.toggle.linewise(vim.fn.visualmode())
end, { remap = true })
vim.keymap.set('n', 'gr', (function() builtin.lsp_references({jump_type="vsplit"}) end), {})
vim.keymap.set('n', 'gd', (function() builtin.lsp_definitions({jump_type="vsplit"}) end), {})
vim.keymap.set('n', 'gt', (function() builtin.lsp_type_definitions({jump_type="vsplit"}) end), {})
local barbar_state = require("barbar.state")
function find_windows_with_buffer(bufnum)
windows = {}
local window_list = vim.api.nvim_list_wins()
-- vim.keymap.set('n', 'gr', (function() builtin.lsp_references({jump_type="vsplit"}) end), {})
-- vim.keymap.set('n', 'gd', (function() builtin.lsp_definitions({jump_type="vsplit"}) end), {})
-- vim.keymap.set('n', 'gt', (function() builtin.lsp_type_definitions({jump_type="vsplit"}) end), {})
-- vim.keymap.set('n', 'gt', (function() builtin.lsp_type_definitions({jump_type="vsplit"}) end), {})
for _, window in ipairs(window_list) do
local win_info = vim.fn.getwininfo(window)
if win_info ~= nil then
for _, buf in ipairs(win_info) do
if buf.bufnr == bufnum then
table.insert(windows, window)
end
end
end
end
return windows
end
function num_useful_windows()
local window_list = vim.api.nvim_tabpage_list_wins(0)
local num = 0
for _, window in ipairs(window_list) do
local win_info = vim.fn.getwininfo(window)
if win_info ~= nil then
for _, win_info in ipairs(win_info) do
if buf_is_useful(win_info.bufnr) then
num = num + 1
end
end
end
end
return num
end
function buf_is_useful(bufnr)
local bufname = vim.api.nvim_buf_get_name(bufnr)
-- if the window's buffer has no name, it's not useful
if bufname == '' then
return false
end
-- print("bufname: ", bufname)
-- if the window's buffer is read only, it's not useful
local readonly = vim.api.nvim_buf_get_option(bufnr, 'readonly')
if readonly then
-- print("=readonly")
return false
end
-- -- if the buffer is not listed, it's not useful
local listed = vim.api.nvim_buf_get_option(bufnr, 'buflisted')
if not listed then
-- print("=unlisted")
return false
end
local buftype = vim.api.nvim_buf_get_option(bufnr, 'buftype')
if buftype == "quickfix" then
-- print("=readonly")
return false
end
local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
if #lines > 1 or (#lines == 1 and #lines[1] > 0) then
return true -- If the buffer has content, return false
else
return false
end
-- the window contains a useful buffer
return true
end
function quit_window(window)
vim.api.nvim_win_call(window, function()
vim.cmd "quit"
end)
end
vim.api.nvim_create_user_command('CloseBuffer', function (opts)
if num_useful_windows() > 1 then
vim.cmd {
cmd = "quit",
bang = opts.bang,
}
else
vim.cmd {
cmd = "BufferDelete",
bang = opts.bang,
}
if not buf_is_useful(vim.api.nvim_get_current_buf()) then
vim.cmd {
cmd = "quit",
bang = opts.bang,
}
end
end
end, { desc = "Close Current Buffer", bang = true, })
local function close_floating()
for _, win in ipairs(vim.api.nvim_list_wins()) do
local config = vim.api.nvim_win_get_config(win)
if config.relative ~= "" then
vim.api.nvim_win_close(win, false)
end
end
end
vim.keymap.set("n", "<Esc>", close_floating, { desc = "Close floats, clear highlights" })
-- local function close_floating()
-- for _, win in ipairs(vim.api.nvim_list_wins()) do
-- local config = vim.api.nvim_win_get_config(win)
-- if config.relative ~= "" then
-- vim.api.nvim_win_close(win, false)
-- end
-- end
-- end
--
-- vim.keymap.set("n", "<Esc>", close_floating, { desc = "Close floats, clear highlights" })
local builtin = require('telescope.builtin')

View file

@ -1,15 +1,68 @@
_: {
custom.program.nvim.requirements = [ "cli" ];
custom.program.nvim.home-config =
{ pkgs, flakes, ... }:
inputs@{ machine, ... }:
{
imports = machine.program {
name = "nvim";
inherit inputs;
requirements = [ "cli" ];
home-config =
{
pkgs,
flakes,
lib,
...
}:
let
nvim_mime_types = [
"application/x-zerosize"
"text/english"
"text/plain"
"text/x-makefile"
"text/x-c++hdr"
"text/x-c++src"
"text/x-chdr"
"text/x-csrc"
"text/x-java"
"text/x-moc"
"text/x-pascal"
"text/x-tcl"
"text/x-tex"
"application/x-shellscript"
"text/x-c"
"text/x-c++"
];
desktop-entry-name = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanvim";
desktop-entry = pkgs.makeDesktopItem {
name = desktop-entry-name;
desktopName = "neovim";
exec = "${./editor-hax.py} %F";
tryExec = "${./editor-hax.py}";
terminal = false;
type = "Application";
categories = [
"Utility"
"TextEditor"
];
icon = "terminal";
mimeTypes = nvim_mime_types;
};
in
{
home = {
sessionVariables = {
EDITOR = "nvim";
};
};
home.file.".local/share/applications/${desktop-entry-name}.desktop" = {
source = "${desktop-entry}/share/applications/${desktop-entry-name}.desktop";
};
xdg.mimeApps.associations.added = lib.mergeAttrsList (
map (mime: {
${mime} = [ "${desktop-entry-name}.desktop" ];
}) nvim_mime_types
);
imports = [
flakes.nixvim.homeModules.nixvim
./options.nix
@ -98,7 +151,10 @@ _: {
# lspconfig.noteslsp.setup{}
# ''
+ (builtins.readFile ./config.lua);
extraConfigLuaPost = ''
'';
};
};
};
}

119
programs/nvim/editor-hax.py Executable file
View file

@ -0,0 +1,119 @@
#!/usr/bin/env python
import subprocess
import os
import sys
import re
from urllib.parse import urlsplit
extract_line_regex = re.compile(r"(.*?)(?::([0-9]+))?(?::([0-9]+))?(:)?$")
main_editor = "nvim"
editors = [main_editor, "vim", "vi"]
real_editor = os.environ.get("REAL_EDITOR", None)
editor_command = main_editor
if real_editor is not None:
editors.append(real_editor)
editor_command = real_editor
def run(cmd, only_stdout=True):
res = subprocess.run(cmd, capture_output=True, text=True, shell=True)
if only_stdout:
return str(res.stdout)
else:
return res
def find_pane(window):
for editor in editors:
pane = run(f"tmux list-panes -a -f '#{{&&:#{{==:#{{window_id}},{window}}},#{{==:#{{pane_current_command}},{editor}}}}}' -F '#{{pane_id}}'").strip();
if pane != "":
return pane
def create_pane(args):
run(f'tmux split-window -h -P -F "#{{pane_id}}" {editor_command} {args}')
def find_or_create_pane(window, args):
if pane := find_pane(window):
# exit copy mode so we don't send these commands directly to tmux
run(f"tmux send-keys -t {pane} -X cancel")
# Escape for some reason doesn't get sent as the escape key if it shows up next to any other keys???
run(f"tmux send-keys -t {pane} Escape")
# note the space, this tells nvim not to save it in history
run(f"tmux send-keys -t {pane} \": drop {args}\" Enter")
run(f"tmux select-pane -t {pane} -Z")
else:
create_pane(args)
def split_line(filename):
mtch = extract_line_regex.match(filename)
file = mtch.group(1)
line = mtch.group(2)
column = mtch.group(3)
url = urlsplit(line)
if url.scheme == "file" and url.path != file:
file = url.path
file = os.path.abspath(file)
print(f"opening {file}:{line}:{column}")
return file, line, column
def join_line(filename, maybe_line, maybe_column):
assert not (maybe_line is None and maybe_column is not None)
if maybe_line is None:
return filename
if maybe_column is None:
maybe_column = "0"
return f"+normal!{maybe_line}G{maybe_column} {filename}"
def trim(arg):
if arg.startswith("\"") and not arg.endswith("\""):
arg = arg.lstrip("\"")
if arg.endswith("\"") and not arg.startswith("\""):
arg = arg.rstrip("\"")
return arg.strip()
def editor_hax(filename):
args = split_line(trim(filename))
current_window = run("tmux display-message -p \"#{window_id}\"").strip();
find_or_create_pane(current_window, join_line(*args))
def xdg_open(arg):
subprocess.run(f"xdg-open {trim(arg)}", shell=True)
def xdg_open_proxy(*args):
for arg in args:
try:
_file, line, _column = split_line(arg)
if line is not None:
editor_hax(arg)
else:
xdg_open(arg)
except:
xdg_open(arg)
def usage():
print(f"usage: {sys.argv[0]} filename:(line):(column)")
print(" Opens a file with line number and colum in the editor in another pane of the current tmux window")
print(f"usage: {sys.argv[0]} xdg-open-proxy filename:(line):(column)")
print(" Calls xdg-open on the given parameters. However, if any part contains a line number and or column, opens in nvim like editor-hax")
exit(1)
if __name__ == "__main__":
if len(sys.argv) < 2:
usage()
elif sys.argv[1] == "xdg-open-proxy":
if len(sys.argv) < 3:
usage()
else:
xdg_open_proxy(*sys.argv[1:])
elif len(sys.argv) > 2:
usage()
else:
editor_hax(sys.argv[1])

View file

@ -17,39 +17,23 @@ in
# splitting
(map "n" "<leader>s" "<cmd>vertical sb<cr>")
# closing
(map "n" "<leader>w" "<cmd>BufferClose<cr>") # single buffer
(map "n" "<leader>cb" "<cmd>BufferClose<cr>") # single buffer
(map "n" "<leader>ct" "<cmd>CloseBuffer<cr>") # buffer or extra tab
(map "n" "<leader>q" "<cmd>CloseBuffer<cr>") # buffer or extra tab
(map "n" "<leader>co" "<cmd>silent! BufferCloseAllButVisible<cr>") # other buffers
(map "n" "<leader>cl" "<cmd>silent! BufferCloseBuffersLeft<cr>") # other buffers (left)
(map "n" "<leader>cr" "<cmd>silent! BufferCloseBuffersRight<cr>") # other buffers (right)
# moving
(map "n" "mL" "<cmd>BufferMovePrevious<cr>") # left
(map "n" "mr" "<cmd>BufferMoveNext<cr>") # right
(map "n" "m0" "<cmd>BufferMoveStart<cr>") # start
(map "n" "m$" "<cmd>BufferMoveEnd<cr>") # end
(map "n" "<leader>jb" "<cmd>BufferPick<cr>") # jump to tab
# jumplist
# (map "n" "<leader><Tab>" "<C-o>")
# (map "n" "<leader><S-Tab>" "<C-i>")
(map "" "<C-a>" "<C-i>") # note: C-a is actually C-i, remapped through kitty.
(luamap "n" "<leader>r" "${telescope}.jumplist()")
(luamap "n" "<leader>R" "${telescope}.loclist()")
# pickers
(luamap "n" "<leader><leader>" "${telescope}.find_files()")
(luamap "n" "<leader>f" "${telescope}.live_grep()")
(luamap "n" "<leader>t" "${telescope}.lsp_document_symbols()")
(luamap "n" "<leader>T" "${telescope}.lsp_dynamic_workspace_symbols()")
(luamap "n" "<leader>/" "${telescope}.current_buffer_fuzzy_find()")
# last used pickers/searches
(luamap "n" "<leader>h" "${telescope}.pickers()")
(luamap "n" "<leader>p" "${telescope}.pickers()")
(luamap "n" "<leader>m" "${telescope}.search_history()")
# open buffers
(luamap "n" "<leader>b" "${telescope}.buffers({sort_mru = true})")
(luamap "n" "<leader><Tab>" "${telescope}.buffers({sort_mru = true})")
# diagnostics
(map "n" "<leader>d" "<cmd>Trouble diagnostics toggle filter.buf=0<cr>")
@ -69,26 +53,25 @@ in
# expand macro
(map "n" "<leader>em" "<cmd>RustLsp expandMacro<cr>")
# easier quitting etc
(map "ca" "W" "w")
(map "ca" "X" "x")
(map "ca" "Q" "CloseBuffer")
(map "ca" "q" "CloseBuffer")
# navigation
(map "" "<leader><Left>" "<C-w><Left>")
(map "" "<leader><Right>" "<C-w><Right>")
(map "" "<leader><Up>" "<C-w><Up>")
(map "" "<leader><Down>" "<C-w><Down>")
(map "" "<leader><Down>" "<C-w><Down>")
(map "" "<leader>h" "<C-w><Left>")
(map "" "<leader>l" "<C-w><Right>")
(map "" "<leader>k" "<C-w><Up>")
(map "" "<leader>j" "<C-w><Down>")
# close buffer
(map "" "<leader>c" "<cmd>bd<cr>")
# {
# key = "/";
# action = "<cmd>lua require('spectre').open_file_search({select_word=true})<CR>";
# }
(map "n" "t" "<cmd>Neotree toggle<cr>")
# (map "n" "t" "<cmd>Neotree toggle<cr>")
# tab for indent/dedent
(map "n" "<tab>" ">>_")
@ -98,6 +81,9 @@ in
(map "v" "<S-tab>" "<gv")
# to avoid many typos
# easier quitting etc
(map "n" ";" ":")
(map "ca" "W" "w")
(map "ca" "X" "x")
];
}

View file

@ -84,5 +84,9 @@ _: {
"noselect"
"noinsert"
];
# disable auto-folding
foldlevel = 99;
foldlevelstart = 99;
};
}

View file

@ -10,15 +10,6 @@ let
};
};
in
# fzy-lua-native = pkgs.vimUtils.buildVimPlugin {
# name = "fzy-lua-native";
# src = pkgs.fetchFromGitHub {
# owner = "romgrk";
# repo = "fzy-lua-native";
# rev = "9d720745d5c2fb563c0d86c17d77612a3519c506";
# hash = "sha256-pBV5iGa1+5gtM9BcDk8I5SKoQ9sydOJHsmyoBcxAct0=";
# };
# };
{
programs.nixvim = {
plugins = {
@ -168,7 +159,11 @@ in
crates.enable = true;
fidget.enable = true;
nvim-autopairs.enable = true;
# nvim-highlight-colors.enable = true;
spider.enable = true;
origami = {
enable = true;
settings.autofold.enabled = false;
};
cmp = {
enable = true;
@ -221,12 +216,16 @@ in
"<C-Space>" = "cmp.mapping.complete()";
"<CR>" = "cmp.mapping.confirm({ select = true })";
"<C-d>" = ''
function()
function(fallback)
if cmp.visible() then
if cmp.visible_docs() then
cmp.close_docs()
else
cmp.open_docs()
end
else
fallback()
end
end
'';
"<Tab>" = next;
@ -270,7 +269,7 @@ in
};
auto-session = {
enable = true;
enable = false;
settings = {
auto_save_enabled = true;
auto_restore_enabled = true;
@ -288,7 +287,7 @@ in
};
neo-tree = {
enable = true;
enable = false;
settings = {
close_if_last_window = true;
enable_git_status = false;
@ -660,7 +659,7 @@ in
return wilder.renderer_mux({
[':'] = popupmenu_renderer,
['/'] = wildmenu_renderer,
substitute = wildmenu_renderer,
substitute = wildmenu_enderer,
})
end)()
'';
@ -695,7 +694,7 @@ in
];
defaults = {
path_display = [ "smart" ];
layout_strategy = "horizontal";
layout_strategy = "flex";
layout_config = {
width = 0.99;
height = 0.99;
@ -709,15 +708,6 @@ in
enable = true;
};
# tabs
barbar = {
enable = true;
settings = {
options.diagnostics = "nvim_lsp";
focus_on_close = "previous";
};
};
# for lsp/cmp inside markdown code blocks
otter = {
enable = true;

View file

@ -1,6 +1,10 @@
_: {
custom.program.tmux.requirements = [ "cli" ];
custom.program.tmux.home-config =
inputs@{ machine, ... }:
{
imports = machine.program {
name = "tmux";
inherit inputs;
requirements = [ "cli" ];
home-config =
{ pkgs, ... }:
{
programs.tmux = {
@ -35,6 +39,8 @@ _: {
# unbind every single normal keybinding
unbind-key -a
set -g status-left "#{?client_prefix,#[bg=colour2],#[bg=colour1]}#[fg=colour0] #S "
# for special characters to work right
# like <C-_>
# set-window-option -g xterm-keys on
@ -93,18 +99,30 @@ _: {
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
bind Left select-pane -L
bind Down select-pane -D
bind Up select-pane -U
bind Right select-pane -R
bind L split-window -h -c "#{pane_current_path}"
bind J split-window -v -c "#{pane_current_path}"
bind H split-window -h -b -c "#{pane_current_path}"
bind K split-window -v -b -c "#{pane_current_path}"
bind S-Left split-window -h -c "#{pane_current_path}"
bind S-Down split-window -v -c "#{pane_current_path}"
bind S-Up split-window -h -b -c "#{pane_current_path}"
bind S-Right split-window -v -b -c "#{pane_current_path}"
bind-key -r -T prefix M-h resize-pane -L 5
bind-key -r -T prefix M-j resize-pane -D 5
bind-key -r -T prefix M-k resize-pane -U 5
bind-key -r -T prefix M-l resize-pane -R 5
bind x swap-pane -D
# double-click ^k (or lshift with kanata) for previous pane like ^w in vim
bind -r ^k select-pane -l
bind-key q confirm-before -p "kill-pane #P? (y/n)" kill-pane
bind-key o choose-tree -wZ
bind-key O choose-tree -sZ
# bind-key o choose-tree -wZ
# bind-key O choose-tree -sZ
# get back command mode and some other basics...
bind : command-prompt
@ -148,23 +166,42 @@ _: {
bind d select-pane -l \; send-keys [
# f: file search
# unbound: git files
# g: git hashes
# u: urls
# C-d: numbers
# M-i: ips
# include line and column numbers in file search
# rebind `f` so we can reuse it here
bind-key -T prefix C-f command-prompt { find-window -Z "%%" }
# jyn is so sorry, and so am I now
# https://github.com/jyn514/dotfiles/blob/65be3c004113290f41f858f4d7f1a6799fabab19/config/tmux.conf#L203-L212
# see `search-regex.sh` for wtf this means
# TODO: include shell variable names
bind-key f copy-mode \; send-keys -X search-backward '(^|/|\<|[[:space:]"])((\.|\.\.)|[[:alnum:]~_"-]*)((/[][[:alnum:]_.#$%&+=@"-]+)+([/ "]|\.([][[:alnum:]_.#$%&+=@"-]+(:[0-9]+)?(:[0-9]+)?)|[][[:alnum:]_.#$%&+=@"-]+(:[0-9]+)(:[0-9]+)?)|(/[][[:alnum:]_.#$%&+=@"-]+){2,}([/ "]|\.([][[:alnum:]_.#$%&+=@"-]+(:[0-9]+)?(:[0-9]+)?)|[][[:alnum:]_.#$%&+=@"-]+(:[0-9]+)(:[0-9]+)?)?|(\.|\.\.)/([][[:alnum:]_.#$%&+=@"-]+(:[0-9]+)?(:[0-9]+)?))'
# urls
bind-key u copy-mode \; send-keys -X search-backward '(https?://|git@|git://|ssh://|ftp://|file:///)[[:alnum:]?=%/_.:,;~@!#$&*+-]*'
# hashes
bind-key g copy-mode \; send-keys -X search-backward '[[:<:]]([0-9a-f]{7,40}|[[:alnum:]]{52}|[0-9a-f]{64})[[:>:]]'
# ips
bind-key M-i copy-mode \; send-keys -X search-backward '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}'
bind-key -T copy-mode-vi o send-keys -X copy-pipe \
'cd #{pane_current_path}; xargs -I {} echo "echo {}" | bash | xargs ${../nvim/editor-hax.py} xdg-open-proxy' \; \
if -F "#{alternate_on}" { send-keys -X cancel }
# save the buffer, then open an editor in the current pane
bind-key -T copy-mode-vi O send-keys -X copy-pipe-and-cancel \
'tmux send-keys "C-q"; xargs -I {} tmux send-keys "vim {}"; tmux send-keys "C-m"'
# search for the highlighted text
bind-key -T copy-mode-vi s send-keys -X copy-pipe \
"cd #{pane_current_path}; xargs -I {} open 'https://www.google.com/search?q={}'" \; \
if -F "#{alternate_on}" { send-keys -X cancel }
# save buffer and retype into the shell
bind-key -T copy-mode-vi Tab send-keys -X copy-selection-and-cancel \; paste-buffer -p
'';
};
# bind-key -T root DoubleClick1Pane run-shell "cd '#{pane_current_path}'; echo '#{mouse_line}' | ${pkgs.writeScriptBin "open-file" ''
# open_file () {
# input=`cat`
# link=$(echo "$input" | grep -Po '[^ \\]*/[^ \\]*\.[^ \\]*\:[0-9]+' | sed 's/\:/|/g')
#
# if [ ! -z "$link" ]; then
# echo "LINK = $link"
# vim_proc=$(pgrep vim | xargs pwdx | grep $(pwd -P) | awk '{print $1}' | sed 's/\:*$//g' | xargs -I{} find /run/user/1000 -depth -maxdepth 1 -name "nvim.{}.0")
#
# nvim --server "$vim_proc" --remote-send "<C-\><C-N>:e $link<cr>"
# fi
# }
#
# open_file 2>&1 >> ~/open-file.log
#
# ''}/bin/open-file"
};
};
}

159
programs/xdg.nix Normal file
View file

@ -0,0 +1,159 @@
{ machine, ... }@inputs:
let
browsers = [
"firefox.desktop"
];
defaultApps = {
text = [
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanvim.desktop"
];
image = [ "org.gnome.Loupe.desktop" ];
audio = [ "mpv.desktop" ];
video = [ "mpv.desktop" ];
directory = [
"nautilus.desktop"
"org.gnome.Nautilus.desktop"
];
mail = [ ] ++ browsers;
calendar = [ ] ++ browsers;
browser = [ ] ++ browsers;
office = [ "libreoffice.desktop" ];
pdf = [ ] ++ browsers;
ebook = [ ];
magnet = [ ];
signal = [ "signal.desktop" ];
};
mimeMap = {
text = [
"text/plain"
"text/english"
"application/x-zerosize"
"text/x-makefile"
"text/x-c++hdr"
"text/x-c++src"
"text/x-chdr"
"text/x-csrc"
"text/x-java"
"text/x-moc"
"text/x-pascal"
"text/x-tcl"
"text/x-tex"
"application/x-shellscript"
"text/x-c"
"text/x-c++"
];
image = [
"image/bmp"
"image/gif"
"image/jpeg"
"image/jpg"
"image/png"
"image/svg+xml"
"image/tiff"
"image/vnd.microsoft.icon"
"image/webp"
];
audio = [
"audio/aac"
"audio/mpeg"
"audio/ogg"
"audio/opus"
"audio/wav"
"audio/webm"
"audio/x-matroska"
];
video = [
"video/mp2t"
"video/mp4"
"video/mpeg"
"video/ogg"
"video/webm"
"video/x-flv"
"video/x-matroska"
"video/x-msvideo"
];
directory = [ "inode/directory" ];
mail = [ "x-scheme-handler/mailto" ];
calendar = [
"text/calendar"
"x-scheme-handler/webcal"
];
browser = [
"text/html"
"x-scheme-handler/about"
"x-scheme-handler/http"
"x-scheme-handler/https"
"x-scheme-handler/unknown"
];
office = [
"application/vnd.oasis.opendocument.text"
"application/vnd.oasis.opendocument.spreadsheet"
"application/vnd.oasis.opendocument.presentation"
"application/vnd.openxmlformats-officedocument.wordprocessingml.document"
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
"application/vnd.openxmlformats-officedocument.presentationml.presentation"
"application/msword"
"application/vnd.ms-excel"
"application/vnd.ms-powerpoint"
"application/rtf"
];
pdf = [ "application/pdf" ];
ebook = [ "application/epub+zip" ];
magnet = [ "x-scheme-handler/magnet" ];
signal = [ "signal.desktop" ];
};
associations =
with inputs.lib;
with builtins;
listToAttrs (
flatten (mapAttrsToList (key: map (type: attrsets.nameValuePair type defaultApps."${key}")) mimeMap)
);
removedAssociations = {
"text/plain" = "dev.zed.Zed.desktop";
"application/x-zerosize" = "dev.zed.Zed.desktop";
};
in
{
imports = machine.program {
name = "xdg";
inherit inputs;
requirements = [ ];
home-config =
{ config, ... }:
{
xdg = {
enable = true;
mime.enable = true;
configHome = "${config.home.homeDirectory}/.config";
userDirs = {
enable = true;
documents = "${config.home.homeDirectory}/Documents";
desktop = "${config.home.homeDirectory}/Documents";
download = "${config.home.homeDirectory}/Downloads";
music = "${config.home.homeDirectory}/Documents/personal/music";
pictures = "${config.home.homeDirectory}/Documents/personal/pictures";
};
configFile."mimeapps.list".force = true;
mimeApps = {
enable = true;
associations.added = associations;
associations.removed = removedAssociations;
defaultApplications = associations;
};
};
};
system-config = _: {
xdg = {
mime = {
enable = true;
defaultApplications = associations;
addedAssociations = associations;
inherit removedAssociations;
};
};
};
};
}

View file

@ -1,6 +1,13 @@
_: {
custom.program.zed.requirements = [ "work" ];
custom.program.zed.home-config =
inputs@{ machine, ... }:
{
imports = machine.program {
name = "zed";
inherit inputs;
requirements = [
"work"
"graphical"
];
home-config =
{ pkgs, ... }:
{
home.packages = pkgs.custom.maple-fonts-pack;
@ -125,6 +132,9 @@ _: {
refreshSupport = true;
};
};
binary = {
path_lookup = true;
};
};
nil = {
binary = {
@ -170,4 +180,5 @@ _: {
};
};
};
};
}

View file

@ -1,9 +1,8 @@
{ pkgs, inputs, ... }:
{ pkgs, ... }:
{
imports = [
(inputs.self + /modules/users.nix)
(../modules/users.nix)
];
users.groups.media = { };
custom.users = {
vivian = {
@ -19,6 +18,16 @@
];
};
mara = {
shell = pkgs.zsh;
keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKAzf3UCwTWJlF878EWqlrLUOBsxw/b/6PoLjbKkA8Xh"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIHi5YnRt1VgK8tt6oSPsKo1X+0gcBXVyvCKXM03/vEh"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFWF1MtDV5HJT+GhD8wrKICyDwQK8ZPQTxZdnsfaqWcs"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIHi1EEGRry1aD6uPmdlcRqdiTiIty0JlnfoXeM0qKBC"
];
};
jana = {
shell = pkgs.fish;
keys = [