Add home-manager config

This commit is contained in:
jalr 2021-11-13 00:09:24 +00:00 committed by Jakob Lechner
parent 30072fc4d6
commit d4540230e4
37 changed files with 2294 additions and 11 deletions

2
.gitignore vendored
View file

@ -1,2 +1,4 @@
result*
.pre-commit-config.yaml
/.direnv
__pycache__

8
flake.lock generated
View file

@ -62,17 +62,17 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1636552551,
"narHash": "sha256-k7Hq/bvUnRlAfFjPGuw3FsSqqspQdRHsCHpgadw6UkQ=",
"lastModified": 1636138231,
"narHash": "sha256-FZQ5wBcB9zI21uQMB/PaEQ/cLYk+Bwnig5cg1+2rPgg=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "9e86f5f7a19db6da2445f07bafa6694b556f9c6d",
"rev": "5c02380de3951d0237807c16eb19873cb3c5f75d",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-21.05",
"repo": "nixpkgs",
"rev": "5c02380de3951d0237807c16eb19873cb3c5f75d",
"type": "github"
}
},

View file

@ -4,6 +4,13 @@
#nixpkgs.url = "github:nixos/nixpkgs/nixos-21.05";
nixpkgs.url = "github:nixos/nixpkgs/5c02380de3951d0237807c16eb19873cb3c5f75d";
nur.url = "github:nix-community/NUR";
home-manager = {
url = "github:nix-community/home-manager/release-21.05";
inputs.nixpkgs.follows = "nixpkgs";
};
nix-pre-commit-hooks = {
url = "github:cachix/pre-commit-hooks.nix/master";
inputs.flake-utils.follows = "flake-utils";
@ -14,6 +21,8 @@
{ self
, nixpkgs
, flake-utils
, home-manager
, nur
, nix-pre-commit-hooks
, ...
}@inputs: flake-utils.lib.eachDefaultSystem
@ -58,6 +67,10 @@
{
_module.args.inputs = inputs;
}
] ++ [{
nixpkgs.overlays = [ nur.overlay ];
}] ++ [
home-manager.nixosModules.home-manager
] ++ extraModules;
})
(import ./machines inputs);

2
home-manager/README.md Normal file
View file

