1
0

Compare commits

...

10 Commits

Author SHA1 Message Date
134fe16393 feat: TETR.IO (+ TETR.IO PLUS integration)
This commit does feature a _few_ changes to my general NixOS config
(namely the ideology switch from importing things everywhere to having
my own custom "`mpkgs`").

However most of this effort was all thanks to TETR.IO. The former
maintainer of `pkgs.tetrio-desktop` and `pkgs.tetrio-plus` seems to not
have been playing recently enough to update the packages to v10. Making
them unusuable.

`mpkgs.tetrio.desktop` is a patched `pkgs.tetrio-desktop` that updates
to v10. Alongside this, and a quick discovery that you could make custom
home-manager modules, I took it upon myself to make TETR.IO
configurations (including those of TETR.IO PLUS) fully generated from
Nix.

This effort took way too long, and feels slightly hacky (the way
injecting configurations works is by generating a LevelDB (Chromium
IndexedDB) for the electron instance's Local Storage) and it involves
some custom stuff. (LevelDB deriviation, plus home-manager module for
copying files rather than linking them `home.initialFile`.)

I'm proud of the result, and Tetris is now fully deterministic,
reproducible, and Nix-y.
2026-01-14 21:49:20 +01:00
af86c0c1e5 patch(nvim): unnest.nvim
Makes using git within a terminal nicer. `vim-fugitive` was my former go
to, but I prefer that, with the `<leader>t` shortcut.
2025-12-30 23:48:22 +01:00
15662647d7 chore(nvim): reintroduce typescript 2025-12-30 23:47:59 +01:00
9f8ed18d72 chore: install additional user programs 2025-12-19 16:15:58 +01:00
7acae9b431 patch: properly configure screen configuration
(post `greetd` introduction)
2025-12-19 16:15:27 +01:00
049c916f46 chore: make neovim gd actually go to definition
For some reason, the default mapping on `gd` does not go to definition
by lsp, but rather by symbol within file.
2025-12-19 16:13:39 +01:00
7ca50dd7fe patch(vesktop): actually apply the configuration 2025-12-19 16:12:55 +01:00
1eb41ac84e chore: add ripgrep to system config 2025-12-19 16:11:32 +01:00
0009b7c33c chore(neovim): switch to fzf-lua for fuzzy finding 2025-12-19 16:10:27 +01:00
056888e635 patch: fallback to stable rust toolchain
Rust-analyzer doesn't play nicely with proc macros on the latest
(default) fenix toolchain.
2025-12-19 16:07:50 +01:00
16 changed files with 1226 additions and 48 deletions

View File

@@ -6,7 +6,7 @@
}:
let
concat = strings: lib.concatStringsSep " " strings;
concat = strings: builtins.concatStringsSep " " strings;
in
{
services.xserver.videoDrivers = [ "nvidia" ];
@@ -21,22 +21,20 @@ in
package = config.boot.kernelPackages.nvidiaPackages.stable;
};
services.xserver.displayManager.setupCommands = concat [
home-manager.users.anton.xsession.profileExtra = concat [
"${lib.getExe pkgs.xorg.xrandr}"
concat
[
"--output DP-0"
"${concat [
"--output DP-2"
"--mode 1920x1080"
"--pos 0x0"
"--rate 144"
"--primary"
]
concat
[
]}"
"${concat [
"--output HDMI-0"
"--mode 1920x1080"
"--pos 1920x0"
"--rate 144"
]
]}"
];
}

View File

