{ config, pkgs, lib, wallpaper, ... }:
let
theme = pkgs.qogir-theme.override { tweaks = [ "square" ]; };
markdownStyleHeader = pkgs.writeText "style.html" ''
'';
markdownCaddyfile = pkgs.writeText "Caddyfile" ''
:8123
encode zstd gzip
templates
file_server browse {
root "/"
hide ".*"
}
@md <
{{ "{file.base}" }}
{{
markdown (include "{path}")
}}
HTML 200
'';
in
{
# Home Manager needs a bit of information about you and the paths it should
# manage.
home.username = "ps";
home.homeDirectory = "/home/ps";
services.xcape = {
enable = true;
mapExpression = {
Caps_Lock = "Escape";
};
};
systemd.user.services.markdownCaddy = {
Unit = {
Description = "Run a web server serving Markdown files.";
Wants = [ "network-online.target" ];
After = [ "network-online.target" ];
};
Install = {
WantedBy = [ "default.target" ];
};
Service = {
WorkingDirectory = "/";
ExecStart = "${pkgs.writeShellScript "markdown-caddy" ''
${pkgs.caddy}/bin/caddy run --config ${markdownCaddyfile} --adapter caddyfile
''}";
};
};
xsession.windowManager.i3 = {
enable = true;
config = {
bars = [];
modifier = "Mod4";
terminal = "${pkgs.kitty}/bin/kitty";
gaps = { inner = 0; outer = 0; };
keybindings =
let
mod = config.xsession.windowManager.i3.config.modifier;
i3-next = pkgs.writers.writePython3 "i3-next" {} ''
import json
from subprocess import check_output
workspaces = json.loads(check_output(
["${pkgs.i3}/bin/i3-msg",
"-t", "get_workspaces"]))
outputs = {}
activeOutput = ""
activeWorkspace = -1
for w in workspaces:
output = w["output"]
workspace = int(w["num"])
if output not in outputs:
outputs[output] = set()
outputs[output].add(workspace)
if w["focused"]:
activeOutput = output
activeWorkspace = workspace
workspacesSorted = sorted(outputs[activeOutput])
activeWorkspaceIndex = workspacesSorted.index(activeWorkspace)
if activeWorkspaceIndex < len(workspacesSorted) - 1:
print(workspacesSorted[activeWorkspaceIndex + 1])
else:
allWorkspaces = set()
for o in outputs.values():
allWorkspaces = allWorkspaces.union(o)
allWorkspacesSorted = sorted(allWorkspaces)
print(allWorkspacesSorted[-1]+1)
'';
i3-empty = pkgs.writers.writePython3 "i3-empty" {} ''
import json
from subprocess import check_output
workspaces = json.loads(check_output(
["${pkgs.i3}/bin/i3-msg",
"-t", "get_workspaces"]))
nextWorkspace = 1
for w in workspaces:
wNum = int(w["num"])
if wNum >= nextWorkspace:
nextWorkspace = wNum + 1
print(nextWorkspace)
'';
i3-max = pkgs.writers.writePython3 "i3-max" {} ''
import json
from subprocess import check_output
workspaces = json.loads(check_output(
["${pkgs.i3}/bin/i3-msg",
"-t", "get_workspaces"]))
result = "MAX"
for w in workspaces:
wName = w["name"]
wFocused = w["focused"]
if wName == "MAX" and wFocused:
result = "back_and_forth"
break
print(f"move window to workspace {result}; workspace {result}")
'';
i3-move-max = pkgs.writers.writePython3 "i3-move-max" {} ''
import json
from subprocess import check_output
workspaces = json.loads(check_output(
["${pkgs.i3}/bin/i3-msg",
"-t", "get_workspaces"]))
result = "MAX"
for w in workspaces:
wName = w["name"]
wFocused = w["focused"]
if wName == "MAX" and wFocused:
result = "back_and_forth"
break
print(f"workspace {result}")
'';
in lib.mkOptionDefault
{
# "${mod}+d" = "exec --no-startup-id krunner";
# "${mod}+Shift+p" = "exec --no-startup-id set-wallpaper";
"${mod}+Shift+Return" = "exec --no-startup-id ${pkgs.kitty}/bin/kitty -d $(${pkgs.xcwd}/bin/xcwd)";
"${mod}+BackSpace" = "kill";
"${mod}+Prior" = "workspace prev_on_output";
"${mod}+Next" = "exec --no-startup-id i3-msg workspace number $(${i3-next})";
"${mod}+End" = "exec --no-startup-id i3-msg workspace $(${i3-empty})";
"${mod}+Shift+Prior" = "move container to workspace prev_on_output";
"${mod}+Shift+Next" = "exec --no-startup-id i3-msg move container to workspace number $(${i3-next})";
"${mod}+Shift+End" = "exec --no-startup-id i3-msg move container to workspace $(${i3-empty})";
"${mod}+Ctrl+Left" = "move workspace to output left";
"${mod}+Ctrl+Right" = "move workspace to output right";
"${mod}+y" = "exec --no-startup-id mirror-phone";
"${mod}+n" = "exec ${pkgs.kitty}/bin/kitty -d ~/sync/txt nvim -c 'autocmd VimEnter * ++once Telescope find_files'";
"${mod}+m" = "exec --no-startup-id i3-msg $(${i3-max})";
"${mod}+b" = "split toggle; layout tabbed";
"${mod}+Shift+m" = "exec --no-startup-id i3-msg $(${i3-move-max})";
"${mod}+Shift+p" = "exec --no-startup-id ${pkgs.autorandr}/bin/autorandr --match-edid -c -f";
};
};
extraConfig = ''
for_window [window_role="pop-up"] floating enable
for_window [window_role="task_dialog"] floating enable
for_window [workspace="9"] floating enable
for_window [class="kitty-popup"] floating enable
for_window [class="Xfce4-appfinder"] floating enable
for_window [class="yakuake"] floating enable
for_window [class="systemsettings"] floating enable
for_window [title="win7"] floating enable; border none
for_window [title="Arbeitsfläche.*"] kill, floating enable, border none
# class border backgr. text indicator child_border
client.focused #000000bf #000000bf #e6ebef #000000bf #000000bf
client.focused_inactive #00000080 #00000080 #e6ebef #00000080 #00000080
client.unfocused #00000040 #00000040 #e6ebef #00000040 #00000040
client.urgent #2f343a #900000 #e6ebef #900000 #2f343a
client.placeholder #000000 #0c0c0c #e6ebef #000000 #0c0c0c
focus_follows_mouse no
mouse_warping none
popup_during_fullscreen all
'';
};
services.picom = {
enable = true;
vSync = true;
opacityRules = [
"0:_NET_WM_STATE@[*]:a = '_NET_WM_STATE_HIDDEN'"
];
};
programs.git = {
userName = "patrick-scho";
userEmail = "patrick.schoenberger@posteo.de";
includes = [{ contents = {
user = {
email = "patrick.schoenberger@posteo.de";
name = "psch";
};
};}];
};
programs.bash = {
enable = true;
historySize = -1;
historyFileSize = -1;
shellAliases = {
snrs = "sudo nixos-rebuild switch --flake /etc/nixos#default";
snrt = "sudo nixos-rebuild test --flake /etc/nixos#default";
snrb = "sudo nixos-rebuild boot --flake /etc/nixos#default";
senc = "sudo $EDITOR /etc/nixos/configuration.nix";
senh = "sudo $EDITOR /etc/nixos/home-ps.nix";
senhc = "sudo $EDITOR /etc/nixos/home-common.nix";
senf = "sudo $EDITOR /etc/nixos/flake.nix";
flakerun = "nix run --override-input nixpkgs nixpkgs";
n = "nvim";
};
};
programs.fzf = {
enable = true;
enableBashIntegration = true;
};
programs.readline = {
enable = true;
bindings = {
"\\e[A" = "history-search-backward";
"\\e[B" = "history-search-forward";
};
};
programs.kitty = {
enable = true;
themeFile = "Adapta_Nokto_Maia";
settings = {
# hide_window_decorations = "yes";
background_opacity = "0.98";
background_blur = "1";
confirm_os_window_close = "0";
enable_audio_bell = "no";
scrollback_pager_history_size = "1024";
};
};
home.file.".config/zls.json".text = ''
{
"enable_build_on_save": true,
"build_on_save_step": "check"
}
'';
home.file.".config/vis/plugins/vis-lspc" = {
source = builtins.fetchGit {
url = "https://gitlab.com/muhq/vis-lspc.git";
rev = "e184eb6c971abfcd0dc7f836f402aae6c33a8d13";
};
recursive = true;
};
home.file.".config/vis/plugins/vis-commentary" = {
source = builtins.fetchGit {
url = "https://github.com/lutobler/vis-commentary.git";
rev = "0e06ed8212c12c6651cb078b822390094b396f08";
};
recursive = true;
};
home.file.".config/vis/visrc.lua".text = ''
require('vis')
require('plugins/vis-commentary')
lspc = require('plugins/vis-lspc')
lspc.menu_cmd = 'vis-menu'
lspc.fallback_dirname_as_root = true
lspc.ls_map.zig = {name='zls',cmd='zls',roots={'build.zig'}}
vis.events.subscribe(vis.events.INIT, function()
-- Your global configuration options
end)
vis.events.subscribe(vis.events.WIN_OPEN, function(win) -- luacheck: no unused args
-- Your per window configuration options e.g.
vis:command('set number on')
vis:command('set autoindent')
vis:command('set tabwidth 4')
vis:command('set expandtab on')
end)
'';
programs.emacs = {
enable = true;
extraConfig = ''
(menu-bar-mode 1)
(tool-bar-mode 0)
(scroll-bar-mode 0)
(global-display-line-numbers-mode)
(setq-default
display-line-numbers-type 'relative
make-backup-files nil
inhibit-startup-screen t)
(load-theme 'tango-dark t)
'';
extraPackages = epkgs: [
epkgs.zig-mode
epkgs.lsp-mode
];
};
programs.tmux = {
enable = true;
escapeTime = 0;
extraConfig = ''
set-option -g default-terminal screen-256color
set -g history-limit 10000
set -g base-index 1
set-option -g renumber-windows on
bind-key -n M-n new-window -c "#{pane_current_path}"
bind-key -n M-1 select-window -t :1
bind-key -n M-2 select-window -t :2
bind-key -n M-3 select-window -t :3
bind-key -n M-4 select-window -t :4
bind-key -n M-5 select-window -t :5
bind-key -n M-6 select-window -t :6
bind-key -n M-7 select-window -t :7
bind-key -n M-8 select-window -t :8
bind-key -n M-9 select-window -t :9
bind-key -n M-0 select-window -t :0
bind-key -n M-. select-window -n
bind-key -n M-, select-window -p
bind-key -n M-S-. swap-window -t +1
bind-key -n M-S-, swap-window -t -1
bind-key -n M-X confirm-before "kill-window"
bind-key -n M-v split-window -h -c "#{pane_current_path}"
bind-key -n M-b split-window -v -c "#{pane_current_path}"
bind-key -n M-R command-prompt -I "" "rename-window '%%'"
bind-key -n M-f resize-pane -Z
bind-key -n M-h select-pane -L
bind-key -n M-l select-pane -R
bind-key -n M-k select-pane -U
bind-key -n M-j select-pane -D
bind-key -n M-Left select-pane -L
bind-key -n M-Right select-pane -R
bind-key -n M-Up select-pane -U
bind-key -n M-Down select-pane -D
bind-key -n "M-H" run-shell 'old=`tmux display -p "#{pane_index}"`; tmux select-pane -L; tmux swap-pane -t $old'
bind-key -n "M-J" run-shell 'old=`tmux display -p "#{pane_index}"`; tmux select-pane -D; tmux swap-pane -t $old'
bind-key -n "M-K" run-shell 'old=`tmux display -p "#{pane_index}"`; tmux select-pane -U; tmux swap-pane -t $old'
bind-key -n "M-L" run-shell 'old=`tmux display -p "#{pane_index}"`; tmux select-pane -R; tmux swap-pane -t $old'
bind-key -n "M-S-Left" run-shell 'old=`tmux display -p "#{pane_index}"`; tmux select-pane -L; tmux swap-pane -t $old'
bind-key -n "M-S-Down" run-shell 'old=`tmux display -p "#{pane_index}"`; tmux select-pane -D; tmux swap-pane -t $old'
bind-key -n "M-S-Up" run-shell 'old=`tmux display -p "#{pane_index}"`; tmux select-pane -U; tmux swap-pane -t $old'
bind-key -n "M-S-Right" run-shell 'old=`tmux display -p "#{pane_index}"`; tmux select-pane -R; tmux swap-pane -t $old'
bind-key -n M-x confirm-before "kill-pane"
bind-key -n M-/ copy-mode
# Linux system clipboard
bind -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "xclip -in -selection clipboard"
bind-key -T copy-mode-vi MouseDragEnd1Pane send -X copy-pipe-and-cancel "xclip -in -selection clipboard"
set -g mouse on
# set-option -g status-keys vi
# set-option -g set-titles on
# set-option -g set-titles-string 'tmux - #W'
# set -g bell-action any
# set-option -g visual-bell off
# set-option -g set-clipboard off
# setw -g mode-keys vi
# setw -g monitor-activity on
# set -g visual-activity on
# set -g status-style fg=colour15
# set -g status-justify centre
# set -g status-left ""
# set -g status-right ""
# set -g status-interval 1
# set -g message-style fg=colour0,bg=colour3
# setw -g window-status-bell-style fg=colour1
# setw -g window-status-current-style fg=yellow,bold
# setw -g window-status-style fg=colour250
# setw -g window-status-current-format ' #{?#{==:#W,#{b:SHELL}},#{b:pane_current_path},#W} '
# setw -g window-status-format ' #{?#{==:#W,#{b:SHELL}},#{b:pane_current_path},#W} '
# # For older tmux:
# #setw -g window-status-format ' #W '
# #setw -g window-status-current-format ' #W '
'';
};
programs.nushell = {
enable = true;
# for editing directly to config.nu
extraConfig = ''
$env.config = {
show_banner: false,
completions: {
case_sensitive: false # case-sensitive completions
quick: true # set to false to prevent auto-selecting completions
partial: true # set to false to prevent partial filling of the prompt
algorithm: "fuzzy" # prefix or fuzzy
}
hooks: {
command_not_found: { |cmd| (command-not-found $cmd | str trim) }
}
}
'';
# shellAliases = {
# vi = "hx";
# vim = "hx";
# nano = "hx";
# };
};
# programs.carapace = {
# enable = true;
# enableNushellIntegration = true;
# };
# programs.starship = {
# enable = true;
# settings = {
# add_newline = false;
# character = {
# success_symbol = "[➜](bold green)";
# error_symbol = "[➜](bold red)";
# };
# };
# };
programs.firefox = {
enable = true;
profiles = {
default = {
settings = {
"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
"browser.fullscreen.autohide" = false;
"browser.toolbars.bookmarks.visibility" = "never";
"browser.tabs.inTitlebar" = 0;
"browser.compactmode.show" = true;
"browser.uidensity" = 1;
};
userChrome = ''
#TabsToolbar {
visibility: collapse !important;
}
'';
};
appmode = {
id = 1;
settings = {
"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
"browser.fullscreen.autohide" = false;
"browser.toolbars.bookmarks.visibility" = "never";
"browser.tabs.inTitlebar" = 0;
"browser.compactmode.show" = true;
"browser.uidensity" = 1;
};
userChrome = ''
#TabsToolbar {
visibility: collapse !important;
}
#nav-bar {
visibility: collapse !important;
}
#navigator-toolbox {
border-bottom: none !important;
}
'';
};
};
};
gtk.enable = true;
gtk.theme = {
package = theme;
name = "Qogir-Dark";
};
# programs.gnome-shell.theme = {
# package = theme;
# name = "Qogir-Dark";
# };
# gtk.iconTheme = {
# package = pkgs.vimix-icon-theme;
# name = "vimix-doder-dark";
# };
home.pointerCursor = {
gtk.enable = true;
x11.enable = true;
name = "volantes_light_cursors";
size = 24;
package = pkgs.volantes-cursors;
};
# This value determines the Home Manager release that your configuration is
# compatible with. This helps avoid breakage when a new Home Manager release
# introduces backwards incompatible changes.
#
# You should not change this value, even if you update Home Manager. If you do
# want to update the value, then make sure to first check the Home Manager
# release notes.
home.stateVersion = "24.05"; # Please read the comment before changing.
# The home.packages option allows you to install Nix packages into your
# environment.
home.packages = with pkgs; [
nixos-icons
spotify-player
prismlauncher
pandoc
ghidra
gnome-firmware
fzf bat delta silver-searcher ripgrep perl universal-ctags
rofi
# bintools
htop
unzip
rr wrk
clang-tools bear
linuxPackages_latest.perf
texliveFull
asciidoctor-with-extensions
emscripten
caddy
python3
qogir-icon-theme
volantes-cursors
xorg.xkill
lf nnn yazi
feh
xarchiver
tig lazygit gitui
thunderbird
aerc
libreoffice
gimp
guvcview
arandr
vial
ncdu
gnumake gcc
linux-wifi-hotspot
#esptool
picocom
wireshark
nil
bc
ffmpeg-full
sc-im visidata
localsend
vis
wineWowPackages.unstableFull winetricks
signal-desktop
# # It is sometimes useful to fine-tune packages, for example, by applying
# # overrides. You can do that directly here, just don't forget the
# # parentheses. Maybe you want to install Nerd Fonts with a limited number of
# # fonts?
# (pkgs.nerdfonts.override { fonts = [ "FantasqueSansMono" ]; })
# # You can also create simple shell scripts directly inside your
# # configuration. For example, this adds a command 'my-hello' to your
# # environment:
# (pkgs.writeShellScriptBin "my-hello" ''
# echo "Hello, ${config.home.username}!"
# '')
# $@ - Liste aller Parameter
# $* - String aller Parameter
# $# - Anzahl aller Parameter
# &> - stdout und stderr pipen
# '' - Literal
# "" - Expanded
#
(pkgs.writeShellScriptBin "app" ''
${pkgs.firefox}/bin/firefox -p appmode --new-window "$@"
'')
(pkgs.writeShellScriptBin "md" ''
file=$(mktemp --suffix=.html) && \
echo $file && \
${pkgs.pandoc}/bin/pandoc -o $file $1 -s -H ${markdownStyleHeader} && \
app $file && \
rm $file
'')
(pkgs.writeShellScriptBin "run" ''
(nohup "$@" &>/dev/null &); sleep 0
'')
(pkgs.writeShellScriptBin "popup" ''
${pkgs.kitty}/bin/kitty -o hide_window_decorations=yes -o background_opacity=0.5 \
--class kitty-popup -o remember_window_size=no \
-o initial_window_width=120c -o initial_window_height=40c \
"$@"
'')
(pkgs.writeShellScriptBin "fzfdir" ''
find "$1" -name "$2" | ${pkgs.fzf}/bin/fzf --layout=reverse
'')
(pkgs.writeShellScriptBin "file-app" ''
app localhost:8123
'')
(pkgs.writeShellScriptBin "run-popup" ''
popup bash -c 'file=$(compgen -c | grep -v fzf | sort -u | fzf --layout=reverse --print-query | tail -n 1) && run $file'
'')
(pkgs.writeShellScriptBin "set-wallpaper" ''
${pkgs.feh}/bin/feh --bg-fill --no-fehbg ${wallpaper}
'')
(pkgs.writeShellScriptBin "mirror-phone" "IP=$(select-ip) && sudo scrcpy --tcpip=$IP --no-audio -K --kill-adb-on-close")
(pkgs.writeShellScriptBin "select-ip" ''
FILE=$HOME/.cache/select-ip.txt
IP=$( ${pkgs.rofi}/bin/rofi -dmenu -input $FILE -p IP ) || exit 1
echo $IP >> $FILE
gawk -i inplace 'FNR==1{delete a} !a[$0]++' $FILE
echo $IP
'')
(pkgs.writeShellScriptBin "create-repo" ''
ssh psch.dev sudo -u git git init --bare /srv/git/$1
'')
];
# Home Manager is pretty good at managing dotfiles. The primary way to manage
# plain files is through 'home.file'.
home.file = {
# # Building this configuration will create a copy of 'dotfiles/screenrc' in
# # the Nix store. Activating the configuration will then make '~/.screenrc' a
# # symlink to the Nix store copy.
# ".screenrc".source = dotfiles/screenrc;
# # You can also set the file content immediately.
# ".gradle/gradle.properties".text = ''
# org.gradle.console=verbose
# org.gradle.daemon.idletimeout=3600000
# '';
".background-image".source = wallpaper;
};
# Home Manager can also manage your environment variables through
# 'home.sessionVariables'. These will be explicitly sourced when using a
# shell provided by Home Manager. If you don't want to manage your shell
# through Home Manager then you have to manually source 'hm-session-vars.sh'
# located at either
#
# ~/.nix-profile/etc/profile.d/hm-session-vars.sh
#
# or
#
# ~/.local/state/nix/profiles/profile/etc/profile.d/hm-session-vars.sh
#
# or
#
# /etc/profiles/per-user/ps/etc/profile.d/hm-session-vars.sh
#
home.sessionVariables = {
# EDITOR = "emacs";
};
# Let Home Manager install and manage itself.
programs.home-manager.enable = true;
}