@ -0,0 +1,2 @@
# Documentation
[Home Manager Manual](https://rycee.gitlab.io/home-manager/)

View file

@ -0,0 +1,154 @@
{ pkgs, nixosConfig, ... }:
let
solarized = import ./solarized.nix;
#nixosConfig.myConfig.terminalEmulator.command = pkgs.writeShellScriptBin "alacritty-sway-cwd" ''
# this_alacritty_pid="$(swaymsg -t get_tree | ${pkgs.jq} -e 'recurse(.nodes[]?) | select((.focused==true) and (.app_id=="Alacritty")).pid')"
# if [ "$this_alacritty_pid" ]; then
# child_pid="$(pgrep -P "$this_alacritty_pid")"
# cwd="$(readlink /proc/$child_pid/cwd)"
# fi
# if [ -e "$cwd" ]; then
# exec ${pkgs.alacritty} --working-directory "$cwd"
# fi
# exec alacritty
#'';
colorschemes = {
# https://github.com/alacritty/alacritty/wiki/Color-schemes#solarized
solarized-dark = {
# Default colors
primary = {
background = solarized.base03.hex;
foreground = solarized.base0.hex;
};
# Cursor colors
cursor = {
text = solarized.base03.hex;
cursor = solarized.base0.hex;
};
# Normal colors
normal = {
black = solarized.base02.hex;
red = solarized.red.hex;
green = solarized.green.hex;
yellow = solarized.yellow.hex;
blue = solarized.blue.hex;
magenta = solarized.magenta.hex;
cyan = solarized.cyan.hex;
white = solarized.base2.hex;
};
# Bright colors
bright = {
black = solarized.base03.hex;
red = solarized.orange.hex;
green = solarized.base01.hex;
yellow = solarized.base00.hex;
blue = solarized.base0.hex;
magenta = solarized.violet.hex;
cyan = solarized.base1.hex;
white = solarized.base3.hex;
};
};
solarized-light = {
# Default colors
primary = {
background = solarized.light.base3.hex;
foreground = solarized.light.base00.hex;
};
# Cursor colors
cursor = {
text = solarized.light.base3.hex;
cursor = solarized.light.base00.hex;
};
# Normal colors
normal = {
black = solarized.light.base02.hex;
red = solarized.light.red.hex;
green = solarized.light.green.hex;
yellow = solarized.light.yellow.hex;
blue = solarized.light.blue.hex;
magenta = solarized.light.magenta.hex;
cyan = solarized.light.cyan.hex;
white = solarized.light.base2.hex;
};
# Bright colors
bright = {
black = solarized.light.base03.hex;
red = solarized.light.orange.hex;
green = solarized.light.base01.hex;
yellow = solarized.light.base00.hex;
blue = solarized.light.base0.hex;
magenta = solarized.light.violet.hex;
cyan = solarized.light.base1.hex;
white = solarized.light.base3.hex;
};
};
};
in
{
programs.alacritty = {
enable = nixosConfig.myConfig.gui.enable;
settings = {
font = {
normal = {
family = "Inconsolata for Powerline";
style = "Regular";
};
size = 12;
};
mouse.hide_when_typing = true;
key_bindings = [
{
key = "F1";
mods = "Control";
action = "DecreaseFontSize";
}
{
key = "F2";
mods = "Control";
action = "IncreaseFontSize";
}
];
bell = {
duration = 100;
color = "#000000";
};
window.dynamic_title = true;
scrolling.history = 100000;
colors = colorschemes.solarized-dark;
background_opacity = 0.95;
};
};
programs.fish.functions = {
ssh = {
description = "ssh wrapper function";
wraps = "ssh";
body = ''
if [ "$TERM" = alacritty ]
TERM=xterm-256color command ssh $argv
else
command ssh $argv
end
'';
};
};
}

View file

@ -0,0 +1,17 @@
{ nixosConfig, ... }:
{
imports = [
./${nixosConfig.myConfig.terminalEmulator}.nix
./direnv.nix
./firefox
./fish.nix
./git.nix
./gnuradio.nix
./kdeconnect.nix
./neo.nix
./neovim.nix
./obs-studio.nix
./sway
];
}

View file

@ -0,0 +1,9 @@
{
programs.direnv = {
enable = true;
nix-direnv = {
enable = true;
enableFlakes = true;
};
};
}

View file

@ -0,0 +1,100 @@
{ nixosConfig, pkgs, ... }:
{
programs.firefox = {
enable = nixosConfig.myConfig.gui.enable;
package = pkgs.firefox-esr;
extensions = with pkgs.nur.repos.rycee.firefox-addons; [
tree-style-tab
ublock-origin
umatrix
violentmonkey
];
profiles = {
default = {
settings = {
#"browser.startup.homepage" = "https://nixos.org";
#"browser.search.region" = "GB";
#"browser.search.isUS" = false;
#"distribution.searchplugins.defaultLocale" = "en-GB";
#"general.useragent.locale" = "en-GB";
#"browser.bookmarks.showMobileBookmarks" = true;
"app.normandy.enabled" = false;
"app.shield.optoutstudies.enabled" = false;
"app.update.auto" = false;
"browser.fixup.alternate.enabled" = false;
"browser.formfill.enable" = false;
"browser.newtabpage.enabled" = false;
"browser.ping-centre.telemetry" = false;
"browser.safebrowsing.downloads.enabled" = false;
"browser.safebrowsing.downloads.remote.block_dangerous" = false;
"browser.safebrowsing.downloads.remote.block_dangerous_host" = false;
"browser.safebrowsing.downloads.remote.block_potentially_unwanted" = false;
"browser.safebrowsing.downloads.remote.block_uncommon" = false;
"browser.safebrowsing.downloads.remote.enabled" = false;
"browser.safebrowsing.downloads.remote.url" = "";
"browser.safebrowsing.malware.enabled" = false;
"browser.safebrowsing.phishing.enabled" = false;
"browser.safebrowsing.provider.google.advisoryURL" = "";
"browser.safebrowsing.provider.google.gethashURL" = "";
"browser.safebrowsing.provider.google.lists" = "";
"browser.safebrowsing.provider.google.reportMalwareMistakeURL" = "";
"browser.safebrowsing.provider.google.reportPhishMistakeURL" = "";
"browser.safebrowsing.provider.google.reportURL" = "";
"browser.safebrowsing.provider.google.updateURL" = "";
"browser.safebrowsing.provider.google4.advisoryURL" = "";
"browser.safebrowsing.provider.google4.dataSharingURL" = "";
"browser.safebrowsing.provider.google4.gethashURL" = "";
"browser.safebrowsing.provider.google4.lists" = "";
"browser.safebrowsing.provider.google4.reportMalwareMistakeURL" = "";
"browser.safebrowsing.provider.google4.reportPhishMistakeURL" = "";
"browser.safebrowsing.provider.google4.reportURL" = "";
"browser.safebrowsing.provider.google4.updateURL" = "";
"browser.safebrowsing.provider.mozilla.gethashURL" = "";
"browser.safebrowsing.provider.mozilla.lists" = "";
"browser.safebrowsing.provider.mozilla.updateURL" = "";
"browser.search.suggest.enabled" = false;
"browser.search.widget.inNavBar" = true;
"browser.startup.page" = 0;
"extensions.pocket.enabled" = false;
"extensions.update.enabled" = false;
"identity.fxaccounts.enabled" = false;
"keyword.enabled" = false;
"network.captive-portal-service.enabled" = false;
"network.predictor.enabled" = false;
"privacy.donottrackheader.enabled" = true;
"startup.homepage_welcome_url" = about:blank;
"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
"toolkit.telemetry.archive.enabled" = false;
"toolkit.telemetry.bhrPing.enabled" = false;
"toolkit.telemetry.firstShutdownPing.enabled" = false;
"toolkit.telemetry.newProfilePing.enabled" = false;
"toolkit.telemetry.server" = http://127.0.0.1:4711;
"toolkit.telemetry.server_owner" = "";
"toolkit.telemetry.shutdownPingSender.enabled" = false;
"toolkit.telemetry.updatePing.enabled" = false;
"urlclassifier.downloadAllowTable" = "";
"urlclassifier.downloadBlockTable" = "";
"urlclassifier.malwareTable" = "";
"urlclassifier.phishTable" = "";
"datareporting.healthreport.uploadEnabled" = "";
"app.normandy.api_url" = "";
"breakpad.reportURL" = "";
"browser.region.network.url" = "";
"browser.search.geoSpecificDefaults.url" = "";
"browser.shell.checkDefaultBrowser" = false;
"privacy.userContext.enabled" = true;
"privacy.userContext.ui.enabled" = true;
"network.dnsCacheExpiration" = 0;
# disable disk cache to reduce ssd writes
"browser.cache.disk.enable" = false;
"browser.cache.memory.enable" = true;
"browser.cache.memory.capacity" = -1;
};
userChrome = builtins.readFile ./userChrome.css;
};
};
};
}

View file

@ -0,0 +1,221 @@
@-moz-document url(chrome://browser/content/browser.xul),
url(chrome://browser/content/browser.xhtml) {
/* hide tab toolbar */
#TabsToolbar {
visibility: collapse !important;
}
/*** Megabar Styler General - version 2020-07-27 ***/
/*** General Preferences ***/
:root {
/* Number of pixels of enlargement when URL bar is focused */
--mbarstyler-popout-pixels: 0px; /* [0px - 7px] */
/* Top Bar Display or Not */
--mbarstyler-top-bar-display: none; /* [block,none] */
/* Font sizes (default: 13.8px for title, 10.2px for URL) */
--mbarstyler-title-font-size: 15px; /* [13px - 18px] */
--mbarstyler-url-font-size: 13px; /* [12px - 16px] */
/* Rows to show without scrolling */
--mbarstyler-max-rows-without-scrolling: 10;
/* Bottom border for each result row */
--mbarstyler-bottom-border-width: 1px; /* [0px or 1px] */
/* Match display style */
--mbarstyler-match-weight: 700; /* [400,700] */
--mbarstyler-match-background-opacity: 0.0; /* [0.0,0.05,0.1] */
}
/*** URL bar enlargement or lack thereof ***/
/* Compute new position, width, and padding */
#urlbar[breakout][breakout-extend] {
top: calc(5px - var(--mbarstyler-popout-pixels)) !important;
left: calc(0px - var(--mbarstyler-popout-pixels)) !important;
width: calc(100% + (2 * var(--mbarstyler-popout-pixels))) !important;
padding: var(--mbarstyler-popout-pixels) !important;
}
[uidensity="compact"] #urlbar[breakout][breakout-extend] {
top: calc(3px - var(--mbarstyler-popout-pixels)) !important;
}
[uidensity="touch"] #urlbar[breakout][breakout-extend] {
top: calc(4px - var(--mbarstyler-popout-pixels)) !important;
}
/* Prevent shift of URL bar contents */
#urlbar[breakout][breakout-extend] > #urlbar-input-container {
height: var(--urlbar-height) !important;
padding: 0 !important;
}
/* Do not animate */
#urlbar[breakout][breakout-extend] > #urlbar-background {
animation: none !important;;
}
/* Remove shadows */
#urlbar[breakout][breakout-extend] > #urlbar-background {
box-shadow: none !important;
}
/*** Top "Blue Bar" Display ***/
.urlbarView-row:first-of-type {
display: var(--mbarstyler-top-bar-display) !important;
}
/*** Font Sizes and Scrolling ***/
/* Title font-size */
.urlbarView-row .urlbarView-title {
font-size: var(--mbarstyler-title-font-size) !important;
}
/* URL / action font-size */
.urlbarView-row .urlbarView-secondary,
.urlbarView-row .urlbarView-url,
.urlbarView-row .urlbarView-action {
font-size: var(--mbarstyler-url-font-size) !important;
}
/* Set max-height for items visible without scrolling */
#urlbarView-results, #urlbar-results {
height: unset !important;
max-height: calc(2.5 * (var(--mbarstyler-title-font-size) + var(--mbarstyler-bottom-border-width)) * var(--mbarstyler-max-rows-without-scrolling)) !important;
}
#urlbar-results {
overflow-y: auto !important;
}
/* Clean up extra spacing at the top and bottom */
#urlbar-results {
padding-top: 0 !important;
padding-bottom: 0 !important;
}
/* Subtle border between results */
.urlbarView-row:not(:last-of-type) {
border-bottom: var(--mbarstyler-bottom-border-width) solid rgba(0, 0, 0, 0.1) !important;
}
/* Match Styling Like Fx43-47 */
.urlbarView-row:not([selected]) .urlbarView-title strong,
.urlbarView-row:not([selected]) .urlbarView-url strong {
font-weight: var(--mbarstyler-match-weight) !important;
border-radius: 2px;
box-shadow: inset 0 0 1px 1px rgba(0, 0, 0, calc(var(--mbarstyler-match-background-opacity) * 2));
background-color: rgba(0, 0, 0, var(--mbarstyler-match-background-opacity));
}
[lwt-popup-brighttext] .urlbarView-row:not([selected]) .urlbarView-title strong,
[lwt-popup-brighttext] .urlbarView-row:not([selected]) .urlbarView-url strong {
box-shadow: inset 0 0 1px 1px rgba(255, 255, 255, calc(var(--mbarstyler-match-background-opacity) * 2));
background-color: rgba(255, 255, 255, var(--mbarstyler-match-background-opacity));
}
[lwthemetextcolor="bright"] .urlbarView-row:not([selected]) .urlbarView-title strong,
[lwthemetextcolor="bright"] .urlbarView-row:not([selected]) .urlbarView-url strong {
box-shadow: inset 0 0 1px 1px rgba(192, 192, 192, calc(var(--mbarstyler-match-background-opacity) * 4));
background-color: rgba(192, 192, 192, calc(var(--mbarstyler-match-background-opacity) * 3));
}
/*** End of: Megabar Styler General ***/
/*** Megabar Styler Two-Row Flex Layout - version 2020-06-03 ***/
/* !!! Requires variables from Megabar Styler General !!! */
/* Adjust heights for scrolling */
#urlbarView-results, #urlbar-results {
max-height: calc(1.625 * (var(--mbarstyler-title-font-size) + var(--mbarstyler-url-font-size) + var(--mbarstyler-bottom-border-width)) * var(--mbarstyler-max-rows-without-scrolling)) !important;
}
/* Wrap the url (adapted from Fx75 narrow bar design) */
.urlbarView-row-inner {
flex-wrap: wrap !important;
padding-top: 0 !important;
padding-bottom: 2px !important;
}
.urlbarView-no-wrap {
max-width: 100% !important;
flex-basis: 100% !important;
position: relative;
}
/* Adjust horizontal and vertical URL position */
.urlbarView-row[has-url] > .urlbarView-row-inner > .urlbarView-url {
padding-inline-start: calc(6px + 2px + /* favicon */ 16px) !important;
margin-top: calc(2px + (var(--mbarstyler-url-font-size) - var(--mbarstyler-title-font-size)));
}
/* Hide the separator if there's a URL */
.urlbarView[actionoverride] .urlbarView-row[has-url] .urlbarView-title-separator,
.urlbarView .urlbarView-row[has-url]:not([type$=tab]) .urlbarView-title-separator,
.urlbarView .urlbarView-row[type=remotetab]:-moz-any(:hover, [selected]) .urlbarView-title-separator {
display: none !important;
}
/* Move Switch Tab info to URL line :: added 2020-04-12 */
/* Make sure URL is always visible */
.urlbarView-row[type="switchtab"][has-url="true"] .urlbarView-url {
visibility: visible !important;
}
/* Show Switch to Tab or Open depending on [actionoverride] */
.urlbarView:not([actionoverride]) .urlbarView-row[type="switchtab"][has-url="true"] .urlbarView-url::before {
content: "Switch to Tab: ";
font-style: italic;
color: var(--urlbar-popup-action-color);
}
.urlbarView:not([actionoverride]) .urlbarView-row[type="switchtab"][has-url="true"][selected] .urlbarView-url::before {
color: HighlightText; /* 2020-05-31 improve visibility when selected */
}
.urlbarView[actionoverride] .urlbarView-row[type="switchtab"][has-url="true"] .urlbarView-url::before {
content: "Open: ";
font-style: italic;
color: var(--urlbar-popup-action-color);
}
.urlbarView[actionoverride] .urlbarView-row[type="switchtab"][has-url="true"][selected] .urlbarView-url::before {
color: HighlightText; /* 2020-05-31 improve visibility when selected */
}
/* Hide the existing Action phrase and separator */
.urlbarView-row[type="switchtab"][has-url="true"] .urlbarView-action,
.urlbarView-row[type="switchtab"][has-url="true"] .urlbarView-title-separator {
display: none !important;
}
/* A little more room for the address bar when drop-down is open :: added 2020-06-02 */
.urlbarView {
margin-block-start: 0 !important;
}
/*** End of: Megabar Styler Two-Row Flex Layout ***/
/*** Megabar Styler One-Offs - version 2020-05-31 ***/
/*** One-Off Search Button Preferences ***/
:root {
/* One-Offs Display or Not */
--mbarstyler-oneoffs-display: none; /* [flex,none] */
}
/* Show or Hide the One-Offs Search Icon Bar */
#urlbar .search-one-offs:not([hidden]) {
display: var(--mbarstyler-oneoffs-display) !important;
}
/* Shorten the One-Offs Search Icon Bar Vertically */
#urlbar .search-one-offs:not([hidden]) {
padding-block: unset !important;
}
/* We don't need the text */
#urlbar .search-one-offs .search-panel-header {
display: none !important;
}
/*** End of: Megabar Styler One-Offs ***/
}