@@ -8,18 +8,19 @@
let
stateVersion = "25.05";
env = import ./.env.nix { inherit pkgs; };
mpkgs = import ./pkgs/default.nix {
config = {
system.stateVersion = stateVersion;
};
};
in
{
imports = [
# Include the results of the hardware scan.
./hardware-configuration.nix
(import (./. + "/${env.hostname}.nix"))
(
let
home-manager = builtins.fetchTarball "https://github.com/nix-community/home-manager/archive/release-${stateVersion}.tar.gz";
in
import "${home-manager}/nixos"
)
mpkgs.home-manager.module
];
nixpkgs.config.allowUnfree = true;
@@ -39,8 +40,10 @@ in
git
xh
jq
fzf
ripgrep
(fenix.complete.withComponents [
(fenix.stable.withComponents [
"rustc"
"cargo"
"clippy"
@@ -48,13 +51,16 @@ in
"rustfmt"
"rust-analyzer"
])
nodejs-slim_latest
nodejs_latest
prettierd
typescript-language-server
pnpm
nixd
nixfmt-rfc-style
clang
llvmPackages.bintools
stylua
go
];
fonts.packages = with pkgs; [
@@ -65,7 +71,7 @@ in
nerd-fonts.symbols-only
inter
times-newer-roman
(import ./pkgs/monaco-font/default.nix { inherit pkgs; })
(mpkgs.font.monaco)
];
fonts.fontconfig = {
@@ -149,9 +155,12 @@ in
];
};
home-manager.useUserPackages = true;
home-manager.useGlobalPkgs = true;
home-manager.users.anton = import ./home.nix;
home-manager = {
useUserPackages = true;
useGlobalPkgs = true;
sharedModules = [ ] ++ (mpkgs.home-manager.sharedModules);
users.anton = import ./home.nix;
};
# programs.home-manager.enable = true;
programs.dconf.enable = true;
@@ -161,7 +170,15 @@ in
style = "adwaita-dark";
};
hardware.graphics.enable = true;
hardware.graphics = {
enable = true;
extraPackages = with pkgs; [
intel-media-driver
intel-vaapi-driver
libvdpau-va-gl
mesa
];
};
hardware.bluetooth = {
enable = true;

View File

@@ -5,14 +5,16 @@
}:
let
neovim = pkgs.callPackage ./pkgs/neovim/default.nix { };
fish = pkgs.callPackage ./pkgs/fish/default.nix { };
mpkgs = import ./pkgs/default.nix { };
inherit (mpkgs.config) neovim fish;
env = import ./.env.nix;
env = import ./.env.nix { inherit pkgs; };
home = /home/anton;
in
{
imports = [ ];
home.username = lib.mkDefault "anton";
home.homeDirectory = lib.mkDefault home;
@@ -24,14 +26,20 @@ in
flameshot
krita
davinci-resolve
vscode
godotPackages_4_5.godot
btop
neovim
btop
xclip
tree
xh
babelfish
hyperfine
bat
typst
tinymist
# required by spotify
ffmpeg_4
@@ -127,6 +135,68 @@ in
};
};
programs.tetrio-desktop = {
enable = true;
package = mpkgs.tetrio.desktop;
plus = {
enable = true;
package = mpkgs.tetrio.plus;
skin.package = mpkgs.tetrio.skins.simple-connected;
};
settings = {
handling = {
auto_repeat_rate = 0;
delayed_auto_shift = 7;
soft_drop_factor = 14;
};
audio = {
scroll_adjust_volume = false;
stereo = 60;
music.preferences = {
kaze-no-sanpomichi = "-";
muscat-to-shiroi-osara = "-";
akindo = "+";
yoru-no-niji = "+";
burari-tokyo = "+";
fuyu-no-jinkoueisei = "+";
honemi-ni-shimiiru-karasukaze = "-";
"21seiki-no-hitobito" = "+";
haru-wo-machinagara = "++";
go-go-go-summer = "-";
sasurai-no-hitoritabi = "++";
wakana = "-";
zange-no-ma = "-";
asphalt = "-";
madobe-no-hidamari = "--";
sora-no-sakura = "-";
suiu = "-";
burning-heart = "+";
hayate-no-sei = "-";
ima-koso = "+";
chiheisen-wo-koete = "--";
moyase-toushi-yobisamase-tamashii = "-";
uchuu-5239 = "+";
ultra-super-heros = "-";
};
};
visual = {
board_bounciness = 20;
background_opacity = 0;
};
multiplayer.notifications.suppress_while_playing = true;
skip_login_screen = "by-url";
advertisments.i_support_the_devs.i_cannot_play_with_ads.and_i_really_want_to.disable = true;
devtools = true;
};
};
programs.vesktop = import ./home/vesktop.nix;
services.gpg-agent = {
enable = true;
enableSshSupport = true;
@@ -149,5 +219,5 @@ in
NIXPKGS_ALLOW_UNFREE = 1;
};
home.stateVersion = (pkgs.callPackage <nixos-config> { }).system.stateVersion;
home.stateVersion = mpkgs.system.stateVersion;
}

View File

