Complete migration of home-manager modules to roles
Migrate all remaining home-manager modules from home/modules/ to home/roles/ to establish a unified role-based configuration pattern. This completes the migration started in Phase 1. Changes: - Phase 1-3: Migrated tmux, plasma-manager, kubectl, and emacs to roles - Phase 4: Migrated aerospace with custom options under home.roles.aerospace.* - Phase 5: Migrated i3+sway with shared config and override options - Phase 6: Removed empty home/modules/ directory All home configs now import only ./roles with role-based enable options. Updated flake.nix machine-specific overrides to use new namespaces. Verified with nix flake check - all configurations build successfully.
This commit is contained in:
200
home/roles/aerospace/default.nix
Normal file
200
home/roles/aerospace/default.nix
Normal file
@@ -0,0 +1,200 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.home.roles.aerospace;
|
||||
in
|
||||
{
|
||||
options.home.roles.aerospace = {
|
||||
enable = mkEnableOption "AeroSpace tiling window manager for macOS";
|
||||
|
||||
leader = mkOption {
|
||||
type = types.str;
|
||||
default = "cmd";
|
||||
description = "Leader key for aerospace shortcuts (e.g., 'cmd', 'ctrl', 'alt')";
|
||||
example = "ctrl";
|
||||
};
|
||||
|
||||
launchd.enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether to enable launchd agent for auto-starting aerospace";
|
||||
};
|
||||
|
||||
userSettings = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
description = ''
|
||||
Additional aerospace configuration settings to merge with defaults.
|
||||
Use this to override or extend the default configuration on a per-machine basis.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
{
|
||||
mode.main.binding."''${leader}-custom" = "custom-command";
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
autoraise = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether to enable autoraise (auto-focus window on hover)";
|
||||
};
|
||||
|
||||
pollMillis = mkOption {
|
||||
type = types.int;
|
||||
default = 50;
|
||||
description = "Polling interval in milliseconds";
|
||||
};
|
||||
|
||||
delay = mkOption {
|
||||
type = types.int;
|
||||
default = 2;
|
||||
description = "Delay before raising window";
|
||||
};
|
||||
|
||||
focusDelay = mkOption {
|
||||
type = types.int;
|
||||
default = 2;
|
||||
description = "Delay before focusing window";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# Only apply on Darwin systems
|
||||
assertions = [
|
||||
{
|
||||
assertion = pkgs.stdenv.isDarwin;
|
||||
message = "Aerospace role is only supported on macOS (Darwin) systems";
|
||||
}
|
||||
];
|
||||
|
||||
# Install aerospace package and autoraise if enabled
|
||||
home.packages = [ pkgs.aerospace ]
|
||||
++ optionals cfg.autoraise.enable [ pkgs.autoraise ];
|
||||
|
||||
# Configure aerospace with user settings
|
||||
programs.aerospace.userSettings = mkMerge [
|
||||
# Default configuration with leader key substitution
|
||||
{
|
||||
mode.main.binding = {
|
||||
"${cfg.leader}-slash" = "layout tiles horizontal vertical";
|
||||
"${cfg.leader}-comma" = "layout accordion horizontal vertical";
|
||||
"${cfg.leader}-shift-q" = "close";
|
||||
"${cfg.leader}-shift-f" = "fullscreen";
|
||||
"${cfg.leader}-h" = "focus left";
|
||||
"${cfg.leader}-j" = "focus down";
|
||||
"${cfg.leader}-k" = "focus up";
|
||||
"${cfg.leader}-l" = "focus right";
|
||||
"${cfg.leader}-shift-h" = "move left";
|
||||
"${cfg.leader}-shift-j" = "move down";
|
||||
"${cfg.leader}-shift-k" = "move up";
|
||||
"${cfg.leader}-shift-l" = "move right";
|
||||
"${cfg.leader}-minus" = "resize smart -50";
|
||||
"${cfg.leader}-equal" = "resize smart +50";
|
||||
"${cfg.leader}-1" = "workspace 1";
|
||||
"${cfg.leader}-2" = "workspace 2";
|
||||
"${cfg.leader}-3" = "workspace 3";
|
||||
"${cfg.leader}-4" = "workspace 4";
|
||||
"${cfg.leader}-5" = "workspace 5";
|
||||
"${cfg.leader}-6" = "workspace 6";
|
||||
"${cfg.leader}-7" = "workspace 7";
|
||||
"${cfg.leader}-8" = "workspace 8";
|
||||
"${cfg.leader}-9" = "workspace 9";
|
||||
"${cfg.leader}-0" = "workspace 10";
|
||||
"${cfg.leader}-shift-1" = "move-node-to-workspace 1";
|
||||
"${cfg.leader}-shift-2" = "move-node-to-workspace 2";
|
||||
"${cfg.leader}-shift-3" = "move-node-to-workspace 3";
|
||||
"${cfg.leader}-shift-4" = "move-node-to-workspace 4";
|
||||
"${cfg.leader}-shift-5" = "move-node-to-workspace 5";
|
||||
"${cfg.leader}-shift-6" = "move-node-to-workspace 6";
|
||||
"${cfg.leader}-shift-7" = "move-node-to-workspace 7";
|
||||
"${cfg.leader}-shift-8" = "move-node-to-workspace 8";
|
||||
"${cfg.leader}-shift-9" = "move-node-to-workspace 9";
|
||||
"${cfg.leader}-shift-0" = "move-node-to-workspace 10";
|
||||
"${cfg.leader}-tab" = "workspace-back-and-forth";
|
||||
"${cfg.leader}-shift-tab" = "move-workspace-to-monitor --wrap-around next";
|
||||
|
||||
"${cfg.leader}-enter" = ''
|
||||
exec-and-forget osascript <<'APPLESCRIPT'
|
||||
tell application "Ghostty"
|
||||
activate
|
||||
tell application "System Events"
|
||||
keystroke "n" using {command down}
|
||||
end tell
|
||||
end tell
|
||||
APPLESCRIPT
|
||||
'';
|
||||
|
||||
"${cfg.leader}-shift-enter" = ''
|
||||
exec-and-forget osascript <<'APPLESCRIPT'
|
||||
tell application "Google Chrome"
|
||||
set newWindow to make new window
|
||||
activate
|
||||
tell newWindow to set index to 1
|
||||
end tell
|
||||
APPLESCRIPT
|
||||
'';
|
||||
|
||||
"${cfg.leader}-shift-e" = "exec-and-forget zsh --login -c \"emacsclient -c -n\"";
|
||||
|
||||
# Service mode: Deliberate aerospace window management
|
||||
"${cfg.leader}-i" = "mode service";
|
||||
|
||||
# Passthrough mode: Temporarily disable aerospace to use macOS shortcuts
|
||||
"${cfg.leader}-p" = "mode passthrough";
|
||||
};
|
||||
|
||||
# Service mode: For deliberate aerospace window management operations
|
||||
mode.service.binding = {
|
||||
esc = ["reload-config" "mode main"];
|
||||
r = ["flatten-workspace-tree" "mode main"]; # reset layout
|
||||
f = ["layout floating tiling" "mode main"]; # Toggle between floating and tiling layout
|
||||
backspace = ["close-all-windows-but-current" "mode main"];
|
||||
|
||||
"${cfg.leader}-shift-h" = ["join-with left" "mode main"];
|
||||
"${cfg.leader}-shift-j" = ["join-with down" "mode main"];
|
||||
"${cfg.leader}-shift-k" = ["join-with up" "mode main"];
|
||||
"${cfg.leader}-shift-l" = ["join-with right" "mode main"];
|
||||
};
|
||||
|
||||
# Passthrough mode: All shortcuts pass through to macOS
|
||||
mode.passthrough.binding = {
|
||||
esc = "mode main";
|
||||
"${cfg.leader}-p" = "mode main";
|
||||
};
|
||||
}
|
||||
cfg.userSettings
|
||||
];
|
||||
|
||||
# Launchd agent for auto-starting aerospace
|
||||
launchd.agents.aerospace = mkIf cfg.launchd.enable {
|
||||
enable = true;
|
||||
config = {
|
||||
Program = "${pkgs.aerospace}/Applications/AeroSpace.app/Contents/MacOS/AeroSpace";
|
||||
RunAtLoad = true;
|
||||
KeepAlive = true;
|
||||
StandardOutPath = "/tmp/aerospace.log";
|
||||
StandardErrorPath = "/tmp/aerospace.err.log";
|
||||
};
|
||||
};
|
||||
|
||||
# Launchd agent for autoraise
|
||||
launchd.agents.autoraise = mkIf cfg.autoraise.enable {
|
||||
enable = true;
|
||||
config = {
|
||||
ProgramArguments = [
|
||||
"${pkgs.autoraise}/bin/AutoRaise"
|
||||
"-pollMillis" (toString cfg.autoraise.pollMillis)
|
||||
"-delay" (toString cfg.autoraise.delay)
|
||||
"-focusDelay" (toString cfg.autoraise.focusDelay)
|
||||
];
|
||||
RunAtLoad = true;
|
||||
KeepAlive = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -11,5 +11,10 @@
|
||||
./media
|
||||
./office
|
||||
./sync
|
||||
./tmux
|
||||
./plasma-manager
|
||||
./emacs
|
||||
./aerospace
|
||||
./i3+sway
|
||||
];
|
||||
}
|
||||
|
||||
77
home/roles/emacs/default.nix
Normal file
77
home/roles/emacs/default.nix
Normal file
@@ -0,0 +1,77 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.home.roles.emacs;
|
||||
|
||||
doomEmacs = pkgs.fetchFromGitHub {
|
||||
owner = "doomemacs";
|
||||
repo = "doomemacs";
|
||||
rev = "8f55404781edacf66fa330205533b002de3fb5ee";
|
||||
sha256 = "sha256-vHwgENjip2+AFzs4oZfnKEAJKwf5Zid7fakImvxxQUw=";
|
||||
};
|
||||
|
||||
# Shared emacs packages
|
||||
emacsPackages = epkgs: [
|
||||
epkgs.vterm
|
||||
epkgs.treesit-grammars.with-all-grammars
|
||||
];
|
||||
|
||||
# Default emacs configuration with vterm support
|
||||
defaultEmacsPackage =
|
||||
if pkgs.stdenv.isDarwin
|
||||
then pkgs.emacs-macport.pkgs.withPackages emacsPackages
|
||||
else pkgs.emacs.pkgs.withPackages emacsPackages;
|
||||
in
|
||||
{
|
||||
options.home.roles.emacs = {
|
||||
enable = mkEnableOption "Doom Emacs with vterm and tree-sitter support";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages = [
|
||||
pkgs.emacs-all-the-icons-fonts
|
||||
pkgs.fira-code
|
||||
pkgs.fontconfig
|
||||
pkgs.graphviz
|
||||
pkgs.isort
|
||||
pkgs.nerd-fonts.fira-code
|
||||
pkgs.nerd-fonts.droid-sans-mono
|
||||
pkgs.nil # nix lsp language server
|
||||
pkgs.nixfmt-rfc-style
|
||||
(pkgs.ripgrep.override {withPCRE2 = true;})
|
||||
pkgs.pipenv
|
||||
pkgs.poetry
|
||||
pkgs.python3
|
||||
];
|
||||
|
||||
programs.emacs = {
|
||||
enable = true;
|
||||
package = defaultEmacsPackage;
|
||||
};
|
||||
|
||||
fonts.fontconfig.enable = true;
|
||||
|
||||
# Mount emacs and tree-sitter grammars from nix store
|
||||
home.file = {
|
||||
"${config.xdg.configHome}/emacs".source = doomEmacs;
|
||||
};
|
||||
|
||||
home.sessionPath = [
|
||||
"${config.xdg.configHome}/emacs/bin"
|
||||
];
|
||||
|
||||
home.sessionVariables = {
|
||||
DOOMDIR = "${config.xdg.configHome}/doom";
|
||||
DOOMLOCALDIR = "${config.xdg.dataHome}/doom";
|
||||
};
|
||||
|
||||
# TODO: Use mkOutOfStoreSymlink instead?
|
||||
home.activation.doomConfig = lib.hm.dag.entryAfter ["writeBoundary"] ''
|
||||
# Always remove and recreate the symlink to ensure it points to the source directory
|
||||
rm -rf "${config.xdg.configHome}/doom"
|
||||
ln -sf "${config.home.homeDirectory}/nixos-configs/home/roles/emacs/doom" "${config.xdg.configHome}/doom"
|
||||
'';
|
||||
};
|
||||
}
|
||||
192
home/roles/emacs/doom/config.el
Normal file
192
home/roles/emacs/doom/config.el
Normal file
@@ -0,0 +1,192 @@
|
||||
;;; $DOOMDIR/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; Place your private configuration here! Remember, you do not need to run 'doom
|
||||
;; sync' after modifying this file!
|
||||
|
||||
|
||||
;; Some functionality uses this to identify you, e.g. GPG configuration, email
|
||||
;; clients, file templates and snippets. It is optional.
|
||||
;; (setq user-full-name "John Doe"
|
||||
;; user-mail-address "john@doe.com")
|
||||
|
||||
;; Doom exposes five (optional) variables for controlling fonts in Doom:
|
||||
;;
|
||||
;; - `doom-font' -- the primary font to use
|
||||
;; - `doom-variable-pitch-font' -- a non-monospace font (where applicable)
|
||||
;; - `doom-big-font' -- used for `doom-big-font-mode'; use this for
|
||||
;; presentations or streaming.
|
||||
;; - `doom-symbol-font' -- for symbols
|
||||
;; - `doom-serif-font' -- for the `fixed-pitch-serif' face
|
||||
;;
|
||||
;; See 'C-h v doom-font' for documentation and more examples of what they
|
||||
;; accept. For example:
|
||||
;;
|
||||
;;(setq doom-font (font-spec :family "Fira Code" :size 12 :weight 'semi-light)
|
||||
;; doom-variable-pitch-font (font-spec :family "Fira Sans" :size 13))
|
||||
;;
|
||||
;; If you or Emacs can't find your font, use 'M-x describe-font' to look them
|
||||
;; up, `M-x eval-region' to execute elisp code, and 'M-x doom/reload-font' to
|
||||
;; refresh your font settings. If Emacs still can't find your font, it likely
|
||||
;; wasn't installed correctly. Font issues are rarely Doom issues!
|
||||
(setq doom-font (font-spec :family "Fira Code"))
|
||||
|
||||
;; Auto-install nerd-icons fonts if they're missing
|
||||
(defun my/ensure-nerd-icons-fonts ()
|
||||
"Check if nerd-icons fonts are installed and install them if missing."
|
||||
(when (display-graphic-p)
|
||||
(unless (find-font (font-spec :name "Symbols Nerd Font Mono"))
|
||||
(when (fboundp 'nerd-icons-install-fonts)
|
||||
(nerd-icons-install-fonts t)))))
|
||||
|
||||
(add-hook 'doom-init-ui-hook #'my/ensure-nerd-icons-fonts)
|
||||
|
||||
;; There are two ways to load a theme. Both assume the theme is installed and
|
||||
;; available. You can either set `doom-theme' or manually load a theme with the
|
||||
;; `load-theme' function. This is the default:
|
||||
(setq doom-theme 'doom-tokyo-night)
|
||||
|
||||
;; This determines the style of line numbers in effect. If set to `nil', line
|
||||
;; numbers are disabled. For relative line numbers, set this to `relative'.
|
||||
(setq display-line-numbers-type t)
|
||||
|
||||
;; If you use `org' and don't want your org files in the default location below,
|
||||
;; change `org-directory'. It must be set before org loads!
|
||||
(setq org-directory "~/org/")
|
||||
(after! org
|
||||
(setq org-agenda-span 'week
|
||||
org-agenda-start-with-log-mode t
|
||||
my-agenda-dirs '("projects" "roam")
|
||||
org-agenda-files (cons org-directory (mapcan (lambda (x) (directory-files-recursively
|
||||
(expand-file-name x org-directory)
|
||||
"\.org$"))
|
||||
my-agenda-dirs))
|
||||
org-log-done 'time
|
||||
org-agenda-custom-commands '(("n" "Agenda"
|
||||
((agenda "")
|
||||
(tags-todo "-someday-recurring")))
|
||||
("s" "Someday Items"
|
||||
((tags-todo "+someday"))))
|
||||
org-todo-keywords '((sequence "TODO(t)" "IN-PROGRESS(p)" "WAIT(w)" "|" "DONE(d)" "KILL(k)"))
|
||||
org-journal-file-type 'weekly
|
||||
org-journal-file-format "%Y-%m-%d.org"
|
||||
org-capture-templates
|
||||
'(("t" "Todo" entry (file+headline "~/org/todo.org" "Inbox")
|
||||
"* TODO %? \n %i \n%a" :prepend t))))
|
||||
|
||||
(map! :after org-agenda
|
||||
:map org-agenda-mode-map
|
||||
:localleader
|
||||
(:prefix ("v" . "view")
|
||||
"d" #'org-agenda-day-view
|
||||
"w" #'org-agenda-week-view))
|
||||
|
||||
;; (use-package! org-caldav
|
||||
;; :defer t
|
||||
;; :config
|
||||
;; (setq org-caldav-url "https://nextcloud.johnogle.info/remote.php/dav/calendars/johno"
|
||||
;; org-caldav-calendar-id "personal"
|
||||
;; org-icalendar-timezone "America/Los_Angeles"
|
||||
;; org-caldav-inbox "~/org/calendar.org"
|
||||
;; org-caldav-files nil
|
||||
;; org-caldav-sync-direction 'cal->org))
|
||||
|
||||
(defun my/get-rbw-password (alias)
|
||||
"Return the password for ALIAS via rbw, unlocking the vault only if needed."
|
||||
(let* ((cmd (format "rbw get %s 2>&1" alias))
|
||||
(output (shell-command-to-string cmd)))
|
||||
(string-trim output)))
|
||||
|
||||
(after! gptel
|
||||
:config
|
||||
(setq! gptel-api-key (my/get-rbw-password "openai-api-key-chatgpt-el")
|
||||
gptel-default-mode 'org-mode
|
||||
gptel-use-tools t
|
||||
gptel-confirm-tool-calls 'always
|
||||
gptel-include-reasoning 'ignore
|
||||
gptel-model "qwen3:30b")
|
||||
|
||||
;; Set default backend to be Ollama-Local
|
||||
(setq! gptel-backend
|
||||
(gptel-make-ollama "Ollama-Local"
|
||||
:host "localhost:11434"
|
||||
:stream t
|
||||
:models '(deepseek-r1 deepseek-r1-fullctx qwen3:30b qwen3:4b llama3.1 qwen2.5-coder mistral-nemo gpt-oss)))
|
||||
|
||||
;; Define custom tools
|
||||
(gptel-make-tool
|
||||
:name "run_shell_command"
|
||||
:description "Execute shell commands and return output. Use this to run system commands, check file contents, or perform system operations."
|
||||
:function (lambda (command)
|
||||
(condition-case err
|
||||
(shell-command-to-string command)
|
||||
(error (format "Error running command: %s" (error-message-string err)))))
|
||||
:args (list '(:name "command" :type "string" :description "Shell command to execute")))
|
||||
|
||||
(gptel-make-tool
|
||||
:name "read_file"
|
||||
:description "Read the contents of a file and return as text"
|
||||
:function (lambda (filepath)
|
||||
(condition-case err
|
||||
(with-temp-buffer
|
||||
(insert-file-contents (expand-file-name filepath))
|
||||
(buffer-string))
|
||||
(error (format "Error reading file %s: %s" filepath (error-message-string err)))))
|
||||
:args (list '(:name "filepath" :type "string" :description "Path to the file to read")))
|
||||
|
||||
(gptel-make-tool
|
||||
:name "list_directory"
|
||||
:description "List contents of a directory"
|
||||
:function (lambda (dirpath)
|
||||
(condition-case err
|
||||
(mapconcat 'identity
|
||||
(directory-files (expand-file-name dirpath) nil "^[^.]")
|
||||
"\n")
|
||||
(error (format "Error listing directory %s: %s" dirpath (error-message-string err)))))
|
||||
:args (list '(:name "dirpath" :type "string" :description "Directory path to list"))))
|
||||
|
||||
(use-package! claude-code-ide
|
||||
:defer t
|
||||
:config
|
||||
(claude-code-ide-emacs-tools-setup)
|
||||
(map! :leader
|
||||
(:prefix ("o" . "open")
|
||||
:desc "Claude Code IDE" "c" #'claude-code-ide-menu)))
|
||||
|
||||
(after! gptel
|
||||
(require 'gptel-tool-library)
|
||||
(setq gptel-tool-library-use-maybe-safe t
|
||||
gptel-tool-library-use-unsafe t)
|
||||
(dolist (module '("bbdb" "buffer" "elisp" "emacs" "gnus" "os" "search-and-replace" "url"))
|
||||
(gptel-tool-library-load-module module)))
|
||||
|
||||
;; Whenever you reconfigure a package, make sure to wrap your config in an
|
||||
;; `after!' block, otherwise Doom's defaults may override your settings. E.g.
|
||||
;;
|
||||
;; (after! PACKAGE
|
||||
;; (setq x y))
|
||||
;;
|
||||
;; The exceptions to this rule:
|
||||
;;
|
||||
;; - Setting file/directory variables (like `org-directory')
|
||||
;; - Setting variables which explicitly tell you to set them before their
|
||||
;; package is loaded (see 'C-h v VARIABLE' to look up their documentation).
|
||||
;; - Setting doom variables (which start with 'doom-' or '+').
|
||||
;;
|
||||
;; Here are some additional functions/macros that will help you configure Doom.
|
||||
;;
|
||||
;; - `load!' for loading external *.el files relative to this one
|
||||
;; - `use-package!' for configuring packages
|
||||
;; - `after!' for running code after a package has loaded
|
||||
;; - `add-load-path!' for adding directories to the `load-path', relative to
|
||||
;; this file. Emacs searches the `load-path' when you load packages with
|
||||
;; `require' or `use-package'.
|
||||
;; - `map!' for binding new keys
|
||||
;;
|
||||
;; To get information about any of these functions/macros, move the cursor over
|
||||
;; the highlighted symbol at press 'K' (non-evil users must press 'C-c c k').
|
||||
;; This will open documentation for it, including demos of how they are used.
|
||||
;; Alternatively, use `C-h o' to look up a symbol (functions, variables, faces,
|
||||
;; etc).
|
||||
;;
|
||||
;; You can also try 'gd' (or 'C-c c d') to jump to their definition and see how
|
||||
;; they are implemented.
|
||||
192
home/roles/emacs/doom/init.el
Normal file
192
home/roles/emacs/doom/init.el
Normal file
@@ -0,0 +1,192 @@
|
||||
;;; init.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; This file controls what Doom modules are enabled and what order they load
|
||||
;; in. Remember to run 'doom sync' after modifying it!
|
||||
|
||||
;; NOTE Press 'SPC h d h' (or 'C-h d h' for non-vim users) to access Doom's
|
||||
;; documentation. There you'll find a link to Doom's Module Index where all
|
||||
;; of our modules are listed, including what flags they support.
|
||||
|
||||
;; NOTE Move your cursor over a module's name (or its flags) and press 'K' (or
|
||||
;; 'C-c c k' for non-vim users) to view its documentation. This works on
|
||||
;; flags as well (those symbols that start with a plus).
|
||||
;;
|
||||
;; Alternatively, press 'gd' (or 'C-c c d') on a module to browse its
|
||||
;; directory (for easy access to its source code).
|
||||
|
||||
(doom! :input
|
||||
;;bidi ; (tfel ot) thgir etirw uoy gnipleh
|
||||
;;chinese
|
||||
;;japanese
|
||||
;;layout ; auie,ctsrnm is the superior home row
|
||||
|
||||
:completion
|
||||
;;company ; the ultimate code completion backend
|
||||
(corfu +orderless) ; complete with cap(f), cape and a flying feather!
|
||||
;;helm ; the *other* search engine for love and life
|
||||
;;ido ; the other *other* search engine...
|
||||
;;ivy ; a search engine for love and life
|
||||
vertico ; the search engine of the future
|
||||
|
||||
:ui
|
||||
;;deft ; notational velocity for Emacs
|
||||
doom ; what makes DOOM look the way it does
|
||||
doom-dashboard ; a nifty splash screen for Emacs
|
||||
;;doom-quit ; DOOM quit-message prompts when you quit Emacs
|
||||
;;(emoji +unicode) ; 🙂
|
||||
hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
|
||||
;;indent-guides ; highlighted indent columns
|
||||
;;ligatures ; ligatures and symbols to make your code pretty again
|
||||
;;minimap ; show a map of the code on the side
|
||||
modeline ; snazzy, Atom-inspired modeline, plus API
|
||||
;;nav-flash ; blink cursor line after big motions
|
||||
;;neotree ; a project drawer, like NERDTree for vim
|
||||
ophints ; highlight the region an operation acts on
|
||||
(popup +defaults) ; tame sudden yet inevitable temporary windows
|
||||
;;tabs ; a tab bar for Emacs
|
||||
;;treemacs ; a project drawer, like neotree but cooler
|
||||
unicode ; extended unicode support for various languages
|
||||
(vc-gutter +pretty) ; vcs diff in the fringe
|
||||
vi-tilde-fringe ; fringe tildes to mark beyond EOB
|
||||
;;window-select ; visually switch windows
|
||||
workspaces ; tab emulation, persistence & separate workspaces
|
||||
;;zen ; distraction-free coding or writing
|
||||
|
||||
:editor
|
||||
(evil +everywhere); come to the dark side, we have cookies
|
||||
file-templates ; auto-snippets for empty files
|
||||
fold ; (nigh) universal code folding
|
||||
;;(format +onsave) ; automated prettiness
|
||||
;;god ; run Emacs commands without modifier keys
|
||||
;;lispy ; vim for lisp, for people who don't like vim
|
||||
multiple-cursors ; editing in many places at once
|
||||
;;objed ; text object editing for the innocent
|
||||
;;parinfer ; turn lisp into python, sort of
|
||||
;;rotate-text ; cycle region at point between text candidates
|
||||
snippets ; my elves. They type so I don't have to
|
||||
;;word-wrap ; soft wrapping with language-aware indent
|
||||
|
||||
:emacs
|
||||
dired ; making dired pretty [functional]
|
||||
electric ; smarter, keyword-based electric-indent
|
||||
;;ibuffer ; interactive buffer management
|
||||
undo ; persistent, smarter undo for your inevitable mistakes
|
||||
vc ; version-control and Emacs, sitting in a tree
|
||||
|
||||
:term
|
||||
;;eshell ; the elisp shell that works everywhere
|
||||
;;shell ; simple shell REPL for Emacs
|
||||
;;term ; basic terminal emulator for Emacs
|
||||
vterm ; the best terminal emulation in Emacs
|
||||
|
||||
:checkers
|
||||
syntax ; tasing you for every semicolon you forget
|
||||
;;(spell +flyspell) ; tasing you for misspelling mispelling
|
||||
;;grammar ; tasing grammar mistake every you make
|
||||
|
||||
:tools
|
||||
ansible
|
||||
;;biblio ; Writes a PhD for you (citation needed)
|
||||
;;collab ; buffers with friends
|
||||
;;debugger ; FIXME stepping through code, to help you add bugs
|
||||
;;direnv
|
||||
docker
|
||||
;;editorconfig ; let someone else argue about tabs vs spaces
|
||||
;;ein ; tame Jupyter notebooks with emacs
|
||||
(eval +overlay) ; run code, run (also, repls)
|
||||
llm ; When I said you needed friends, I didn't mean...
|
||||
lookup ; navigate your code and its documentation
|
||||
lsp ; M-x vscode
|
||||
magit ; a git porcelain for Emacs
|
||||
;;make ; run make tasks from Emacs
|
||||
;;pass ; password manager for nerds
|
||||
pdf ; pdf enhancements
|
||||
;;prodigy ; FIXME managing external services & code builders
|
||||
;;terraform ; infrastructure as code
|
||||
;;tmux ; an API for interacting with tmux
|
||||
tree-sitter ; syntax and parsing, sitting in a tree...
|
||||
;;upload ; map local to remote projects via ssh/ftp
|
||||
|
||||
:os
|
||||
(:if (featurep :system 'macos) macos) ; improve compatibility with macOS
|
||||
tty ; improve the terminal Emacs experience
|
||||
|
||||
:lang
|
||||
;;agda ; types of types of types of types...
|
||||
;;beancount ; mind the GAAP
|
||||
;;(cc +lsp) ; C > C++ == 1
|
||||
;;clojure ; java with a lisp
|
||||
;;common-lisp ; if you've seen one lisp, you've seen them all
|
||||
;;coq ; proofs-as-programs
|
||||
;;crystal ; ruby at the speed of c
|
||||
;;csharp ; unity, .NET, and mono shenanigans
|
||||
;;data ; config/data formats
|
||||
;;(dart +flutter) ; paint ui and not much else
|
||||
;;dhall
|
||||
;;elixir ; erlang done right
|
||||
;;elm ; care for a cup of TEA?
|
||||
emacs-lisp ; drown in parentheses
|
||||
;;erlang ; an elegant language for a more civilized age
|
||||
;;ess ; emacs speaks statistics
|
||||
;;factor
|
||||
;;faust ; dsp, but you get to keep your soul
|
||||
;;fortran ; in FORTRAN, GOD is REAL (unless declared INTEGER)
|
||||
;;fsharp ; ML stands for Microsoft's Language
|
||||
;;fstar ; (dependent) types and (monadic) effects and Z3
|
||||
;;gdscript ; the language you waited for
|
||||
;;(go +lsp) ; the hipster dialect
|
||||
;;(graphql +lsp) ; Give queries a REST
|
||||
;;(haskell +lsp) ; a language that's lazier than I am
|
||||
;;hy ; readability of scheme w/ speed of python
|
||||
;;idris ; a language you can depend on
|
||||
;;json ; At least it ain't XML
|
||||
;;(java +lsp) ; the poster child for carpal tunnel syndrome
|
||||
;;javascript ; all(hope(abandon(ye(who(enter(here))))))
|
||||
;;julia ; a better, faster MATLAB
|
||||
;;kotlin ; a better, slicker Java(Script)
|
||||
;;latex ; writing papers in Emacs has never been so fun
|
||||
;;lean ; for folks with too much to prove
|
||||
;;ledger ; be audit you can be
|
||||
;;lua ; one-based indices? one-based indices
|
||||
markdown ; writing docs for people to ignore
|
||||
;;nim ; python + lisp at the speed of c
|
||||
(nix +tree-sitter) ; I hereby declare "nix geht mehr!"
|
||||
;;ocaml ; an objective camel
|
||||
(org +roam2) ; organize your plain life in plain text
|
||||
;;php ; perl's insecure younger brother
|
||||
;;plantuml ; diagrams for confusing people more
|
||||
;;purescript ; javascript, but functional
|
||||
(python +poetry) ; beautiful is better than ugly
|
||||
;;qt ; the 'cutest' gui framework ever
|
||||
;;racket ; a DSL for DSLs
|
||||
;;raku ; the artist formerly known as perl6
|
||||
;;rest ; Emacs as a REST client
|
||||
;;rst ; ReST in peace
|
||||
;;(ruby +rails) ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"}
|
||||
;;(rust +lsp) ; Fe2O3.unwrap().unwrap().unwrap().unwrap()
|
||||
;;scala ; java, but good
|
||||
;;(scheme +guile) ; a fully conniving family of lisps
|
||||
sh ; she sells {ba,z,fi}sh shells on the C xor
|
||||
;;sml
|
||||
;;solidity ; do you need a blockchain? No.
|
||||
;;swift ; who asked for emoji variables?
|
||||
;;terra ; Earth and Moon in alignment for performance.
|
||||
;;web ; the tubes
|
||||
;;yaml ; JSON, but readable
|
||||
;;zig ; C, but simpler
|
||||
|
||||
:email
|
||||
;;(mu4e +org +gmail)
|
||||
;;notmuch
|
||||
;;(wanderlust +gmail)
|
||||
|
||||
:app
|
||||
;;calendar
|
||||
;;emms
|
||||
;;everywhere ; *leave* Emacs!? You must be joking
|
||||
;;irc ; how neckbeards socialize
|
||||
;;(rss +org) ; emacs as an RSS reader
|
||||
|
||||
:config
|
||||
;;literate
|
||||
(default +bindings +smartparens))
|
||||
61
home/roles/emacs/doom/packages.el
Normal file
61
home/roles/emacs/doom/packages.el
Normal file
@@ -0,0 +1,61 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; $DOOMDIR/packages.el
|
||||
|
||||
;; To install a package with Doom you must declare them here and run 'doom sync'
|
||||
;; on the command line, then restart Emacs for the changes to take effect -- or
|
||||
;; use 'M-x doom/reload'.
|
||||
|
||||
|
||||
;; To install SOME-PACKAGE from MELPA, ELPA or emacsmirror:
|
||||
;; (package! some-package)
|
||||
|
||||
;; To install a package directly from a remote git repo, you must specify a
|
||||
;; `:recipe'. You'll find documentation on what `:recipe' accepts here:
|
||||
;; https://github.com/radian-software/straight.el#the-recipe-format
|
||||
;; (package! another-package
|
||||
;; :recipe (:host github :repo "username/repo"))
|
||||
|
||||
;; If the package you are trying to install does not contain a PACKAGENAME.el
|
||||
;; file, or is located in a subdirectory of the repo, you'll need to specify
|
||||
;; `:files' in the `:recipe':
|
||||
;; (package! this-package
|
||||
;; :recipe (:host github :repo "username/repo"
|
||||
;; :files ("some-file.el" "src/lisp/*.el")))
|
||||
|
||||
;; If you'd like to disable a package included with Doom, you can do so here
|
||||
;; with the `:disable' property:
|
||||
;; (package! builtin-package :disable t)
|
||||
|
||||
;; You can override the recipe of a built in package without having to specify
|
||||
;; all the properties for `:recipe'. These will inherit the rest of its recipe
|
||||
;; from Doom or MELPA/ELPA/Emacsmirror:
|
||||
;; (package! builtin-package :recipe (:nonrecursive t))
|
||||
;; (package! builtin-package-2 :recipe (:repo "myfork/package"))
|
||||
|
||||
;; Specify a `:branch' to install a package from a particular branch or tag.
|
||||
;; This is required for some packages whose default branch isn't 'master' (which
|
||||
;; our package manager can't deal with; see radian-software/straight.el#279)
|
||||
;; (package! builtin-package :recipe (:branch "develop"))
|
||||
|
||||
;; Use `:pin' to specify a particular commit to install.
|
||||
;; (package! builtin-package :pin "1a2b3c4d5e")
|
||||
|
||||
|
||||
;; Doom's packages are pinned to a specific commit and updated from release to
|
||||
;; release. The `unpin!' macro allows you to unpin single packages...
|
||||
;; (unpin! pinned-package)
|
||||
;; ...or multiple packages
|
||||
;; (unpin! pinned-package another-pinned-package)
|
||||
;; ...Or *all* packages (NOT RECOMMENDED; will likely break things)
|
||||
;; (unpin! t)
|
||||
|
||||
;; (package! org-caldav)
|
||||
|
||||
(package! gptel :recipe (:nonrecursive t))
|
||||
|
||||
(package! claude-code-ide
|
||||
:recipe (:host github :repo "manzaltu/claude-code-ide.el"))
|
||||
|
||||
(package! gptel-tool-library
|
||||
:recipe (:host github :repo "aard-fi/gptel-tool-library"
|
||||
:files ("*.el")))
|
||||
469
home/roles/i3+sway/default.nix
Normal file
469
home/roles/i3+sway/default.nix
Normal file
@@ -0,0 +1,469 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.home.roles.i3_sway;
|
||||
|
||||
shared_config = recursiveUpdate rec {
|
||||
modifier = "Mod4";
|
||||
terminal = "ghostty";
|
||||
defaultWorkspace = "workspace number 1";
|
||||
|
||||
keybindings = {
|
||||
"${shared_config.modifier}+Return" = "exec ${terminal}";
|
||||
"${shared_config.modifier}+Shift+q" = "kill";
|
||||
|
||||
"${shared_config.modifier}+a" = "focus parent";
|
||||
"${shared_config.modifier}+Shift+a" = "focus child";
|
||||
|
||||
"${shared_config.modifier}+h" = "focus left";
|
||||
"${shared_config.modifier}+j" = "focus down";
|
||||
"${shared_config.modifier}+k" = "focus up";
|
||||
"${shared_config.modifier}+l" = "focus right";
|
||||
|
||||
"${shared_config.modifier}+Shift+h" = "move left";
|
||||
"${shared_config.modifier}+Shift+j" = "move down";
|
||||
"${shared_config.modifier}+Shift+k" = "move up";
|
||||
"${shared_config.modifier}+Shift+l" = "move right";
|
||||
|
||||
"${shared_config.modifier}+Left" = "focus left";
|
||||
"${shared_config.modifier}+Down" = "focus down";
|
||||
"${shared_config.modifier}+Up" = "focus up";
|
||||
"${shared_config.modifier}+Right" = "focus right";
|
||||
|
||||
"${shared_config.modifier}+Shift+Left" = "move left";
|
||||
"${shared_config.modifier}+Shift+Down" = "move down";
|
||||
"${shared_config.modifier}+Shift+Up" = "move up";
|
||||
"${shared_config.modifier}+Shift+Right" = "move right";
|
||||
|
||||
#"${shared_config.modifier}+h" = "split h";
|
||||
"${shared_config.modifier}+v" = "split v";
|
||||
"${shared_config.modifier}+Shift+f" = "fullscreen toggle";
|
||||
|
||||
"${shared_config.modifier}+s" = "layout stacking";
|
||||
"${shared_config.modifier}+w" = "layout tabbed";
|
||||
"${shared_config.modifier}+e" = "layout toggle split";
|
||||
|
||||
"${shared_config.modifier}+Shift+space" = "floating toggle";
|
||||
"${shared_config.modifier}+space" = "focus mode_toggle";
|
||||
|
||||
"${shared_config.modifier}+Shift+minus" = "move scratchpad";
|
||||
"${shared_config.modifier}+minus" = "scratchpad show";
|
||||
|
||||
"${shared_config.modifier}+1" = "workspace number 1";
|
||||
"${shared_config.modifier}+2" = "workspace number 2";
|
||||
"${shared_config.modifier}+3" = "workspace number 3";
|
||||
"${shared_config.modifier}+4" = "workspace number 4";
|
||||
"${shared_config.modifier}+5" = "workspace number 5";
|
||||
"${shared_config.modifier}+6" = "workspace number 6";
|
||||
"${shared_config.modifier}+7" = "workspace number 7";
|
||||
"${shared_config.modifier}+8" = "workspace number 8";
|
||||
"${shared_config.modifier}+9" = "workspace number 9";
|
||||
"${shared_config.modifier}+0" = "workspace number 10";
|
||||
|
||||
"${shared_config.modifier}+Shift+1" =
|
||||
"move container to workspace number 1";
|
||||
"${shared_config.modifier}+Shift+2" =
|
||||
"move container to workspace number 2";
|
||||
"${shared_config.modifier}+Shift+3" =
|
||||
"move container to workspace number 3";
|
||||
"${shared_config.modifier}+Shift+4" =
|
||||
"move container to workspace number 4";
|
||||
"${shared_config.modifier}+Shift+5" =
|
||||
"move container to workspace number 5";
|
||||
"${shared_config.modifier}+Shift+6" =
|
||||
"move container to workspace number 6";
|
||||
"${shared_config.modifier}+Shift+7" =
|
||||
"move container to workspace number 7";
|
||||
"${shared_config.modifier}+Shift+8" =
|
||||
"move container to workspace number 8";
|
||||
"${shared_config.modifier}+Shift+9" =
|
||||
"move container to workspace number 9";
|
||||
"${shared_config.modifier}+Shift+0" =
|
||||
"move container to workspace number 10";
|
||||
|
||||
"${shared_config.modifier}+Shift+c" = "reload";
|
||||
"${shared_config.modifier}+Shift+r" = "restart";
|
||||
|
||||
"${shared_config.modifier}+r" = "mode resize";
|
||||
|
||||
"XF86MonBrightnessUp" = "exec ddcutil setvcp 10 + 5";
|
||||
"XF86MonBrightnessDown" = "exec ddcutil setvcp 10 - 5";
|
||||
};
|
||||
} cfg.extraSharedConfig;
|
||||
in {
|
||||
options.home.roles.i3_sway = {
|
||||
enable = mkEnableOption "i3 and Sway tiling window managers with waybar and rofi";
|
||||
|
||||
extraSharedConfig = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
description = "Extra configuration shared between i3 and sway";
|
||||
};
|
||||
|
||||
extraI3Config = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
description = "Extra i3-specific configuration";
|
||||
};
|
||||
|
||||
extraSwayConfig = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
description = "Extra sway-specific configuration";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# i3blocks configuration file
|
||||
home.file.".config/i3blocks/config".text = ''
|
||||
# i3blocks config - replicating waybar setup
|
||||
separator_block_width=15
|
||||
markup=pango
|
||||
|
||||
[disk]
|
||||
command=df -h / | awk 'NR==2 {print "💾 " $5}'
|
||||
interval=30
|
||||
separator=true
|
||||
|
||||
[cpu]
|
||||
command=top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{print "🧠 " int(100 - $1) "%"}'
|
||||
interval=2
|
||||
separator=true
|
||||
|
||||
[memory]
|
||||
command=free | awk 'NR==2 {printf "🐏 %.0f%%\n", $3*100/$2}'
|
||||
interval=5
|
||||
separator=true
|
||||
|
||||
[pulseaudio]
|
||||
command=${pkgs.writeShellScript "i3blocks-pulseaudio" ''
|
||||
volume=$(pactl get-sink-volume @DEFAULT_SINK@ | grep -Po '\d+%' | head -1)
|
||||
muted=$(pactl get-sink-mute @DEFAULT_SINK@ | grep -o 'yes')
|
||||
if [ "$muted" = "yes" ]; then
|
||||
echo "🔇"
|
||||
else
|
||||
vol_num=''${volume%\%}
|
||||
if [ $vol_num -le 33 ]; then
|
||||
echo "🔈 $volume"
|
||||
elif [ $vol_num -le 66 ]; then
|
||||
echo "🔉 $volume"
|
||||
else
|
||||
echo "🔊 $volume"
|
||||
fi
|
||||
fi
|
||||
''}
|
||||
interval=1
|
||||
signal=10
|
||||
separator=true
|
||||
|
||||
[backlight]
|
||||
command=${pkgs.writeShellScript "i3blocks-backlight" ''
|
||||
if command -v ddcutil &>/dev/null; then
|
||||
# Handle mouse scroll events
|
||||
case $BLOCK_BUTTON in
|
||||
4) ddcutil setvcp 10 + 5 ;; # Scroll up - increase brightness
|
||||
5) ddcutil setvcp 10 - 5 ;; # Scroll down - decrease brightness
|
||||
esac
|
||||
|
||||
# Display current brightness
|
||||
brightness=$(ddcutil getvcp 10 2>/dev/null | grep -oP 'current value =\s*\K\d+')
|
||||
if [ -n "$brightness" ]; then
|
||||
echo "☀️ $brightness%"
|
||||
fi
|
||||
fi
|
||||
''}
|
||||
interval=5
|
||||
separator=true
|
||||
|
||||
[network]
|
||||
command=${pkgs.writeShellScript "i3blocks-network" ''
|
||||
if iwgetid -r &>/dev/null; then
|
||||
ssid=$(iwgetid -r)
|
||||
signal=$(grep "^\s*w" /proc/net/wireless | awk '{print int($3 * 100 / 70)}')
|
||||
echo "📶 $ssid ($signal%)"
|
||||
else
|
||||
ip=$(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '127.0.0.1' | head -1)
|
||||
if [ -n "$ip" ]; then
|
||||
echo "🔌 $ip"
|
||||
else
|
||||
echo "❌"
|
||||
fi
|
||||
fi
|
||||
''}
|
||||
interval=5
|
||||
separator=true
|
||||
|
||||
[battery]
|
||||
command=${pkgs.writeShellScript "i3blocks-battery" ''
|
||||
if [ -d /sys/class/power_supply/BAT0 ]; then
|
||||
capacity=$(cat /sys/class/power_supply/BAT0/capacity)
|
||||
status=$(cat /sys/class/power_supply/BAT0/status)
|
||||
|
||||
if [ "$status" = "Charging" ]; then
|
||||
echo "⚡ $capacity%"
|
||||
else
|
||||
echo "🔋 $capacity%"
|
||||
fi
|
||||
fi
|
||||
''}
|
||||
interval=10
|
||||
separator=true
|
||||
|
||||
[time]
|
||||
command=date '+%Y-%m-%d %H:%M'
|
||||
interval=1
|
||||
separator=false
|
||||
'';
|
||||
|
||||
xsession.windowManager.i3 = let
|
||||
base_i3_config = recursiveUpdate shared_config {
|
||||
bars = [{
|
||||
position = "bottom";
|
||||
statusCommand = "${pkgs.i3blocks}/bin/i3blocks";
|
||||
trayOutput = "primary"; # Enable system tray on primary output
|
||||
fonts = {
|
||||
names = [ "Fira Code" "monospace" ];
|
||||
size = 11.0;
|
||||
};
|
||||
colors = {
|
||||
background = "#000000";
|
||||
statusline = "#ffffff";
|
||||
separator = "#666666";
|
||||
|
||||
# Workspace button colors (matching waybar)
|
||||
focusedWorkspace = {
|
||||
border = "#285577";
|
||||
background = "#285577";
|
||||
text = "#ffffff";
|
||||
};
|
||||
activeWorkspace = {
|
||||
border = "#5f676a";
|
||||
background = "#5f676a";
|
||||
text = "#ffffff";
|
||||
};
|
||||
inactiveWorkspace = {
|
||||
border = "#222222";
|
||||
background = "#222222";
|
||||
text = "#888888";
|
||||
};
|
||||
urgentWorkspace = {
|
||||
border = "#900000";
|
||||
background = "#900000";
|
||||
text = "#ffffff";
|
||||
};
|
||||
};
|
||||
}];
|
||||
keybindings = shared_config.keybindings // {
|
||||
"${shared_config.modifier}+d" = "exec rofi -show drun";
|
||||
"${shared_config.modifier}+Shift+e" =
|
||||
"exec i3-nagbar -t warning -m 'Do you want to exit i3?' -b 'Yes' 'i3-msg exit'";
|
||||
};
|
||||
startup = [
|
||||
# GNOME polkit authentication agent
|
||||
{
|
||||
command = "/run/current-system/sw/libexec/polkit-gnome-authentication-agent-1";
|
||||
always = false;
|
||||
notification = false;
|
||||
}
|
||||
# Picom compositor for smooth rendering and no tearing (important for Nvidia)
|
||||
{
|
||||
command = "picom --backend glx -b";
|
||||
always = false;
|
||||
notification = false;
|
||||
}
|
||||
# NetworkManager system tray applet
|
||||
{
|
||||
command = "nm-applet";
|
||||
always = false;
|
||||
notification = false;
|
||||
}
|
||||
# Set wallpaper with feh
|
||||
{
|
||||
command = "feh --bg-scale ${../../wallpapers/metroid-samus-returns-kz-3440x1440.jpg}";
|
||||
always = false;
|
||||
notification = false;
|
||||
}
|
||||
];
|
||||
};
|
||||
in {
|
||||
enable = true;
|
||||
config = recursiveUpdate base_i3_config cfg.extraI3Config;
|
||||
};
|
||||
|
||||
wayland.windowManager.sway = let
|
||||
base_sway_config = recursiveUpdate shared_config {
|
||||
bars = []; # Disable default bar, use waybar instead
|
||||
keybindings = shared_config.keybindings // {
|
||||
"${shared_config.modifier}+d" = "exec wofi --show drun";
|
||||
"${shared_config.modifier}+Shift+e" =
|
||||
"exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit'";
|
||||
};
|
||||
input = {
|
||||
"type:keyboard" = {
|
||||
xkb_options = "caps:escape";
|
||||
};
|
||||
"type:touchpad" = {
|
||||
tap = "enabled";
|
||||
tap_button_map = "lrm";
|
||||
drag = "enabled";
|
||||
natural_scroll = "disabled";
|
||||
dwt = "enabled";
|
||||
};
|
||||
};
|
||||
output = {
|
||||
"*" = {
|
||||
bg = "${../../wallpapers/metroid-samus-returns-kz-3440x1440.jpg} fill";
|
||||
};
|
||||
};
|
||||
startup = [
|
||||
# Launch waybar status bar
|
||||
{
|
||||
command = "waybar";
|
||||
always = false;
|
||||
}
|
||||
];
|
||||
};
|
||||
in {
|
||||
enable = true;
|
||||
config = recursiveUpdate base_sway_config cfg.extraSwayConfig;
|
||||
};
|
||||
|
||||
programs.waybar = {
|
||||
enable = true;
|
||||
systemd.enable = false; # Don't auto-start via systemd - only launch in sway
|
||||
settings = {
|
||||
mainBar = {
|
||||
layer = "top";
|
||||
position = "bottom";
|
||||
height = 30;
|
||||
spacing = 4;
|
||||
|
||||
modules-left = [ "sway/workspaces" "sway/mode" ];
|
||||
modules-center = [ ];
|
||||
modules-right = [ "disk" "cpu" "memory" "pulseaudio" "backlight" "network" "battery" "tray" "clock" ];
|
||||
|
||||
"sway/workspaces" = {
|
||||
disable-scroll = true;
|
||||
all-outputs = true;
|
||||
};
|
||||
|
||||
"clock" = {
|
||||
format = "{:%Y-%m-%d %H:%M}";
|
||||
tooltip-format = "<tt><small>{calendar}</small></tt>";
|
||||
calendar = {
|
||||
mode = "year";
|
||||
mode-mon-col = 3;
|
||||
weeks-pos = "right";
|
||||
on-scroll = 1;
|
||||
format = {
|
||||
months = "<span color='#ffead3'><b>{}</b></span>";
|
||||
days = "<span color='#ecc6d9'><b>{}</b></span>";
|
||||
weeks = "<span color='#99ffdd'><b>W{}</b></span>";
|
||||
weekdays = "<span color='#ffcc66'><b>{}</b></span>";
|
||||
today = "<span color='#ff6699'><b><u>{}</u></b></span>";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
"disk" = {
|
||||
interval = 30;
|
||||
format = "💾 {percentage_used}%";
|
||||
path = "/";
|
||||
tooltip-format = "Used: {used} / {total} ({percentage_used}%)\nFree: {free} ({percentage_free}%)";
|
||||
};
|
||||
|
||||
"cpu" = {
|
||||
format = "🧠 {usage}%";
|
||||
tooltip = false;
|
||||
};
|
||||
|
||||
"memory" = {
|
||||
format = "🐏 {percentage}%";
|
||||
tooltip-format = "RAM: {used:0.1f}G / {total:0.1f}G";
|
||||
};
|
||||
|
||||
"pulseaudio" = {
|
||||
format = "{icon} {volume}%";
|
||||
format-muted = "🔇";
|
||||
format-icons = {
|
||||
headphone = "🎧";
|
||||
default = [ "🔈" "🔉" "🔊" ];
|
||||
};
|
||||
on-click = "pavucontrol";
|
||||
};
|
||||
|
||||
"backlight" = {
|
||||
format = "☀️ {percent}%";
|
||||
tooltip = false;
|
||||
};
|
||||
|
||||
"network" = {
|
||||
format-wifi = "📶 {essid} ({signalStrength}%)";
|
||||
format-ethernet = "🔌 {ipaddr}";
|
||||
format-disconnected = "❌";
|
||||
tooltip-format = "{ifname}: {ipaddr}/{cidr}";
|
||||
};
|
||||
|
||||
"battery" = {
|
||||
states = {
|
||||
warning = 30;
|
||||
critical = 15;
|
||||
};
|
||||
format = "{icon} {capacity}%";
|
||||
format-charging = "⚡ {capacity}%";
|
||||
format-icons = [ "🪫" "🔋" "🔋" "🔋" "🔋" ];
|
||||
};
|
||||
|
||||
"tray" = {
|
||||
spacing = 10;
|
||||
};
|
||||
};
|
||||
};
|
||||
style = ''
|
||||
* {
|
||||
padding: 0 4px;
|
||||
font-family: "Fira Code", monospace;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
#workspaces button {
|
||||
padding: 0 8px;
|
||||
background-color: #333333;
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
}
|
||||
|
||||
#workspaces button.focused {
|
||||
background-color: #285577;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#workspaces button.visible {
|
||||
background-color: #5f676a;
|
||||
}
|
||||
|
||||
#workspaces button.urgent {
|
||||
background-color: #900000;
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
programs.rofi = {
|
||||
enable = true;
|
||||
theme = "solarized";
|
||||
extraConfig = {
|
||||
modi = "drun,run,window";
|
||||
show-icons = true;
|
||||
drun-display-format = "{name}";
|
||||
disable-history = false;
|
||||
hide-scrollbar = true;
|
||||
display-drun = " Apps";
|
||||
display-run = " Run";
|
||||
display-window = " Windows";
|
||||
sidebar-mode = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -7,10 +7,237 @@ let
|
||||
in
|
||||
{
|
||||
options.home.roles.kubectl = {
|
||||
enable = mkEnableOption "Enable management tools for the homelab k3s oglenet cluster";
|
||||
enable = mkEnableOption "management tools for the homelab k3s oglenet cluster with secure Bitwarden integration";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
programs.kubectl-secure.enable = true;
|
||||
home.packages = with pkgs; [
|
||||
kubectl
|
||||
kubernetes-helm
|
||||
];
|
||||
|
||||
programs.k9s.enable = true;
|
||||
|
||||
programs.bash.initExtra = mkAfter ''
|
||||
# Kubectl secure session management
|
||||
export KUBECTL_SESSION_DIR="/dev/shm/kubectl-$$"
|
||||
|
||||
kube-select() {
|
||||
if [[ $# -ne 1 ]]; then
|
||||
echo "Usage: kube-select <context-name>"
|
||||
echo "Available contexts: $(kube-list)"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local context="$1"
|
||||
|
||||
# Clean up any existing session first
|
||||
kube-clear 2>/dev/null
|
||||
|
||||
# Create new session directory
|
||||
mkdir -p "$KUBECTL_SESSION_DIR"
|
||||
chmod 700 "$KUBECTL_SESSION_DIR"
|
||||
|
||||
# Set cleanup trap for this shell session
|
||||
trap "rm -rf '$KUBECTL_SESSION_DIR' 2>/dev/null" EXIT
|
||||
|
||||
# Set KUBECONFIG for this session
|
||||
export KUBECONFIG="$KUBECTL_SESSION_DIR/config"
|
||||
|
||||
# Load config from Bitwarden secure notes
|
||||
if ! rbw get "kubectl-$context" > "$KUBECONFIG" 2>/dev/null; then
|
||||
echo "Error: Could not retrieve kubectl-$context from Bitwarden"
|
||||
echo "Make sure the entry exists with name: kubectl-$context"
|
||||
kube-clear
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify the kubeconfig is valid
|
||||
if ! kubectl config view >/dev/null 2>&1; then
|
||||
echo "Error: Invalid kubeconfig retrieved from Bitwarden"
|
||||
kube-clear
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "✓ Loaded kubectl context: $context (session: $$)"
|
||||
echo " Config location: $KUBECONFIG"
|
||||
}
|
||||
|
||||
kube-list() {
|
||||
echo "Available kubectl contexts in Bitwarden:"
|
||||
rbw search kubectl- 2>/dev/null | grep "^kubectl-" | sed 's/^kubectl-/ - /' || echo " (none found or rbw not accessible)"
|
||||
}
|
||||
|
||||
kube-clear() {
|
||||
if [[ -n "$KUBECTL_TIMEOUT_PID" ]]; then
|
||||
kill "$KUBECTL_TIMEOUT_PID" 2>/dev/null
|
||||
unset KUBECTL_TIMEOUT_PID
|
||||
fi
|
||||
|
||||
if [[ -d "$KUBECTL_SESSION_DIR" ]]; then
|
||||
rm -rf "$KUBECTL_SESSION_DIR"
|
||||
echo "Cleared kubectl session ($$)"
|
||||
fi
|
||||
|
||||
unset KUBECONFIG
|
||||
}
|
||||
|
||||
kube-status() {
|
||||
if [[ -f "$KUBECONFIG" ]]; then
|
||||
local current_context
|
||||
current_context=$(kubectl config current-context 2>/dev/null)
|
||||
if [[ -n "$current_context" ]]; then
|
||||
echo "Active kubectl context: $current_context"
|
||||
echo "Session: $$ | Config: $KUBECONFIG"
|
||||
|
||||
# Show cluster info
|
||||
local cluster_server
|
||||
cluster_server=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}' 2>/dev/null)
|
||||
if [[ -n "$cluster_server" ]]; then
|
||||
echo "Cluster: $cluster_server"
|
||||
fi
|
||||
else
|
||||
echo "No active context in current session"
|
||||
fi
|
||||
else
|
||||
echo "No kubectl session active in this shell"
|
||||
echo "Use 'kube-select <context>' to start a session"
|
||||
fi
|
||||
}
|
||||
|
||||
# Helper function to show available commands
|
||||
kube-help() {
|
||||
echo "Secure kubectl session management commands:"
|
||||
echo ""
|
||||
echo "Session management:"
|
||||
echo " kube-select <context> - Load kubeconfig from Bitwarden"
|
||||
echo " kube-status - Show current session status"
|
||||
echo " kube-clear - Clear current session"
|
||||
echo ""
|
||||
echo "Configuration management:"
|
||||
echo " kube-list - List available contexts in Bitwarden"
|
||||
echo ""
|
||||
echo "Help:"
|
||||
echo " kube-help - Show this help"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " kube-select prod # Loads from secure note"
|
||||
echo " kubectl get pods"
|
||||
echo " kube-clear"
|
||||
echo ""
|
||||
echo "Note: Kubeconfigs are stored as secure notes in Bitwarden"
|
||||
}
|
||||
'';
|
||||
|
||||
programs.zsh.initExtra = mkAfter ''
|
||||
# Kubectl secure session management (zsh)
|
||||
export KUBECTL_SESSION_DIR="/dev/shm/kubectl-$$"
|
||||
|
||||
kube-select() {
|
||||
if [[ $# -ne 1 ]]; then
|
||||
echo "Usage: kube-select <context-name>"
|
||||
echo "Available contexts: $(kube-list)"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local context="$1"
|
||||
|
||||
# Clean up any existing session first
|
||||
kube-clear 2>/dev/null
|
||||
|
||||
# Create new session directory
|
||||
mkdir -p "$KUBECTL_SESSION_DIR"
|
||||
chmod 700 "$KUBECTL_SESSION_DIR"
|
||||
|
||||
# Set cleanup trap for this shell session
|
||||
trap "rm -rf '$KUBECTL_SESSION_DIR' 2>/dev/null" EXIT
|
||||
|
||||
# Set KUBECONFIG for this session
|
||||
export KUBECONFIG="$KUBECTL_SESSION_DIR/config"
|
||||
|
||||
# Load config from Bitwarden secure notes
|
||||
if ! rbw get "kubectl-$context" > "$KUBECONFIG" 2>/dev/null; then
|
||||
echo "Error: Could not retrieve kubectl-$context from Bitwarden"
|
||||
echo "Make sure the entry exists with name: kubectl-$context"
|
||||
kube-clear
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify the kubeconfig is valid
|
||||
if ! kubectl config view >/dev/null 2>&1; then
|
||||
echo "Error: Invalid kubeconfig retrieved from Bitwarden"
|
||||
kube-clear
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "✓ Loaded kubectl context: $context (session: $$)"
|
||||
echo " Config location: $KUBECONFIG"
|
||||
}
|
||||
|
||||
kube-list() {
|
||||
echo "Available kubectl contexts in Bitwarden:"
|
||||
rbw search kubectl- 2>/dev/null | grep "^kubectl-" | sed 's/^kubectl-/ - /' || echo " (none found or rbw not accessible)"
|
||||
}
|
||||
|
||||
kube-clear() {
|
||||
if [[ -n "$KUBECTL_TIMEOUT_PID" ]]; then
|
||||
kill "$KUBECTL_TIMEOUT_PID" 2>/dev/null
|
||||
unset KUBECTL_TIMEOUT_PID
|
||||
fi
|
||||
|
||||
if [[ -d "$KUBECTL_SESSION_DIR" ]]; then
|
||||
rm -rf "$KUBECTL_SESSION_DIR"
|
||||
echo "Cleared kubectl session ($$)"
|
||||
fi
|
||||
|
||||
unset KUBECONFIG
|
||||
}
|
||||
|
||||
kube-status() {
|
||||
if [[ -f "$KUBECONFIG" ]]; then
|
||||
local current_context
|
||||
current_context=$(kubectl config current-context 2>/dev/null)
|
||||
if [[ -n "$current_context" ]]; then
|
||||
echo "Active kubectl context: $current_context"
|
||||
echo "Session: $$ | Config: $KUBECONFIG"
|
||||
|
||||
# Show cluster info
|
||||
local cluster_server
|
||||
cluster_server=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}' 2>/dev/null)
|
||||
if [[ -n "$cluster_server" ]]; then
|
||||
echo "Cluster: $cluster_server"
|
||||
fi
|
||||
else
|
||||
echo "No active context in current session"
|
||||
fi
|
||||
else
|
||||
echo "No kubectl session active in this shell"
|
||||
echo "Use 'kube-select <context>' to start a session"
|
||||
fi
|
||||
}
|
||||
|
||||
# Helper function to show available commands
|
||||
kube-help() {
|
||||
echo "Secure kubectl session management commands:"
|
||||
echo ""
|
||||
echo "Session management:"
|
||||
echo " kube-select <context> - Load kubeconfig from Bitwarden"
|
||||
echo " kube-status - Show current session status"
|
||||
echo " kube-clear - Clear current session"
|
||||
echo ""
|
||||
echo "Configuration management:"
|
||||
echo " kube-list - List available contexts in Bitwarden"
|
||||
echo ""
|
||||
echo "Help:"
|
||||
echo " kube-help - Show this help"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " kube-select prod # Loads from secure note"
|
||||
echo " kubectl get pods"
|
||||
echo " kube-clear"
|
||||
echo ""
|
||||
echo "Note: Kubeconfigs are stored as secure notes in Bitwarden"
|
||||
}
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
188
home/roles/plasma-manager/default.nix
Normal file
188
home/roles/plasma-manager/default.nix
Normal file
@@ -0,0 +1,188 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.home.roles.plasma-manager;
|
||||
in
|
||||
{
|
||||
options.home.roles.plasma-manager = {
|
||||
enable = mkEnableOption "KDE Plasma desktop environment configuration";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# The current KDE config can be output with the command:
|
||||
# nix run github:nix-community/plasma-manager
|
||||
#
|
||||
# Plasma-manager options documentation
|
||||
# https://nix-community.github.io/plasma-manager/options.xhtml
|
||||
#
|
||||
# TODO: (ambitious) Add Kmail support to plasma-manager
|
||||
programs.plasma = {
|
||||
enable = true;
|
||||
overrideConfig = true;
|
||||
|
||||
hotkeys.commands."launch-ghostty" = {
|
||||
name = "Launch Ghostty";
|
||||
key = "Meta+Return";
|
||||
command = "ghostty";
|
||||
};
|
||||
|
||||
shortcuts = {
|
||||
kmix = {
|
||||
"decrease_microphone_volume" = "Microphone Volume Down";
|
||||
"decrease_volume" = "Volume Down";
|
||||
"decrease_volume_small" = "Shift+Volume Down";
|
||||
"increase_microphone_volume" = "Microphone Volume Up";
|
||||
"increase_volume" = "Volume Up";
|
||||
"increase_volume_small" = "Shift+Volume Up";
|
||||
"mic_mute" = ["Microphone Mute" "Meta+Volume Mute,Microphone Mute" "Meta+Volume Mute,Mute Microphone"];
|
||||
"mute" = "Volume Mute";
|
||||
};
|
||||
|
||||
mediacontrol = {
|
||||
"mediavolumedown" = "none,,Media volume down";
|
||||
"mediavolumeup" = "none,,Media volume up";
|
||||
"nextmedia" = "Media Next";
|
||||
"pausemedia" = "Media Pause";
|
||||
"playmedia" = "none,,Play media playback";
|
||||
"playpausemedia" = "Media Play";
|
||||
"previousmedia" = "Media Previous";
|
||||
"stopmedia" = "Media Stop";
|
||||
};
|
||||
|
||||
ksmserver = {
|
||||
"Lock Session" = ["Meta+Ctrl+Q" "Screensaver" "Screensaver,Lock Session"];
|
||||
};
|
||||
|
||||
kwin = {
|
||||
"Window Close" = "Meta+Shift+Q";
|
||||
"Kill Window" = "Meta+Ctrl+Esc";
|
||||
"Window Operations Menu" = "Alt+F3";
|
||||
"Window Resize" = "Meta+R,,Resize Window";
|
||||
|
||||
"Overview" = "Meta+Ctrl+W";
|
||||
"Grid View" = "Meta+G";
|
||||
"Edit Tiles" = "Meta+T";
|
||||
|
||||
"Activate Window Demanding Attention" = "Meta+Ctrl+A";
|
||||
|
||||
"Show Desktop" = "Meta+Ctrl+D";
|
||||
|
||||
"Walk Through Windows" = "Alt+Tab";
|
||||
"Walk Through Windows (Reverse)" = "Alt+Shift+Tab";
|
||||
"Walk Through Windows of Current Application" = "Alt+`";
|
||||
"Walk Through Windows of Current Application (Reverse)" = "Alt+~";
|
||||
|
||||
"Window Quick Tile Bottom" = "Meta+Down";
|
||||
"Window Quick Tile Left" = "Meta+Left";
|
||||
"Window Quick Tile Right" = "Meta+Right";
|
||||
"Window Quick Tile Top" = "Meta+Up";
|
||||
|
||||
"Switch to Desktop 1" = "Meta+1";
|
||||
"Switch to Desktop 2" = "Meta+2";
|
||||
"Switch to Desktop 3" = "Meta+3";
|
||||
"Switch to Desktop 4" = "Meta+4";
|
||||
"Switch to Desktop 5" = "Meta+5";
|
||||
"Switch to Desktop 6" = "Meta+6";
|
||||
"Switch to Desktop 7" = "Meta+7";
|
||||
"Switch to Desktop 8" = "Meta+8";
|
||||
"Switch to Desktop 9" = "Meta+9";
|
||||
"Switch to Desktop 10" = "Meta+0";
|
||||
|
||||
"Window to Desktop 1" = "Meta+!"; # Meta+Shift+1
|
||||
"Window to Desktop 2" = "Meta+@"; # Meta+Shift+2
|
||||
"Window to Desktop 3" = "Meta+#"; # Meta+Shift+3
|
||||
"Window to Desktop 4" = "Meta+$"; # Meta+Shift+4
|
||||
"Window to Desktop 5" = "Meta+%"; # Meta+Shift+5
|
||||
"Window to Desktop 6" = "Meta+^"; # Meta+Shift+6
|
||||
"Window to Desktop 7" = "Meta+&"; # Meta+Shift+7
|
||||
"Window to Desktop 8" = "Meta+*"; # Meta+Shift+8
|
||||
"Window to Desktop 9" = "Meta+("; # Meta+Shift+9
|
||||
"Window to Desktop 10" = "Meta+)"; # Meta+Shift+0
|
||||
|
||||
"view_actual_size" = "Meta+Ctrl+=";
|
||||
"view_zoom_in" = ["Meta++" "Meta+=,Meta++" "Meta+=,Zoom In"];
|
||||
"view_zoom_out" = "Meta+-";
|
||||
};
|
||||
"org_kde_powerdevil"."Decrease Keyboard Brightness" = "Keyboard Brightness Down";
|
||||
"org_kde_powerdevil"."Decrease Screen Brightness" = "Monitor Brightness Down";
|
||||
"org_kde_powerdevil"."Decrease Screen Brightness Small" = "Shift+Monitor Brightness Down";
|
||||
"org_kde_powerdevil"."Hibernate" = "Hibernate";
|
||||
"org_kde_powerdevil"."Increase Keyboard Brightness" = "Keyboard Brightness Up";
|
||||
"org_kde_powerdevil"."Increase Screen Brightness" = "Monitor Brightness Up";
|
||||
"org_kde_powerdevil"."Increase Screen Brightness Small" = "Shift+Monitor Brightness Up";
|
||||
"org_kde_powerdevil"."PowerDown" = "Power Down";
|
||||
"org_kde_powerdevil"."PowerOff" = "Power Off";
|
||||
"org_kde_powerdevil"."Sleep" = "Sleep";
|
||||
"org_kde_powerdevil"."Toggle Keyboard Backlight" = "Keyboard Light On/Off";
|
||||
"org_kde_powerdevil"."Turn Off Screen" = [ ];
|
||||
"org_kde_powerdevil"."powerProfile" = ["Battery" "Meta+B,Battery" "Meta+B,Switch Power Profile"];
|
||||
|
||||
plasmashell = {
|
||||
"activate application launcher" = ["Meta" "Alt+F1,Meta" "Alt+F1,Activate Application Launcher"];
|
||||
"activate task manager entry 1" = "none,,";
|
||||
"activate task manager entry 2" = "none,,";
|
||||
"activate task manager entry 3" = "none,,";
|
||||
"activate task manager entry 4" = "none,,";
|
||||
"activate task manager entry 5" = "none,,";
|
||||
"activate task manager entry 6" = "none,,";
|
||||
"activate task manager entry 7" = "none,,";
|
||||
"activate task manager entry 8" = "none,,";
|
||||
"activate task manager entry 9" = "none,,";
|
||||
"activate task manager entry 10" = "none,,";
|
||||
"show activity switcher" = "none,,";
|
||||
};
|
||||
};
|
||||
|
||||
configFile = {
|
||||
kwinrc.Desktops.Number = {
|
||||
value = 10;
|
||||
immutable = true;
|
||||
};
|
||||
|
||||
# Enable KWin tiling features
|
||||
kwinrc.Tiling = {
|
||||
# Enable tiling functionality
|
||||
"padding" = 4;
|
||||
};
|
||||
|
||||
# Enable krohnkite plugin automatically
|
||||
kwinrc.Plugins = {
|
||||
krohnkiteEnabled = true;
|
||||
};
|
||||
|
||||
kwinrc.Effect-overview = {
|
||||
# Configure overview effect for better tiling workflow
|
||||
BorderActivate = 9; # Top-left corner activation
|
||||
};
|
||||
|
||||
kcminputrc.Libinput = {
|
||||
AccelerationProfile = "adaptive";
|
||||
PointerAcceleration = 0.5;
|
||||
};
|
||||
|
||||
kcminputrc.Mouse = {
|
||||
X11LibInputXAccelProfileFlat = false;
|
||||
XLbInptAccelProfileFlat = false;
|
||||
};
|
||||
|
||||
kdeglobals.KDE.LookAndFeelPackage = "org.kde.breezedark.desktop";
|
||||
|
||||
# Focus follows mouse configuration
|
||||
kwinrc.Windows = {
|
||||
FocusPolicy = "FocusFollowsMouse";
|
||||
AutoRaise = true; # Set to true if you want windows to auto-raise on focus
|
||||
AutoRaiseInterval = 750; # Delay in ms before auto-raise (if enabled)
|
||||
DelayFocusInterval = 0; # Delay in ms before focus follows mouse
|
||||
};
|
||||
|
||||
# Desktop wallpaper configuration
|
||||
plasma-localerc.Formats.LANG = "en_US.UTF-8";
|
||||
|
||||
# Set wallpaper for all desktops
|
||||
plasmarc.Wallpapers.usersWallpapers = "${../../wallpapers/metroid-samus-returns-kz-3440x1440.jpg}";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
62
home/roles/tmux/default.nix
Normal file
62
home/roles/tmux/default.nix
Normal file
@@ -0,0 +1,62 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.home.roles.tmux;
|
||||
|
||||
tokyo-night = pkgs.tmuxPlugins.mkTmuxPlugin {
|
||||
pluginName = "tokyo-night";
|
||||
rtpFilePath = "tokyo-night.tmux";
|
||||
version = "1.6.1";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "janoamaral";
|
||||
repo = "tokyo-night-tmux";
|
||||
rev = "d610ced20d5f602a7995854931440e4a1e0ab780";
|
||||
sha256 = "sha256-17vEgkL7C51p/l5gpT9dkOy0bY9n8l0/LV51mR1k+V8=";
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
options.home.roles.tmux = {
|
||||
enable = mkEnableOption "tmux terminal multiplexer with Tokyo Night theme";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
programs.tmux.enable = true;
|
||||
programs.tmux.terminal = "tmux-direct";
|
||||
programs.tmux.keyMode = "vi";
|
||||
programs.tmux.escapeTime = 0;
|
||||
programs.tmux.mouse = true;
|
||||
programs.tmux.newSession = true;
|
||||
programs.tmux.historyLimit = 50000;
|
||||
programs.tmux.clock24 = true;
|
||||
programs.tmux.baseIndex = 1;
|
||||
programs.tmux.prefix = "M-\\\\";
|
||||
|
||||
programs.tmux.plugins = with pkgs; [
|
||||
tmuxPlugins.cpu
|
||||
tmuxPlugins.battery
|
||||
tmuxPlugins.better-mouse-mode
|
||||
tmuxPlugins.net-speed
|
||||
tmuxPlugins.online-status
|
||||
tmuxPlugins.pain-control
|
||||
tmuxPlugins.tilish
|
||||
tmuxPlugins.yank
|
||||
|
||||
{
|
||||
plugin = tmuxPlugins.resurrect;
|
||||
extraConfig = "set -g @resurrect-strategy-nvim 'session'";
|
||||
}
|
||||
{
|
||||
plugin = tmuxPlugins.continuum;
|
||||
extraConfig = ''
|
||||
set -g @continuum-restore 'on'
|
||||
set -g @continuum-save-interval '15' # minutes
|
||||
'';
|
||||
}
|
||||
|
||||
tokyo-night
|
||||
];
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user