View file

@ -0,0 +1,172 @@
{ config, pkgs, ... }:
{
programs.fish = {
enable = true;
plugins = [
{
name = "theme-agnoster";
src = pkgs.fetchFromGitHub {
owner = "oh-my-fish";
repo = "theme-agnoster";
rev = "43860ce1536930bca689470e26083b0a5b7bd6ae";
sha256 = "16k94hz3s6wayass6g1lhlcjmbpf2w8mzx90qrrqp120h80xwp25";
fetchSubmodules = true;
};
}
{
name = "fzf";
src = pkgs.fetchFromGitHub {
owner = "jethrokuan";
repo = "fzf";
rev = "479fa67d7439b23095e01b64987ae79a91a4e283";
sha256 = "0k6l21j192hrhy95092dm8029p52aakvzis7jiw48wnbckyidi6v";
fetchSubmodules = true;
};
}
];
shellAliases = {
ls = "ls --color=auto";
crontab = "crontab -i";
};
#interactiveShellInit = ''
# echo "programs.fish.interactiveShellInit"
#'';
shellInit = ''
# key bindings
bind \cr '__fzf_reverse_isearch'
# PATH
set -U fish_user_paths $HOME/.local/bin $HOME/.local/bin/pio
# pass
#set -x PASSWORD_STORE_ENABLE_EXTENSIONS true
set -x AWS_VAULT_BACKEND pass
set -x AWS_VAULT_PASS_PREFIX aws
# colors
set -x GCC_COLORS 'error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
abbr --add v vim
#alias cal='ncal -b -M'
alias myip='dig +short myip.opendns.com @resolver1.opendns.com'
function hm -d 'merge history and delete failed commands'
history --merge
if test -z "$fish_private_mode" && test -e "$__fish_user_data_dir/successful_commands" && test -e "$__fish_user_data_dir/failed_commands"
while read line;
if ! grep -qFx $line "$__fish_user_data_dir/successful_commands"
set hist_command (echo $line | base64 -d)
echo "deleting command: $hist_command"
echo "."
history delete --exact --case-sensitive $hist_command
end
end < "$__fish_user_data_dir/failed_commands"
echo -n > "$__fish_user_data_dir/successful_commands"
echo -n > "$__fish_user_data_dir/failed_commands"
end
end
hm
# fancy tools
if which exa > /dev/null 2>&1
alias l=exa
alias ll='exa -l --time-style=long-iso --git'
alias la='exa -la --time-style=long-iso --git'
alias tree='exa --tree'
alias llt='exa -s modified -l'
else
alias l=ls
alias ll='ls -l'
alias la='ls -la'
alias llt='ls -trl'
end
if which rg > /dev/null 2>&1
alias g=rg
complete -c g -w rg
else if which ag > /dev/null 2>&1
alias g=ag
complete -c g -w ag
else
alias g='grep --color=auto'
complete -c g -w grep
end
function betaflight-configurator -d 'betaflight-configurator wrapper function' --wraps betaflight-configurator
GDK_BACKEND="x11" command betaflight-configurator $argvl
end
function jqless -d 'jq -C [args] | less -R'
jq -C $argv | less -R
end
# NixOS direnv
if which direnv > /dev/null
eval (direnv hook fish)
end
function __cut_commandline -d 'cut commandline and paste it later'
set -g commandline_buffer (commandline)
commandline ""
end
function __postexec --on-event fish_postexec
if test $status -ne 0
if test -z "$hist_cmd"
if test -z "$fish_private_mode"
echo $argv[1] | base64 >> "$__fish_user_data_dir/failed_commands"
end
end
else
if test -z "$fish_private_mode"
echo $argv[1] | base64 >> "$__fish_user_data_dir/successful_commands"
end
commandline $commandline_buffer
set -e commandline_buffer
end
end
function dirh-nocolor --description "Print the current directory history (the prev and next lists)"
set -l options h/help
argparse -n dirh --max-args=0 $options -- $argv
or return
if set -q _flag_help
__fish_print_help dirh
return 0
end
set -l dirc (count $dirprev)
if test $dirc -gt 0
set -l dirprev_rev $dirprev[-1..1]
# This can't be (seq $dirc -1 1) because of BSD.
set -l dirnum (seq 1 $dirc)
for i in $dirnum[-1..1]
printf '%s\n' $dirprev_rev[$i]
end
end
echo $PWD
set -l dirc (count $dirnext)
if test $dirc -gt 0
set -l dirnext_rev $dirnext[-1..1]
for i in (seq $dirc)
printf '%s\n' $dirnext_rev[$i]
end
end
end
function dirh-fzf -d 'directory history fuzzy finder'
builtin cd (dirh-nocolor | uniq | fzf)
end
bind \ed 'dirh-fzf'
'';
};
}

View file

@ -0,0 +1,123 @@
{ nixosConfig, pkgs, ... }:
{
home.packages = with pkgs; [
fzf
gitAndTools.diff-so-fancy
];
programs = {
git = {
enable = true;
userName = nixosConfig.myConfig.git.user.name;
userEmail = nixosConfig.myConfig.git.user.email;
extraConfig = {
core.pager = "diff-so-fancy | less --tabs=4 -RFX";
pull.ff = "only";
alias.find-merge = "!sh -c 'commit=$0 && branch=\${1:-HEAD} && (git rev-list $commit..$branch --ancestry-path | cat -n; git rev-list $commit..$branch --first-parent | cat -n) | sort -k2 -s | uniq -f1 -d | sort -n | tail -1 | cut -f2'";
alias.show-merge = "!sh -c 'merge=$(git find-merge $0 $1) && [ -n \"$merge\" ] && git show $merge'";
};
};
fish = {
shellAbbrs = {
ga = "git add";
gam = "git commit --amend";
gap = "git add --patch";
gb = "git branch";
gbd = "git branch --delete";
gbl = "git blame";
gbm = "git branch --move";
gc = "git clean";
gcl = "git clone";
gcm = "git commit --verbose";
gco = "git checkout";
gd = "git diff";
gdc = "git diff --cached";
gf = "git fetch";
ginit = "git init";
gl = "git log";
gpll = "git pull";
gpsh = "git push";
grb = "git rebase --autostash";
grbi = "git rebase --autostash --interactive --autosquash \(git merge-base HEAD origin/master\)";
gr = "git restore";
grs = "git restore --staged";
grst = "git reset";
gs = "git status";
gsh = "git show";
gsm = "git submodule";
gsmi = "git submodule init";
gsmu = "git submodule update";
gsp = "git stash pop";
gst = "git stash";
gsw = "git switch";
gswc = "git switch -c";
gwl = "git worktree list";
gwr = "git worktree remove";
};
functions = {
#function gwa -d 'git worktree add'
gwa = {
description = "Add worktree";
body = ''
set -l dir (basename $argv[1])
git worktree add ../$dir -b (whoami)/$argv[1] && cd ../$dir
'';
};
# function git -d 'git wrapper function' --wraps git
git = {
description = "git wrapper function";
wraps = "git";
body = ''
if test (count $argv) -eq 0
command git
return $status
else
switch $argv[1]
case push
command git $argv
set -l git_result $status
if [ $git_result -eq 128 ]
set set_upstream (command git push 3>&1 1>&2 2>&3 3>&- | grep -o 'git push --set-upstream.*$')
if [ ! -z "$set_upstream" ]
echo "set upstream: $set_upstream"
commandline $set_upstream
commandline -f repaint
end
end
return $git_result
case '*'
command git $argv
return $status
end
end
'';
};
git_pick-commit_merge-base_origin_master = {
description = "fuzzy find a commit hash";
body = ''
git log --oneline (git merge-base HEAD origin/master)..HEAD | fzf --preview='git show (echo {} | cut -d" " -f 1)' --preview-window=top:75% | cut -d" " -f 1
'';
};
gfix = {
description = "git commit --fixup with fuzzy find commmit picker";
body = ''
set commit (git_pick-commit_merge-base_origin_master)
commandline "git commit --fixup=$commit"
'';
};
".g" = {
description = "change directory to repository root";
body = ''
set git_repo_dir (git rev-parse --show-toplevel 2>/dev/null)
if [ "$git_repo_dir" ]
cd $git_repo_dir
else
return 1
end
'';
};
};
};
};
}