@@ -56,8 +56,8 @@ in
let
background = lib.concatStringsSep " " [
"exec --no-startup-id"
"${lib.concatStringsSep " " [
"${lib.getExe pkgs.xwinwrap}"
(lib.concatStringsSep " " [
(lib.getExe pkgs.xwinwrap)
"-g 3820x1080"
"-s"
"-b"
@@ -65,10 +65,10 @@ in
"-sp"
"-ov"
"-nf"
]}"
])
"--"
"${lib.concatStringsSep " " [
"${lib.getExe pkgs.mpv}"
(lib.concatStringsSep " " [
(lib.getExe pkgs.mpv)
"${wallpaper}/wallpaper.mov"
"-wid WID"
"--loop"
@@ -81,7 +81,7 @@ in
"--framedrop=vo"
"--profile=low-latency"
"--hwdec=auto"
]}"
])
];
displays =
if (env ? displays) then
@@ -89,6 +89,12 @@ in
"workspace 1 output ${env.displays.primary}"
(if (env.displays ? secondary) then "workspace 2 output ${env.displays.secondary}" else "")
"exec i3-msg focus output ${env.displays.primary}"
(
if (env.displays ? xrandr) then
"exec \"${lib.getExe pkgs.xorg.xrandr} ${env.displays.xrandr}\""
else
""
)
]
else
"";

55
pkgs/default.nix Normal file
View File

@@ -0,0 +1,55 @@
{
pkgs ? import <nixpkgs> { config.allowUnfree = true; },
config ? (import <nixpkgs/nixos> { }).config,
fetchzip ? pkgs.fetchzip,
...
}:
let
system = {
stateVersion = config.system.stateVersion;
};
use = path: pkgs.callPackage (import path) { inherit pkgs; };
in
{
inherit system;
wallpaper = use ./wallpaper/default.nix;
tetrio.desktop = use ./tetrio/default.nix;
tetrio.plus =
let
repo = {
owner = "UniQMG";
name = "tetrio-plus";
job = "11675178434";
hash = "sha256-j3ACcnT64eMQtWYDGOE2oGXpnN5EUqk+lyV6ARBEtU8=";
};
src = fetchzip {
url = "https://gitlab.com/${repo.owner}/${repo.name}/-/jobs/${repo.job}/artifacts/raw/app.asar.zip";
hash = repo.hash;
};
in
"${src}/app.asar";
tetrio.skins = {
simple-connected = use ./tetrio/skins/simple-connected.nix;
};
leveldb-cli = use ./leveldb/default.nix;
config.neovim = use ./neovim/default.nix;
config.fish = use ./fish/default.nix;
font.monaco = use ./monaco-font/default.nix;
home-manager = {
module =
let
home-manager = fetchzip {
url = "https://github.com/nix-community/home-manager/archive/release-${system.stateVersion}.tar.gz";
hash = "sha256-WHkdBlw6oyxXIra/vQPYLtqY+3G8dUVZM8bEXk0t8x4=";
};
in
import "${home-manager}/nixos";
sharedModules = [ ./home-manager/initialFile.nix ./tetrio/module.nix ];
};
}

View File