View file

@ -0,0 +1,13 @@
{ nixosConfig, lib, pkgs, ... }:
let
gnuradioEnv = pkgs.gnuradio3_8.override {
extraPackages = pkgs.lib.attrVals [
"osmosdr"
]
pkgs.gnuradio3_8Packages;
};
in
(lib.mkIf nixosConfig.myConfig.gui.enable {
home.packages = [ gnuradioEnv ];
})

View file

@ -0,0 +1,7 @@
{ nixosConfig, pkgs, lib, ... }: {
services.kdeconnect = {
enable = nixosConfig.myConfig.gui.enable;
#indicator = true;
};
}

View file

@ -0,0 +1,22 @@
{ pkgs, ... }:
let
mute-indicator = pkgs.callPackage mute-indicator/default.nix { };
in
{
home.packages = [
mute-indicator
];
systemd.user.services.mute-indicator = {
Unit.Description = "Mute Indicator";
Service = {
Type = "simple";
ExecStart = "${mute-indicator}/bin/service";
Environment = "DEVICE=dasUSBViech";
RestartSec = 5;
Restart = "on-failure";
};
Install.WantedBy = [ "default.target" ];
};
}

View file

@ -0,0 +1,7 @@
{ config, pkgs, ... }:
{
home.sessionVariables = {
XKB_DEFAULT_LAYOUT = "de";
XKB_DEFAULT_VARIANT = "neo";
};
}

View file

@ -0,0 +1,73 @@
{ config, pkgs, ... }:
{
home.sessionVariables = {
EDITOR = "nvim";
};
programs.neovim = {
enable = true;
vimAlias = true;
extraConfig = ''
colorscheme NeoSolarized
"""""""""""""""""
" Swap and undo "
set noswapfile
set nobackup
if has('persistent_undo')
" yay persistent undo
:silent !mkdir -p ~/.local/vim-undo
set undofile
set undodir=~/.local/vim-undo
endif
cabbr <expr> %% expand('%:p:h')
set listchars=trail:·,precedes:«,extends:»,eol:,tab:\
nmap <silent> <leader>c :set list!<CR>
set smartcase
set hlsearch
nnoremap <silent> <CR> :nohlsearch<CR>:set nolist<CR><CR>
" highlight whitespace
highlight ExtraWhitespace ctermbg=red guibg=red
highlight WrongIndent ctermbg=2 guibg=blue
match ExtraWhitespace /\s\+$/
augroup highlight_extra_whitespace
autocmd BufWinEnter * match ExtraWhitespace /\s\+$/
autocmd InsertEnter * match ExtraWhitespace /\s\+\%#\@<!$/
autocmd InsertLeave * match ExtraWhitespace /\s\+$/
autocmd BufWinLeave * call clearmatches()
augroup END
let g:LanguageClient_serverCommands = {
\ 'c': ['${pkgs.ccls}/ccls'],
\ 'cpp': ['${pkgs.ccls}/bin/ccls'],
\ 'python': ['${pkgs.python38Packages.python-language-server}/bin/pyls'],
\ 'ruby': ['${pkgs.solargraph}/bin/solargraph', 'stdio'],
\ 'sh': ['${pkgs.nodePackages.bash-language-server}/bin/bash-language-server', 'start'],
\ 'terraform': ['${pkgs.terraform-lsp}/bin/terraform-lsp', 'serve'],
\ 'yaml': ['${pkgs.nodePackages.yaml-language-server}/yaml-language-server', '--stdio'],
\ 'nix': ['${pkgs.rnix-lsp}/bin/rnix-lsp'],
\ }
let g:deoplete#enable_at_startup = 1
'';
# nix-env -f '<nixpkgs>' -qaP -A vimPlugins
plugins = with pkgs.vimPlugins; [
#Valloric/MatchTagAlways
#frankier/neovim-colors-solarized-truecolor-only
#nvie/vim-rst-tables
LanguageClient-neovim
NeoSolarized
deoplete-nvim
editorconfig-vim
vim-gitgutter
vim-indent-guides
vim-nix
vim-puppet
vim-terraform
];
};
}

View file

@ -0,0 +1,9 @@
{ nixosConfig, pkgs, ... }:
{
programs.obs-studio = {
enable = nixosConfig.myConfig.gui.enable;
plugins = with pkgs; [
obs-wlrobs
];
};
}

View file

@ -0,0 +1,66 @@
{
base00 = {
hex = "#657b83";
rgb = "101,123,131";
};
base01 = {
hex = "#586e75";
rgb = "88,110,117";
};
base02 = {
hex = "#073642";
rgb = "7,54,66";
};
base03 = {
hex = "#002b36";
rgb = "0,43,54";
};
base0 = {
hex = "#839496";
rgb = "131,148,150";
};
base1 = {
hex = "#93a1a1";
rgb = "147,161,161";
};
base2 = {
hex = "#eee8d5";
rgb = "238,232,213";
};
base3 = {
hex = "#fdf6e3";
rgb = "253,246,227";
};
blue = {
hex = "#268bd2";
rgb = "38,139,210";
};
cyan = {
hex = "#2aa198";
rgb = "42,161,152";
};
green = {
hex = "#859900";
rgb = "133,153,0";
};
magenta = {
hex = "#d33682";
rgb = "211,54,130";
};
orange = {
hex = "#cb4b16";
rgb = "203,75,22";
};
red = {
hex = "#dc322f";
rgb = "220,50,47";
};
violet = {
hex = "#6c71c4";
rgb = "108,113,196";
};
yellow = {
hex = "#b58900";
rgb = "181,137,0";
};
}

View file

@ -0,0 +1,363 @@
{ nixosConfig, config, lib, pkgs, ... }:
let
solarized = import ../solarized.nix;
terminalEmulator =
if nixosConfig.myConfig.terminalEmulator == "alacritty"
then
pkgs.writeShellScript "alacritty-sway-cwd" ''
this_alacritty_pid="$(${pkgs.sway}/bin/swaymsg -t get_tree | ${pkgs.jq}/bin/jq -e 'recurse(.nodes[]?) | select((.focused==true) and (.app_id=="Alacritty")).pid')"
if [ "$this_alacritty_pid" ]; then
child_pid="$(pgrep -P "$this_alacritty_pid")"
cwd="$(readlink /proc/$child_pid/cwd)"
fi
if [ -e "$cwd" ]; then
exec ${pkgs.alacritty}/bin/alacritty --working-directory "$cwd"
fi
exec ${pkgs.alacritty}/bin/alacritty
''
else nixosConfig.myConfig.terminalEmulator;
cfg = config.wayland.windowManager.sway.config;
wallpaper = pkgs.fetchurl {
url = "https://raw.githubusercontent.com/swaywm/sway/3b2bc894a5ebbcbbd6707d45a25d171779c2e874/assets/Sway_Wallpaper_Blue_1920x1080.png";
sha256 = "1rkqd0h7w64plibn7k3krk5vdc3pnv3fc7m2xc2mxnwrbsgngwsz";
meta.license = lib.licenses.cc0;
};
in
{
imports = lib.optionals nixosConfig.myConfig.gui.enable [
./waybar.nix
./wofi.nix
];
} // (lib.mkIf nixosConfig.myConfig.gui.enable {
home.packages = with pkgs; [
sway-contrib.grimshot # screenshots
wdisplays # graphical output manager
];
home.sessionVariables = {
QT_QPA_PLATFORM = "wayland";
QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
ELM_ENGINE = "wayland_shm";
GDK_BACKEND = "wayland";
_JAVA_AWT_WM_NONREPARENTING = "1";
};
#home.sessionVariables = {
# CLUTTER_BACKEND = "wayland";
# GDK_BACKEND = "wayland";
# GDK_DPI_SCALE = 1;
# MOZ_ENABLE_WAYLAND = 1;
# QT_QPA_PLATFORM = "wayland-egl";
# QT_WAYLAND_DISABLE_WINDOWDECORATION = 1;
# SDL_VIDEODRIVER = "wayland";
# WLR_NO_HARDWARE_CURSORS = 1;
# _JAVA_AWT_WM_NONREPARENTING = 1;
# _JAVA_OPTIONS = "-Dawt.useSystemAAFontSettings=on";
#};
programs.fish.loginShellInit = ''
if [ -z $WAYLAND_DISPLAY ] && [ (tty) = /dev/tty1 ]
export XDG_SESSION_TYPE="wayland" # otherwise set to tty
exec systemd-cat -t sway sway
end
'';
wayland.windowManager.sway = {
enable = true;
config = {
modifier = "Mod4";
left = "n";
right = "t";
up = "g";
down = "r";
terminal = "${terminalEmulator}";
menu = "${pkgs.wofi}/bin/wofi --allow-images --show drun";
output."*".bg = "${wallpaper} fill";
# FIXME
#input = {
# #"type:keyboard" = {
# # xkb_layout = "neo";
# #};
#} // (lib.optionalAttrs (nixosConfig.networking.hostName == "mayushii") {
# "type:touchpad".events = "disabled";
# "2:10:TPPS/2_Elan_TrackPoint".pointer_accel = "-0.15";
#});
keybindings = {
"${cfg.modifier}+Return" = "exec ${cfg.terminal}";
"${cfg.modifier}+Backspace" = "exec ${cfg.terminal}";
"--to-code ${cfg.modifier}+Escape" = "exec ${cfg.menu}";
#"--to-code ${cfg.modifier}+udiaeresis" = "exec ${cfg.menu}";
"${cfg.modifier}+Shift+c" = "kill";
# "${cfg.modifier}+r" = "exec ${cfg.menu}";
# "${cfg.modifier}+Control+r" = "reload";
"${cfg.modifier}+Shift+q" = "exec ${pkgs.sway}/bin/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' '${pkgs.sway}/bin/swaymsg exit'";
# Focus
"${cfg.modifier}+${cfg.left}" = "focus left";
"${cfg.modifier}+${cfg.down}" = "focus down";
"${cfg.modifier}+${cfg.up}" = "focus up";
"${cfg.modifier}+${cfg.right}" = "focus right";
"${cfg.modifier}+Left" = "focus left";
"${cfg.modifier}+Down" = "focus down";
"${cfg.modifier}+Up" = "focus up";
"${cfg.modifier}+Right" = "focus right";
# Moving
"${cfg.modifier}+Shift+${cfg.left}" = "move left";
"${cfg.modifier}+Shift+${cfg.down}" = "move down";
"${cfg.modifier}+Shift+${cfg.up}" = "move up";
"${cfg.modifier}+Shift+${cfg.right}" = "move right";
"${cfg.modifier}+Shift+Left" = "move left";
"${cfg.modifier}+Shift+Down" = "move down";
"${cfg.modifier}+Shift+Up" = "move up";
"${cfg.modifier}+Shift+Right" = "move right";
# Workspaces
"${cfg.modifier}+1" = "workspace number 1";
"${cfg.modifier}+2" = "workspace number 2";
"${cfg.modifier}+3" = "workspace number 3";
"${cfg.modifier}+4" = "workspace number 4";
"${cfg.modifier}+5" = "workspace number 5";
"${cfg.modifier}+6" = "workspace number 6";
"${cfg.modifier}+7" = "workspace number 7";
"${cfg.modifier}+8" = "workspace number 8";
"${cfg.modifier}+9" = "workspace number 9";
"${cfg.modifier}+0" = "workspace number 10";
"${cfg.modifier}+h" = "workspace prev_on_output";
"${cfg.modifier}+f" = "workspace next_on_output";
"${cfg.modifier}+Shift+1" = "move container to workspace number 1";
"${cfg.modifier}+Shift+2" = "move container to workspace number 2";
"${cfg.modifier}+Shift+3" = "move container to workspace number 3";
"${cfg.modifier}+Shift+4" = "move container to workspace number 4";
"${cfg.modifier}+Shift+5" = "move container to workspace number 5";
"${cfg.modifier}+Shift+6" = "move container to workspace number 6";
"${cfg.modifier}+Shift+7" = "move container to workspace number 7";
"${cfg.modifier}+Shift+8" = "move container to workspace number 8";
"${cfg.modifier}+Shift+9" = "move container to workspace number 9";
"${cfg.modifier}+Shift+0" = "move container to workspace number 10";
# Moving workspaces between outputs
"${cfg.modifier}+Control+${cfg.left}" = "move workspace to output left";
"${cfg.modifier}+Control+${cfg.down}" = "move workspace to output down";
"${cfg.modifier}+Control+${cfg.up}" = "move workspace to output up";
"${cfg.modifier}+Control+${cfg.right}" = "move workspace to output right";
"${cfg.modifier}+Control+Left" = "move workspace to output left";
"${cfg.modifier}+Control+Down" = "move workspace to output down";
"${cfg.modifier}+Control+Up" = "move workspace to output up";
"${cfg.modifier}+Control+Right" = "move workspace to output right";
# Splits
"${cfg.modifier}+e" = "splith";
"${cfg.modifier}+a" = "splitv";
# Layouts
"${cfg.modifier}+j" = "layout stacking";
"${cfg.modifier}+period" = "layout tabbed";
"${cfg.modifier}+comma" = "layout toggle split";
"${cfg.modifier}+m" = "fullscreen toggle";
#"${cfg.modifier}+a" = "focus parent";
"${cfg.modifier}+Shift+space" = "floating toggle";
"${cfg.modifier}+space" = "focus mode_toggle";
## Scratchpad
"${cfg.modifier}+Shift+b" = "move scratchpad";
"${cfg.modifier}+b" = "scratchpad show";
## Resize mode
"${cfg.modifier}+s" = "mode resize";
## Multimedia Keys
#"XF86AudioMute" = "exec ${pkgs.pulseaudio}/bin/pactl set-sink-mute @DEFAULT_SINK@ toggle";
#"XF86AudioMicMute" = "exec ${pkgs.pulseaudio}/bin/pactl set-source-mute @DEFAULT_SOURCE@ toggle";
#"--locked XF86MonBrightnessDown" = "exec ${pkgs.brightnessctl}/bin/brightnessctl set 5%-";
#"--locked XF86MonBrightnessUp" = "exec ${pkgs.brightnessctl}/bin/brightnessctl set +5%";
#"XF86AudioRaiseVolume" = "exec ${pkgs.pulseaudio}/bin/pactl set-sink-volume @DEFAULT_SINK@ +5%";
#"XF86AudioLowerVolume" = "exec ${pkgs.pulseaudio}/bin/pactl set-sink-volume @DEFAULT_SINK@ -5%";
#"XF86AudioPrev" = "exec ${pkgs.mpc_cli}/bin/mpc -q next";
#"XF86AudioNext" = "exec ${pkgs.mpc_cli}/bin/mpc -q prev";
#"XF86AudioPlay" = "exec ${pkgs.mpc_cli}/bin/mpc -q toggle";
## Mumble PTT
#"--no-repeat Shift_R" = "exec ${pkgs.dbus}/bin/dbus-send --session --type=method_call --dest=net.sourceforge.mumble.mumble / net.sourceforge.mumble.Mumble.startTalking";
#"--no-repeat --release Shift_R" = "exec ${pkgs.dbus}/bin/dbus-send --session --type=method_call --dest=net.sourceforge.mumble.mumble / net.sourceforge.mumble.Mumble.stopTalking";
## reset
#"Shift_R+Shift" = "exec ${pkgs.dbus}/bin/dbus-send --session --type=method_call --dest=net.sourceforge.mumble.mumble / net.sourceforge.mumble.Mumble.stopTalking";
"XF86AudioMute" = "exec pactl set-source-mute alsa_input.usb-BEHRINGER_UMC202HD_192k-00.analog-stereo-input toggle";
"${cfg.modifier}+l" = "exec ${pkgs.swaylock}/bin/swaylock -f -i ${wallpaper}";
};
bars = [ ]; # managed as systemd user unit
assigns = {
"5" = [
{ app_id = "firefox"; }
{ app_id = "anki"; }
];
"3" = [
{ class = "Claws-mail"; }
];
"4" = [
{ app_id = "net.sourceforge.mumble."; }
];
"2" = [
{ app_id = "audacious"; }
{ app_id = "pavucontrol"; }
];
"7" = [
{ app_id = "net.sourceforge.gscan2pdf"; }
{ app_id = "libreoffice-startcenter"; }
];
"8" = [
{ app_id = "darktable"; }
{ app_id = "org.inkscape.Inkscape"; }
{ class = "Blender"; }
{ class = "Gimp"; }
{ class = "krita"; }
];
};
window.border = 2;
gaps = {
inner = 6;
smartGaps = false;
};
floating = {
titlebar = true;
border = 1;
};
colors = {
focused = rec {
border = solarized.base1.hex;
background = solarized.base2.hex;
text = solarized.base1.hex;
indicator = solarized.cyan.hex;
childBorder = background;
};
focusedInactive = rec {
border = solarized.base0.hex;
background = solarized.base03.hex;
text = solarized.base0.hex;
indicator = solarized.cyan.hex;
childBorder = background;
};
unfocused = rec {
border = solarized.base0.hex;
background = solarized.base03.hex;
text = solarized.base0.hex;
indicator = solarized.cyan.hex;
childBorder = background;
};
urgent = rec {
border = solarized.base02.hex;
background = solarized.red.hex;
text = solarized.base02.hex;
indicator = solarized.cyan.hex;
childBorder = background;
};
};
fonts = {
names = [ "monospace" ];
style = "Regular";
size = 10.0;
};
};
extraConfig = ''
# Cursor
seat seat0 xcursor_theme Adwaita
'' + (
let
environmentVariables = lib.concatStringsSep " " [
"DBUS_SESSION_BUS_ADDRESS"
"DISPLAY"
"SWAYSOCK"
"WAYLAND_DISPLAY"
];
in
''
# From https://github.com/swaywm/sway/wiki#gtk-applications-take-20-seconds-to-start
exec systemctl --user import-environment ${environmentVariables} && \
hash dbus-update-activation-environment 2>/dev/null && \
dbus-update-activation-environment --systemd ${environmentVariables} && \
systemctl --user start sway-session.target
''
);
};
systemd.user.targets.sway-session = {
Unit = {
Description = "sway compositor session";
Documentation = [ "man:systemd.special(7)" ];
BindsTo = [ "graphical-session.target" ];
Wants = [ "graphical-session-pre.target" ];
After = [ "graphical-session-pre.target" ];
};
};
systemd.user.services.swayidle = {
Unit.PartOf = [ "sway-session.target" ];
Install.WantedBy = [ "sway-session.target" ];
Service = {
# swayidle requires sh and swaymsg to be in path
Environment = "PATH=${pkgs.bash}/bin:${config.wayland.windowManager.sway.package}/bin";
ExecStart = ''
${pkgs.swayidle}/bin/swayidle -w \
timeout 300 "${pkgs.swaylock}/bin/swaylock -f -i ${wallpaper}" \
timeout 300 '${pkgs.sway}/bin/swaymsg "output * dpms off"' \
resume '${pkgs.sway}/bin/swaymsg "output * dpms on"' \
before-sleep "${pkgs.swaylock}/bin/swaylock -f -i ${wallpaper}"
'';
Restart = "on-failure";
};
};
xdg.configFile."swaynag/config".text =
let
# adding it to the header doesnt work since the defaults overwrite it
commonConfig = /* ini */ ''
background=${lib.substring 1 6 solarized.base3.hex}
border-bottom=${lib.substring 1 6 solarized.base2.hex}
border=${lib.substring 1 6 solarized.base2.hex}
button-background=${lib.substring 1 6 solarized.base3.hex}
button-text=${lib.substring 1 6 solarized.base00.hex}
'';
in
/* ini */ ''
font=Monospace 12
[warning]
text=${lib.substring 1 6 solarized.yellow.hex}
${commonConfig}
[error]
text=${lib.substring 1 6 solarized.red.hex}
${commonConfig}
'';
})

View file

@ -0,0 +1,463 @@
{ config, lib, nixosConfig, pkgs, ... }:
let
watchUserUnitState = unit: started: stopped: pkgs.writeShellScript "watch-user-unit-${unit}-state" ''
${pkgs.systemd}/bin/journalctl --user -u ${unit} -t systemd -o cat -f \
| ${pkgs.gnugrep}/bin/grep --line-buffered -Eo '^(Started|Stopped)' \
| ${pkgs.jq}/bin/jq --unbuffered -Rc 'if . == "Started" then ${builtins.toJSON started} else ${builtins.toJSON stopped} end'
'';
toggleUserUnitState = unit: pkgs.writeShellScript "toggle-user-unit-${unit}-state" ''
if ${pkgs.systemd}/bin/systemctl --user show ${unit} | ${pkgs.gnugrep}/bin/grep -q ActiveState=active; then
${pkgs.systemd}/bin/systemctl --user stop ${unit}
else
${pkgs.systemd}/bin/systemctl --user start ${unit}
fi
'';
# nerd fonts are abusing arabic which breaks latin text
# context: https://github.com/Alexays/Waybar/issues/628
lrm = "&#8206;";
# for fine-grained control over spacing
thinsp = "&#8201;";
solarized = import ../solarized.nix;
in
{
# home-managers waybar module performs additional checks that are overly strict
xdg.configFile."waybar/config".text = lib.generators.toJSON { } {
layer = "top";
position = "top";
height = 24;
modules-center = [ ];
modules-left = [
"sway/workspaces"
"sway/mode"
];
modules-right = [
"tray"
"custom/screencast"
"custom/redshift"
"idle_inhibitor"
"backlight"
"mpd"
"pulseaudio"
"network"
"custom/vpn"
"memory"
"cpu"
"temperature"
"battery"
"clock"
"custom/calendar"
];
"sway/workspaces" = {
disable-scroll = true;
};
"sway/mode" = {
format = "{}";
};
tray = {
spacing = 5;
};
"custom/redshift" = {
exec = watchUserUnitState
"gammastep"
{ class = "active"; }
{ class = "inactive"; };
on-click = toggleUserUnitState "gammastep";
return-type = "json";
format = "";
tooltip = false;
};
idle_inhibitor = {
format = "{icon}";
format-icons = {
activated = " ";
deactivated = " ";
};
};
"custom/screencast" = {
exec = pkgs.writeScript "screencast-monitor" /* python */ ''
#!${pkgs.python3}/bin/python3
import subprocess
import sys
active_outputs = 0
with subprocess.Popen(
["${pkgs.coreutils}/bin/stdbuf", "-o0", "${nixosConfig.services.pipewire.package}/bin/pw-link", "-m", "-o", "xdg-desktop-portal-wlr"],
stdout=subprocess.PIPE,
text=True,
) as proc:
for line in proc.stdout:
action = line.split(" ")[0]
if action == "=" or action == "+":
active_outputs += 1
elif action == "-":
active_outputs -= 1
else:
print(f"Invalid action {action} (in line {line})", file=sys.stderr)
if active_outputs > 0:
print("${lrm} ")
else:
print()
sys.stdout.flush()
'';
format = "{}";
tooltip = false;
};
backlight = {
format = "{percent}% {icon}";
format-icons = [ " " " " " " " " " " " " " " ];
on-scroll-up = "${pkgs.brightnessctl}/bin/brightnessctl -q set +5%";
on-scroll-down = "${pkgs.brightnessctl}/bin/brightnessctl -q set 5%-";
};
mpd = {
server = config.services.mpd.network.listenAddress;
format = "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist} {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S}) ";
format-disconnected = "Disconnected ";
format-stopped = "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped ";
unknown-tag = "N/A";
interval = 2;
tooltip-format = "MPD (connected)";
tooltip-format-disconnected = "MPD (disconnected)";
on-scroll-up = "${pkgs.mpc_cli}/bin/mpc -q -h ${config.services.mpd.network.listenAddress} volume +2";
on-scroll-down = "${pkgs.mpc_cli}/bin/mpc -q -h ${config.services.mpd.network.listenAddress} volume -2";
title-len = 48;
artist-len = 24;
consume-icons = {
on = " ";
};
random-icons = {
off = " ";
on = " ";
};
repeat-icons = {
on = " ";
};
single-icons = {
on = " ";
};
state-icons = {
paused = "";
playing = "";
};
};
pulseaudio = {
format = "{volume}% {icon} {format_source}";
format-bluetooth = "{volume}% {icon} {format_source}";
format-bluetooth-muted = "${lrm}${lrm} {icon} {format_source}";
format-muted = "${lrm}${lrm} {format_source}";
format-source = "{volume}% ${thinsp}";
format-source-muted = "${thinsp}";
format-icons = {
car = " ";
default = [ "" "奔" "" ];
hands-free = " ";
headphone = " ";
headset = " ";
phone = " ";
portable = " ";
};
on-click-right = "${pkgs.pavucontrol}/bin/pavucontrol";
};
network = {
format-wifi = "{essid} ({signalStrength}%) ";
format-ethernet = "{ipaddr}/{cidr} ";
format-linked = "{ifname} (No IP) ";
format-disconnected = "Disconnected ";
format-alt = "{ifname}: {ipaddr}/{cidr}";
tooltip = false;
on-click-right = "${config.programs.alacritty.package}/bin/alacritty -e ${pkgs.networkmanager}/bin/nmtui";
};
"custom/vpn" = {
interval = 10;
exec = pkgs.writeShellScript "vpn-state" ''
${pkgs.iproute}/bin/ip -j link \
| ${pkgs.jq}/bin/jq --unbuffered --compact-output '
[[.[].ifname | select(. | startswith("mullvad"))][] | split("-")[1] + " ${thinsp}"] as $conns
| { text: ($conns[0] // ""), class: (if $conns | length > 0 then "connected" else "disconnected" end) }'
'';
return-type = "json";
format = "{}";
tooltip = false;
};
memory = {
interval = 2;
format = "{:2}% ";
};
cpu = {
interval = 2;
format = "{usage:2}% ";
tooltip = false;
};
temperature = {
critical-threshold = 80;
format = "{temperatureC}°C {icon}";
format-icons = [ "" "" "" "" "" ];
} // (lib.optionalAttrs (nixosConfig.networking.hostName == "mayushii") {
hwmon-path = "/sys/class/hwmon/hwmon3/temp1_input";
});
battery = {
interval = 5;
format = "{capacity}% {icon}";
format-charging = "{capacity}% ";
format-plugged = "{capacity}% ${lrm}";
format-alt = "{time} {icon}";
format-icons = [ "" "" "" "" "" "" "" "" "" "" "" ];
states = {
critical = 15;
good = 95;
warning = 30;
};
};
clock = {
format = "{:%H:%M %Z}";
format-alt = "{:%Y-%m-%d (%a)}";
tooltip-format = "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>";
};
"custom/calendar" = {
interval = 300;
exec = pkgs.writeScript "calendar" /* python */ ''
#!${pkgs.python3}/bin/python3
import json
import subprocess
def khal(args):
completed = subprocess.run(["${pkgs.khal}/bin/khal"] + args, capture_output=True)
assert completed.returncode == 0
return completed.stdout.decode("utf-8")
events_today = khal(["list", "today", "today", "-df", "", "-f", "{title}"]).rstrip().split("\n")
events_2d = khal(["list", "today", "tomorrow", "-df", "<b>{name}, {date}</b>"]).rstrip()
if len(events_today) == 1 and events_today[0] == "No events":
events_today = []
if len(events_today) == 0:
text = " "
else:
text = f"{len(events_today)} "
print(
json.dumps(
{
"class": "active" if len(events_today) > 0 else "",
"text": text,
"tooltip": events_2d,
}
)
)
'';
return-type = "json";
format = "{}";
};
};
xdg.configFile."waybar/style.css".text = ''
* {
border-radius: 0;
border: none;
font-family: "Iosevka Nerd Font";
font-size: 14px;
min-height: 0;
transition-property: none;
}
window#waybar {
background-color: ${solarized.base03.hex};
color: ${solarized.base0.hex};
}
#workspaces button {
padding: 0 5px;
background-color: ${solarized.base03.hex};
color: inherit;
border-bottom: 2px solid transparent;
}
#workspaces button:hover {
background: ${solarized.base02.hex};
box-shadow: inherit;
text-shadow: inherit;
}
#workspaces button.focused {
border-bottom: 2px solid ${solarized.green.hex};
}
#workspaces button.urgent {
background-color: ${solarized.red.hex};
}
#mode {
background-color: ${solarized.base02.hex};
font-style: italic;
}
/* all modules on the right */
#waybar > box > box:nth-child(3) > widget > label {
padding: 0 10px;
}
#battery.charging {
color: ${solarized.base02.hex};
background-color: ${solarized.green.hex};
}
@keyframes blink {
to {
background-color: ${solarized.base3.hex};
color: ${solarized.base00.hex};
}
}
#battery.critical:not(.charging),
#temperature.critical {
background-color: ${solarized.red.hex};
animation-name: blink;
animation-duration: 0.5s;
/* FIXME use nearest neighbor interpolation if possible */
animation-timing-function: cubic-bezier(1, 0, 0, 1);
animation-iteration-count: infinite;
animation-direction: alternate;
}
#cpu {
background-color: ${solarized.cyan.hex};
color: ${solarized.base02.hex}
}
#memory {
background-color: ${solarized.yellow.hex};
color: ${solarized.base02.hex}
}
#backlight {
background-color: ${solarized.base3.hex};
color: ${solarized.base00.hex};
}
#network {
background-color: ${solarized.violet.hex};
color: ${solarized.base02.hex}
}
#custom-vpn {
background-color: ${solarized.blue.hex};
color: ${solarized.base02.hex}
}
#network.disconnected {
background-color: ${solarized.red.hex};
}
#pulseaudio {
background-color: ${solarized.base3.hex};
color: ${solarized.base00.hex};
}
#pulseaudio.muted {
background-color: ${solarized.base03.hex};
color: ${solarized.base0.hex};
}
#temperature {
background-color: ${solarized.magenta.hex};
color: ${solarized.base02.hex};
}
#idle_inhibitor.activated {
background-color: ${solarized.base3.hex};
color: ${solarized.base03.hex};
}
#mpd {
background-color: ${solarized.green.hex};
color: ${solarized.base02.hex};
}
#mpd.disconnected {
background-color: ${solarized.red.hex};
}
#mpd.stopped {
background-color: ${solarized.orange.hex};
}
#mpd.paused {
background-color: ${solarized.yellow.hex};
}
#custom-redshift {
color: ${solarized.base02.hex};
}
#custom-redshift.active {
background-color: ${solarized.red.hex};
}
#custom-redshift.inactive {
background-color: ${solarized.blue.hex};
}
#tray {
padding: 0 5px;
}
#custom-notification_inhibitor.active {
background-color: ${solarized.base3.hex};
color: ${solarized.base03.hex};
}
#custom-screencast {
background-color: ${solarized.red.hex};
color: ${solarized.base03.hex};
animation-name: blink;
animation-duration: 0.5s;
animation-timing-function: cubic-bezier(1, 0, 0, 1);
animation-iteration-count: infinite;
animation-direction: alternate;
}
#custom-calendar.active {
background-color: ${solarized.base3.hex};
color: ${solarized.base00.hex};
}
'';
systemd.user.services.waybar = {
Unit = {
Description = "Highly customizable Wayland bar for Sway and Wlroots based compositors.";
Documentation = "https://github.com/Alexays/Waybar/wiki/";
PartOf = [ "sway-session.target" ];
};
Install.WantedBy = [ "sway-session.target" ];
Service = {
# ensure sway is already started, otherwise workspaces will not work
ExecStartPre = "${config.wayland.windowManager.sway.package}/bin/swaymsg";
ExecStart = "${pkgs.waybar}/bin/waybar";
ExecReload = "${pkgs.utillinux}/bin/kill -SIGUSR2 $MAINPID";
Restart = "on-failure";
RestartSec = "1s";
};
};
# TODO: remove when https://github.com/nix-community/home-manager/issues/2064
# is resolved
systemd.user.targets.tray = {
Unit = {
Description = "Home Manager System Tray";
Requires = [ "graphical-session-pre.target" ];
};
};
}

View file

@ -0,0 +1,64 @@
{ nixosConfig, config, lib, pkgs, ... }:
let
solarized = import ../solarized.nix;
in
{
xdg.configFile."wofi/style.css".text =
let
# adding it to the header doesnt work since the defaults overwrite it
commonConfig = /* ini */ ''
background=${lib.substring 1 6 solarized.base3}
border-bottom=${lib.substring 1 6 solarized.base2}
border=${lib.substring 1 6 solarized.base2}
button-background=${lib.substring 1 6 solarized.base3}
button-text=${lib.substring 1 6 solarized.base00}
'';
in
/* css */ ''
window {
margin: 0px;
border: 3px solid ${solarized.base02.hex};
border-radius: 8px;
background-color: rgba(${solarized.base03.rgb},0.8);
}
#input {
margin: 5px;
border: none;
color: ${solarized.base0.hex};
background-color: rgba(${solarized.base02.rgb},0.8);
}
#inner-box {
margin: 5px;
border: none;
background: none;
}
#outer-box {
margin: 5px;
border: none;
background: none;
}
#scroll {
margin: 0px;
border: none;
}
#text {
margin: 5px;
border: none;
color: ${solarized.base0.hex};
}
#entry:selected {
background-color: rgba(${solarized.base02.rgb},0.8);
}
#entry:selected #text{
color: ${solarized.green.hex};
}
'';
}

View file

@ -0,0 +1,21 @@
{ lib, ... }:
{
options.myConfig = {
git.user = {
name = lib.mkOption {
type = lib.types.str;
description = "name to use for git commits";
};
email = lib.mkOption {
type = lib.types.str;
description = "email to use for git commits";
};
};
terminalEmulator = lib.mkOption {
type = lib.types.str;
description = "default Terminal emulator name";
default = "alacritty";
};
};
}

View file

@ -0,0 +1,87 @@
{ config, pkgs, ... }:
{
imports = [
./default.nix
];
myConfig.git.user = {
name = "Jakob Lechner";
email = "jal@tradebyte.biz";
};
users.users.jal = {
isNormalUser = true;
extraGroups = [
"dialout"
"docker"
"libvirtd"
"lp"
"networkmanager"
"scanner"
"video"
"wheel"
"wireshark"
]; # Enable sudo for the user.
shell = pkgs.fish;
};
home-manager = {
useUserPackages = true;
useGlobalPkgs = true;
users.jal = { lib, pkgs, ... }: {
imports = [ ../modules ];
config = {
home.stateVersion = config.system.stateVersion;
home.packages = with pkgs; [
awscli2
mycli
timetrap
vagrant
# common
ansible
asciinema
bat
cached-nix-shell
direnv
dnsutils
docker-compose
envsubst
evince
exa
gcr # required for pinentry-gnome
geeqie
gitAndTools.diff-so-fancy
gnupg
khal
lsof
mpv
ncdu
networkmanagerapplet
nmap
pass-wayland
pcmanfm
pinentry-gnome
psutils
pwgen
python38
python38Packages.pylint
python38Packages.virtualenv
qtpass
ripgrep
screen
speedtest-cli
sway-contrib.grimshot
tig
vdirsyncer
vlc
wget
whois
xdg_utils
];
};
};
};
}

109
home-manager/users/jalr.nix Normal file
View file

@ -0,0 +1,109 @@
{ config, pkgs, ... }:
{
imports = [
./default.nix
];
myConfig.git.user = {
name = "jalr";
email = "mail@jalr.de";
};
users.users.jalr = {
isNormalUser = true;
extraGroups = [
"dialout"
"docker"
"libvirtd"
"lp"
"networkmanager"
"scanner"
"video"
"wheel"
"wireshark"
]; # Enable sudo for the user.
shell = pkgs.fish;
};
home-manager = {
useUserPackages = true;
useGlobalPkgs = true;
users.jalr = { lib, pkgs, ... }: {
imports = [ ../modules ];
config = {
home.stateVersion = config.system.stateVersion;
home.packages = with pkgs; [
audacity
axoloti
claws-mail
cutecom
ghostscript
gimp
inkscape
jameica
kicad
krita
mumble
newsboat
openscad
pdftk
platformio
printrun
ptouch-print
qrencode
qtox
sshfs
streamlink
tdesktop
tmate
tor-browser-bundle-bin
wdisplays
yt-dlp
# common
ansible
asciinema
bat
cached-nix-shell
direnv
dnsutils
docker-compose
envsubst
evince
exa
gcr # required for pinentry-gnome
geeqie
gitAndTools.diff-so-fancy
gnupg
khal
lsof
mpv
ncdu
networkmanagerapplet
nmap
pass-wayland
pcmanfm
pinentry-gnome
psutils
pwgen
python38
python38Packages.pylint
python38Packages.virtualenv
qtpass
ripgrep
screen
speedtest-cli
sway-contrib.grimshot
tig
vdirsyncer
vlc
wget
whois
xdg_utils
];
};
};
};
}

View file

@ -97,7 +97,9 @@
myConfig = {
gui.enable = true;
sdr.enable = true;
autologin.enable = true;
autologin.username = "jalr";
};
# This value determines the NixOS release from which the default

View file

@ -27,7 +27,7 @@
};
extraHosts = ''
#10.10.10.10 example.com
#10.158.228.70 support.demo.core.tradebyte.com
#10.158.228.70 support.demo.core.tradebyte.com
#10.158.228.28 demo.core.tradebyte.com
#10.158.227.210 supporttest.tradebyte.com
#10.158.227.132 test.tradebyte.com
@ -120,6 +120,7 @@
myConfig = {
gui.enable = true;
sdr.enable = false;
autologin.enable = true;
autologin.username = "jal";
tradebyte.enable = true;

View file

@ -86,7 +86,9 @@
myConfig = {
gui.enable = true;
sdr.enable = true;
autologin.enable = true;
autologin.username = "jalr";
};
networking.wg-quick.interfaces.wgkalle = {

View file

@ -3,8 +3,9 @@
{
console.font = "Lat2-Terminus16";
fonts.fonts = with pkgs; lib.mkIf config.myConfig.gui.enable [
(nerdfonts.override { fonts = [ "Iosevka" ]; })
font-awesome
powerline-fonts
roboto
font-awesome
];
}

View file

@ -5,16 +5,11 @@ lib.mkIf config.myConfig.gui.enable {
enable = true;
# FIXME: move to home manager
extraPackages = with pkgs; [
alacritty
grim
mako
redshift-wlr
slurp
swayidle
swaylock
waybar
wl-clipboard
wofi
xwayland
];
extraSessionCommands = ''

3
pkgs/mute-indicator/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
.pio
.pioenvs
.piolibdeps

View file

@ -0,0 +1,8 @@
I recommend setting up a udev rule, so that the python script knows which serial port it should connect to:
```bash
echo 'SUBSYSTEM=="tty", ATTRS{idVendor}=="1eaf", ATTRS{idProduct}=="6d75", SYMLINK+="mute-indicator"' | sudo tee /etc/udev/rules.d/99-mute-indicator.rules
```
### Google Meet
[Greasemonkey user script to automatically unmute](https://gist.github.com/jalr/ba132ed4a7133cf4fdbc98c97bf1a9e4)

View file

@ -0,0 +1,21 @@
{ python38Packages }:
python38Packages.buildPythonApplication rec {
pname = "mute-indicator";
version = "0.0.1";
src = ./.;
propagatedBuildInputs = with python38Packages; [
python
pulsectl
pyserial
];
# installPhase = ''
# echo $src
# mkdir -p $out/bin
# cp pulseaudio-mute-indicator.py $out/bin/pulseaudio-mute-indicator
# chmod +x $out/bin/pulseaudio-mute-indicator
# '';
}

View file

@ -0,0 +1,24 @@
[env:bluepill]
framework = arduino
platform = ststm32
board = genericSTM32F103C8
board_build.mcu = stm32f103c8t6
board_build.f_cpu = 72000000L
upload_protocol = dfu
upload_port = anything
lib_deps =
Adafruit NeoPixel
build_flags =
-D USBCON
-D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC
-D USBD_VID=0x1EAF
-D USBD_PID=0x6d75
-D USB_MANUFACTURER_STRING="\"github.com/jalr\""
-D USB_PRODUCT_STRING="\"mute-indicator\""
# -D HAL_PCD_MODULE_ENABLED
# -D USB_PRODUCT=bluepill

View file

@ -0,0 +1 @@

View file

@ -0,0 +1,28 @@
import pulsectl
import serial
def run():
with pulsectl.Pulse("event-printer") as pulse:
def print_events(ev):
with pulsectl.Pulse("event-source-info") as pulse2:
source = pulse2.source_info(ev.index)
if source.name in [
"alsa_input.usb-BEHRINGER_UMC202HD_192k-00.analog-stereo",
"alsa_input.usb-BEHRINGER_UMC202HD_192k-00.analog-stereo-input",
]:
muted = bool(source.mute)
with serial.Serial(port="/dev/mute-indicator", baudrate=115200) as ser:
if muted:
ser.write("L0:32,0,0\n".encode())
ser.write("L1:32,0,0\n".encode())
ser.write("S\n".encode())
else:
ser.write("L0:0,32,0\n".encode())
ser.write("L1:0,32,0\n".encode())
ser.write("S\n".encode())
pulse.event_mask_set("source")
pulse.event_callback_set(print_events)
pulse.event_listen(timeout=0)

View file

@ -0,0 +1,20 @@
from setuptools import setup, find_packages
setup(
name="pulseaudio_mute_indicator",
version="0.0.1",
url="https://github.com/jalr/mute-indicator.git",
author="jalr",
author_email="mail@jalr.de",
description="Microphone mute LED indicator",
packages=find_packages(),
install_requires=[
"pulsectl",
"pyserial",
],
entry_points={
"console_scripts": [
"service = pulseaudio_mute_indicator.service:run",
],
},
)

View file

@ -0,0 +1,60 @@
#include <Arduino.h>
#include <Adafruit_NeoPixel.h>
#define NUM_LEDS 2
#define DATA_PIN PB8
Adafruit_NeoPixel pixels(NUM_LEDS, DATA_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(115200);
delay(500);
pixels.begin();
Serial.println("Serial Neopixel interface ready.");
pixels.clear();
}
void loop() {
if (Serial.available() > 0) {
Serial.println("Received command");
char command = Serial.read();
switch(command) {
case 'L':
{
Serial.println("got L");
String ledStr = Serial.readStringUntil(':');
if (ledStr.length() > 0) {
long led = ledStr.toInt();
Serial.print("got led:");
Serial.println(led);
long red = Serial.readStringUntil(',').toInt();
Serial.print("got red:");
Serial.println(red);
long green = Serial.readStringUntil(',').toInt();
Serial.print("got green:");
Serial.println(green);
long blue = Serial.readStringUntil('\n').toInt();
Serial.print("got blue:");
Serial.println(blue);
pixels.setPixelColor(led, pixels.Color(red, green, blue));
Serial.println("pixel set.");
}
break;
}
case 'S':
{
Serial.readStringUntil('\n');
pixels.show();
Serial.println("pixel shown.");
break;
}
case 'C':
{
Serial.readStringUntil('\n');
pixels.clear();
Serial.println("pixels cleared.");
break;
}
}
}
}