@@ -0,0 +1,172 @@
{
pkgs,
lib ? pkgs.lib,
config,
...
}:
let
inherit (lib) mkOption types;
cfg = lib.filterAttrs (n: f: f.enable) config.home.initialFile;
home = config.home.homeDirectory;
in
{
options = {
home.initialFile = mkOption {
type = types.attrsOf (
types.submodule (
{ name, config, ... }:
{
options = {
enable = mkOption {
type = types.bool;
default = true;
};
target = mkOption {
type = types.str;
apply =
path:
let
absPath = if lib.hasPrefix "/" path then path else "${home}/${path}";
in
lib.removePrefix (home + "/") absPath;
description = "Path to target file relative to home directory";
default = "/homeless-shelter/home";
};
text = mkOption {
type = types.nullOr types.lines;
description = "Text of the file, otherwise copies .source file.";
default = null;
};
source = mkOption {
type = types.path;
description = "Path of file whose source to copy";
};
mode = mkOption {
type = types.nullOr types.str;
description = "File mode to apply to target file (sourced from .source / .text if not specified)";
default = null;
};
dir_mode = mkOption {
type = types.str;
description = "File mode to apply to directories";
default = "0755";
};
recursive = mkOption {
type = types.bool;
description = "Whether or not to recursively copy .source as a directory instead of as a file";
default = false;
};
force = mkOption {
type = types.bool;
description = "Whether to unconditionally replace the target file, even if it already exists.";
default = false;
};
};
config = {
target = lib.mkDefault name;
source = lib.mkIf (config.text != null) (
lib.mkDefault (
pkgs.writeTextFile {
inherit (config) text;
name = lib.hm.strings.storeFileName name;
}
)
);
};
}
)
);
description = "Attribute set of files to write into the user home (if they don't already exist).";
default = { };
};
};
config = {
assertions = [
(
let
dups = lib.attrNames (
lib.filterAttrs (n: v: v > 1) (
lib.foldAttrs (acc: v: acc + v) 0 (lib.mapAttrsToList (n: v: { ${v.target} = 1; }) cfg)
)
);
dupsStr = lib.concatStringsSep ", " dups;
in
{
assertion = dups == [ ];
message = ''
Conflicting managed target files: ${dupsStr}
This may happen, for example, if you have a configuration similar to
home.initialFile = {
conflict1 = { source = ./foo.nix; target = "baz"; };
conflict2 = { source = ./bar.nix; target = "baz"; };
}'';
}
)
];
home.activation.copyInitialFiles = lib.hm.dag.entryAfter [ "writeBoundary" ] (
let
homeArg = lib.escapeShellArg home;
in
''
function copyFile() {
local source="$1"
local targetRel="$2"
local mode="$3"
local dirMode="$4"
local recursive="$5"
local force="$6"
local target="${homeArg}/$targetRel"
if [[ -e "$target" && "$force" != "true" ]]; then
verboseEcho "Skipping existing $target"
return 0
fi
run mkdir -p "$(dirname "$target")"
if [[ -d "$source" ]]; then
if [[ "$recursive" != "true" ]]; then
errorEcho "Source '$source' is a directory but recursive=false"
return 1
fi
run rm -rf "$target"
run cp -r "$source" "$target"
else
if [[ -e "$target" && "$force" == "true" ]]; then
run rm -f "$target"
fi
run cp "$source" "$target"
fi
if [[ -n "$mode" ]]; then
if [[ -d "$target" && "$recursive" == "true" ]]; then
run chmod "$dirMode" "$target"
find "$target" -type f -exec chmod "$mode" {} +
else
run chmod "$mode" "$target"
fi
fi
}
''
+ lib.concatMapStrings (
v:
let
src = lib.escapeShellArg (toString v.source);
tgt = lib.escapeShellArg v.target;
mode = if v.mode == null then "''" else lib.escapeShellArg v.mode;
in
''
copyFile ${src} ${tgt} ${mode} ${lib.escapeShellArg v.dir_mode} ${lib.trivial.boolToString v.recursive} ${lib.trivial.boolToString v.force}
''
) (lib.attrValues cfg)
);
};
}

21
pkgs/leveldb/default.nix Normal file
View File

@@ -0,0 +1,21 @@
{
pkgs ? import <nixpkgs> { },
}:
pkgs.buildGoModule {
name = "leveldb-cli";
version = "1.0.0";
src = pkgs.fetchFromGitHub {
owner = "theblueplum";
repo = "leveldb-cli";
rev = "main";
hash = "sha256-Q4BVmmqc6MPrOLy/lSV1FyhAoKBq0U2UcMHYEMOhtpo=";
};
vendorHash = "sha256-b25hlPQft9iKyIw6E9jtORBgoLPnNa4+Z5QoeFoayfc=";
meta = {
mainProgram = "leveldb";
};
}

View File

@@ -53,6 +53,9 @@ local keymap = {
goto_last_buffer = {
['<leader>l'] = ':e#<CR>',
},
goto_definition = {
['gd'] = vim.lsp.buf.declaration
},
scratch_pad = {
['<leader>s'] = table.concat({
':bo vs',

View File

@@ -9,10 +9,14 @@ return {
{
'tpope/vim-fugitive',
cmd = { 'Git' },
enabled = false, -- prefer using a terminal buffer with unnest.nvim
},
{
dir = '~/dev/share.nvim/',
opts = {},
enabled = false,
},
{
'brianhuster/unnest.nvim',
},
}

View File

@@ -24,7 +24,7 @@ local function formatter(exe, args)
}
end
local prettier = formatter('prettier', {
local prettier = formatter('prettierd', {
'--config-precedence prefer-file',
'--single-quote',
'--use-tabs',

View File

@@ -11,11 +11,12 @@ return {
mason_lspconfig.setup(lazy.opts)
mason_lspconfig.setup_handlers({
vim.lsp.enable
vim.lsp.enable,
})
vim.lsp.enable('nixd')
vim.lsp.enable('rust_analyzer')
for _, lsp in pairs({ 'nixd', 'rust_analyzer', 'ts_ls' }) do
vim.lsp.enable(lsp)
end
end,
dependencies = {
'mason-org/mason.nvim',
@@ -51,11 +52,16 @@ return {
menu = {
auto_show = true,
draw = {
columns = { { 'kind_icon' }, { 'label', 'label_description', gap = 1 }, { 'kind' } },
columns = {
{ 'kind_icon' },
{ 'label', 'label_description', gap = 1 },
{ 'kind' },
},
components = {
kind_icon = {
text = function(ctx)
local icon, _, _ = common.icons_require().get('lsp', ctx.kind)
local icon, _, _ =
common.icons_require().get('lsp', ctx.kind)
return icon
end,
},

View File

@@ -1,24 +1,32 @@
local common = require('BluePlum.lazy')
local telescope = {
local fzf_lua = {
find_files = function()
require('telescope.builtin').find_files({ show_hidden = true })
require('fzf-lua').files()
end,
live_grep = function()
require('telescope.builtin').live_grep()
require('fzf-lua').grep()
end,
buffers = function()
require('telescope.builtin').buffers()
require('fzf-lua').buffers()
end,
quick_fix = function()
require('fzf-lua').lsp_code_actions()
end,
diagnostics = function()
require('fzf-lua').diagnostics_workspace()
end,
}
return {
{
'nvim-telescope/telescope.nvim',
dependencies = { common.plenary },
'ibhagwan/fzf-lua',
dependencies = { common.icons },
keys = {
{ '<leader>ff', telescope.find_files },
{ '<leader>fs', telescope.live_grep },
{ '<leader>bb', telescope.buffers },
{ '<leader>ff', fzf_lua.find_files },
{ '<leader>fs', fzf_lua.live_grep },
{ '<leader>fd', fzf_lua.diagnostics },
{ '<leader>bb', fzf_lua.buffers },
{ 'gra', fzf_lua.quick_fix },
},
},

30
pkgs/tetrio/default.nix Normal file
View File

@@ -0,0 +1,30 @@
{
pkgs ? import <nixpkgs> { },
fetchzip ? pkgs.fetchzip,
withTetrioPlus ? false,
tetrio-plus ? pkgs.tetrio-plus,
...
}:
let
tetrio-desktop =
let
version = "10";
in
{
inherit version;
src = fetchzip {
url = "https://tetr.io/about/desktop/builds/${version}/TETR.IO%20Setup.deb";
hash = "sha256-2FtFCajNEj7O8DGangDecs2yeKbufYLx1aZb3ShnYvw=";
nativeBuildInputs = with pkgs; [ dpkg ];
};
};
in
(pkgs.tetrio-desktop.overrideAttrs {
version = tetrio-desktop.version;
src = tetrio-desktop.src;
}).override {
inherit withTetrioPlus tetrio-plus;
}

32
pkgs/tetrio/leveldb.nix Normal file
View File

@@ -0,0 +1,32 @@
{
pkgs ? import <nixpkgs> { },
mpkgs ? import /etc/nixos/pkgs/default.nix { },
origin ? "https://tetr.io",
key ? "userConfig",
value,
...
}:
let
src = ./.;
in
pkgs.stdenv.mkDerivation {
pname = "tetrio-leveldb";
version = "1";
inherit src;
nativeBuildInputs = [ mpkgs.leveldb-cli ];
buildPhase = ''
runHook preBuild
${pkgs.lib.getExe mpkgs.leveldb-cli} \
$out \
${pkgs.lib.escapeShellArg origin} \
${pkgs.lib.escapeShellArg key} \
${pkgs.lib.escapeShellArg (builtins.toJSON value)}
runHook postBuild
'';
}

725
pkgs/tetrio/module.nix Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
{
pkgs ? import <nixpkgs> { },
...
}:
let
src = pkgs.fetchurl {
url = "https://you.have.fail/tetrioplus/data/tpsefiles/skin/SpooKoArts/simple_connected.zip.tpse";
hash = "sha256-dIrEpEV9Gy2iU6K6rMrNX4XFQEchkJqSmOuQwVF4EQQ=";
};
in
pkgs.stdenv.mkDerivation {
name = "simple-connected";
version = "2022-06-26";
inherit src;
dontUnpack = true;
dontBuild = true;
installPhase = ''
runHook preInstall
cp ${src} $out
runHook postInstall
'';
fixupPhase = ''
runHook preFixup
sed -i 's/\bskin\b/value/' $out
runHook postFixup
'';
}