summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPreston Pan <ret2pop@nullring.xyz>2026-03-25 20:06:26 -0700
committerPreston Pan <ret2pop@nullring.xyz>2026-03-25 20:06:26 -0700
commitd79e97256cb01e33c47822859e171161352fb7c9 (patch)
treec7c03b4eae03d52923a21833920e1b1523a35af4
parent42656b6d8e9d433ee9a032605755679157980365 (diff)
add qtile configuration
-rw-r--r--agenda.org25
-rw-r--r--config/emacs.org574
-rw-r--r--config/nix.org977
-rw-r--r--config/qtile.org421
-rw-r--r--config/qutebrowser.org99
-rw-r--r--journal/20260324.org10
m---------nix0
-rw-r--r--robots.txt2
8 files changed, 998 insertions, 1110 deletions
diff --git a/agenda.org b/agenda.org
index 9dbe3ce..d99bb3b 100644
--- a/agenda.org
+++ b/agenda.org
@@ -19,10 +19,10 @@ These are general life tasks that I need to do, which don't depend on a specific
- [ ] write a shell script to get passwords from my run path.
- [ ] write tests for installer script.
- [ ] write documentation
-- [ ] add Raspberry Pi cross compiled system to ~nixmacs~.
+- [-] add Raspberry Pi cross compiled system to ~nixmacs~.
- [ ] Should have integration tests.
- - [ ] Should have a basic git server with git LFS.
- - [ ] Should have an SSH server.
+ - [X] Should have a basic git server with git LFS.
+ - [X] Should have an SSH server.
- [ ] Should have simple cronjobs.
- [ ] Gitolite
- [ ] AI Agent integration
@@ -85,11 +85,13 @@ Current stack:
- Hyaluronic acid (2x/day)
- Glycerin for hands
** TODO Supplements
-SCHEDULED: <2026-03-22 Sun .+1d>
+SCHEDULED: <2026-03-26 Thu 12:00 .+1d>
:PROPERTIES:
-:LAST_REPEAT: [2026-03-21 Sat 10:26]
+:LAST_REPEAT: [2026-03-25 Wed 11:52]
:STYLE: habit
:END:
+- State "DONE" from "TODO" [2026-03-25 Wed 11:52]
+- State "DONE" from "TODO" [2026-03-24 Tue 16:24]
- State "DONE" from "TODO" [2026-03-21 Sat 10:26]
- State "DONE" from "TODO" [2026-03-18 Wed 22:51]
- State "DONE" from "TODO" [2025-09-30 Tue 13:20]
@@ -149,7 +151,7 @@ SCHEDULED: <2025-09-29 Mon .+1d>
- State "DONE" from "TODO" [2025-06-26 Thu 23:22]
I want to be able to run or bike every day so that I get my exercise in.
** TODO Stretch
-SCHEDULED: <2026-03-20 Fri .+1d>
+SCHEDULED: <2026-03-20 Fri 00:00 .+1d>
:PROPERTIES:
:LAST_REPEAT: [2026-03-19 Thu 03:36]
:STYLE: habit
@@ -174,11 +176,12 @@ Stretches:
- Seal
- Cat
** TODO Journal
-SCHEDULED: <2026-03-22 Sun .+1d>
+SCHEDULED: <2026-03-25 Wed 22:00 .+1d>
:PROPERTIES:
-:LAST_REPEAT: [2026-03-21 Sat 10:33]
+:LAST_REPEAT: [2026-03-24 Tue 22:48]
:STYLE: habit
:END:
+- State "DONE" from "TODO" [2026-03-24 Tue 22:48]
- State "DONE" from "TODO" [2026-03-21 Sat 10:33]
- State "DONE" from "TODO" [2026-03-18 Wed 23:16]
- State "DONE" from "TODO" [2026-03-17 Tue 02:05]
@@ -206,14 +209,16 @@ SCHEDULED: <2026-03-22 Sun .+1d>
- State "DONE" from "TODO" [2025-01-11 Sat 02:25]
I want to journal every day, at least a little bit, about my life and track it with a git repo.
** TODO Update Agenda
+SCHEDULED: <2026-03-26 Thu 11:00 .+1d>
:PROPERTIES:
-:LAST_REPEAT: [2026-03-21 Sat 10:26]
+:LAST_REPEAT: [2026-03-25 Wed 10:11]
:END:
+- State "DONE" from "TODO" [2026-03-25 Wed 10:11]
+- State "DONE" from "TODO" [2026-03-24 Tue 16:24]
- State "DONE" from "TODO" [2026-03-21 Sat 10:26]
- State "DONE" from "TODO" [2026-03-19 Thu 03:36]
- State "DONE" from "TODO" [2026-03-18 Wed 22:51]
If I didn't update the agenda today, take my agenda with a grain of salt.
-SCHEDULED: <2026-03-22 Sun .+1d>
** TODO Start Vacuum Robot
Start the vacuum robot so that it can clean the floor, every day.
SCHEDULED: <2025-10-16 Thu .+1d>
diff --git a/config/emacs.org b/config/emacs.org
index 29794af..98fe132 100644
--- a/config/emacs.org
+++ b/config/emacs.org
@@ -79,7 +79,7 @@ syntax elsewhere. Generally, however, these are all unordered and not dependent
;; start with sane defaults
(pixel-scroll-precision-mode 1)
- (display-battery-mode 1)
+ ;; (display-battery-mode 1)
(display-time-mode 1)
(menu-bar-mode -1)
(scroll-bar-mode -1)
@@ -89,12 +89,14 @@ syntax elsewhere. Generally, however, these are all unordered and not dependent
;; load theme, fonts, and transparency. Prettify symbols.
(set-face-attribute 'default nil :font "Iosevka Nerd Font" :height 130)
(set-face-attribute 'variable-pitch nil :font "Lora" :height 1.1)
-
+ (set-face-attribute 'alert-urgent-face nil :inherit nil)
(when (display-graphic-p)
- (set-fontset-font t 'han (font-spec :family "Noto Sans CJK SC"))
- (set-fontset-font t 'kana (font-spec :family "Noto Sans CJK JP"))
- (set-fontset-font t 'symbol (font-spec :family "Noto Color Emoji"))
- (set-fontset-font t 'symbol (font-spec :family "Symbols Nerd Font Mono") nil 'append)))
+ (set-fontset-font t 'han (font-spec :family "Noto Sans CJK SC"))
+ (set-fontset-font t 'kana (font-spec :family "Noto Sans CJK JP"))
+ (set-fontset-font t 'emoji (font-spec :family "Noto Color Emoji") nil 'prepend)
+ (set-fontset-font t 'symbol (font-spec :family "Noto Color Emoji") nil 'append)
+ (set-fontset-font t '(#x1f300 . #x1f5ff) (font-spec :family "Noto Color Emoji") nil 'prepend)
+ (set-fontset-font t '(#xe000 . #xf8ff) (font-spec :family "Symbols Nerd Font Mono") nil 'append)))
;; imperative
(defun evil-config ()
@@ -128,14 +130,14 @@ syntax elsewhere. Generally, however, these are all unordered and not dependent
;; taken from blog https://writepermission.com/org-blogging-rss-feed.html
(defun rp/org-rss-publish-to-rss (plist filename pub-dir)
"Publish RSS with PLIST, only when FILENAME is 'rss.org'.
-PUB-DIR is when the output will be placed."
+ PUB-DIR is when the output will be placed."
(if (equal "rss.org" (file-name-nondirectory filename))
(org-rss-publish-to-rss plist filename pub-dir)))
(defun format-rss-feed-entry (entry style project)
"Format ENTRY for the RSS feed.
-ENTRY is a file name. STYLE is either 'list' or 'tree'.
-PROJECT is the current project."
+ ENTRY is a file name. STYLE is either 'list' or 'tree'.
+ PROJECT is the current project."
(cond ((not (directory-name-p entry))
(let* ((file (org-publish--expand-file-name entry project))
(title (org-publish-find-title entry project))
@@ -182,6 +184,106 @@ PROJECT is the current project."
(defun rp/org-sitemap-publish-function (plist filename pub-dir)
(when (string-equal (file-name-nondirectory filename) "sitemap.xml")
(org-publish-attachment plist filename pub-dir)))
+
+(defvar my-mu4e-search-history nil)
+
+(defun my-mu4e-search-with-ivy ()
+ "Search mu4e using the native prompt wrapped in Ivy."
+ (interactive)
+ ;; We use mu4e's own query reader if possible, otherwise fallback
+ (let ((query (completing-read "mu4e search: "
+ my-mu4e-search-history nil nil nil
+ 'my-mu4e-search-history)))
+ (unless (string-blank-p query)
+ (mu4e-search query))))
+
+(defun my-mu4e-narrow-with-ivy ()
+ "Live-preview matches in the current buffer using Ivy,
+then append the typed input to the mu4e database query."
+ (interactive)
+ (let* ((current-query (or (mu4e-last-query) ""))
+ ;; 1. Collect all lines in the current headers buffer for the preview
+ (lines (save-excursion
+ (goto-char (point-min))
+ (let (res)
+ (while (not (eobp))
+ (push (buffer-substring-no-properties
+ (line-beginning-position)
+ (line-end-position))
+ res)
+ (forward-line 1))
+ (reverse res)))))
+
+ ;; 2. Launch Ivy with the collected lines
+ (ivy-read (format "Narrow '%s' with: " current-query)
+ lines
+ :action (lambda (_)
+ ;; 3. IGNORE the selected line (_).
+ ;; Instead, grab exactly what you typed into the prompt.
+ (let ((input ivy-text))
+ (if (string-blank-p input)
+ (message "No narrowing term provided. Canceled.")
+ ;; 4. Combine the old query with your new input and query Xapian
+ (mu4e-search (format "(%s) AND (%s)" current-query input))))))))
+
+(defvar my-current-weather "Fetching weather..."
+ "Stores the latest fetched weather string.")
+
+;; 2. The asynchronous fetch function
+(defun my-fetch-weather-async ()
+ "Fetch weather asynchronously without blocking Emacs."
+ (interactive)
+ (let ((buf (get-buffer-create " *wttr-output*")))
+ (with-current-buffer buf (erase-buffer))
+ (make-process
+ :name "wttr-fetch"
+ :buffer buf
+ :command '("curl" "-s" "--max-time" "2" "wttr.in/?format=3")
+ ;; The sentinel runs when the process finishes (success or fail)
+ :sentinel (lambda (process event)
+ (when (string-match-p "finished" event)
+ (let ((output (with-current-buffer (process-buffer process)
+ (string-trim (buffer-string)))))
+ ;; Validate output just like your old try macro did
+ (if (or (string-blank-p output)
+ (string-match-p "BLOCK FAILED\\|Unknown location\\|<html>" output))
+ (setq my-current-weather "Weather currently unavailable.")
+ (setq my-current-weather output)))
+
+ ;; If the dashboard is visible, refresh it so the new text appears!
+ (when (get-buffer-window "*dashboard*" 'visible)
+ (with-current-buffer "*dashboard*"
+ (dashboard-refresh-buffer))))))))
+
+;; 3. Your new, simplified (and fast!) dashboard widget
+(defun my-dashboard-insert-weather-clock (list-size)
+ "Insert a styled clock and the pre-fetched weather variable."
+ (let ((clock (format-time-string "%I:%M %p • %A, %B %d")))
+ (insert "\n")
+ (insert (propertize clock 'face '(:height 1.5 :weight bold :foreground "#51afef")))
+ (insert "\n\n")
+ ;; Just insert the variable. No network calls happen here.
+ (insert (propertize my-current-weather 'face '(:foreground "#a9a1e1" :weight semi-bold)))
+ (insert "\n\n")))
+
+(defun my-refresh-dashboard-if-visible ()
+ "Refresh the dashboard buffer, but only if it's currently visible in a window."
+ (when (get-buffer-window "*dashboard*" 'visible)
+ (with-current-buffer "*dashboard*"
+ (dashboard-refresh-buffer))))
+
+(defun my-setup-dashboard-timer ()
+ "Start a timer to refresh the dashboard every 60 seconds."
+ ;; Cancel any existing timer first to avoid creating multiple timers
+ (when (timerp my-dashboard-refresh-timer)
+ (cancel-timer my-dashboard-refresh-timer))
+ ;; Run the refresh function every 60 seconds
+ (setq my-dashboard-refresh-timer (run-with-timer 60 60 #'my-refresh-dashboard-if-visible)))
+
+(defun my-fix-htmlize-invalid-face-bug (orig-fn face attribute &optional frame inherit)
+ (if (eq face t)
+ 'unspecified
+ (funcall orig-fn face attribute frame inherit)))
#+end_src
** Random Packages
These are packages that I require in order to write some scripts in emacs-lisp.
@@ -211,6 +313,20 @@ Emacs is self documenting, after all!
(standard-indent 2 "base indentation")
(custom-safe-themes t "I already manage my themes with nix")
(custom-file null-device "Don't save custom configs")
+ (jit-lock-chunk-size 16384 "actually load code blocks")
+ (jit-lock-stealth-time 1.25 "fontify in the background after 1.25s of idle time")
+ (jit-lock-stealth-nice 0.1 "don't freeze Emacs while stealth fontifying")
+ ;; ---------------------------------------------------------------------------
+ ;; UTF-8 Everywhere
+ ;; ---------------------------------------------------------------------------
+ (set-language-environment "UTF-8")
+ (set-default-coding-systems 'utf-8)
+ (prefer-coding-system 'utf-8)
+ (set-terminal-coding-system 'utf-8)
+ (set-keyboard-coding-system 'utf-8)
+ (set-selection-coding-system 'utf-8)
+ (locale-coding-system 'utf-8)
+ (use-default-font-for-symbols nil)
;; Startup errors
(warning-minimum-level :emergency "Supress emacs warnings")
@@ -219,12 +335,11 @@ Emacs is self documenting, after all!
(browse-url-generic-program "qutebrowser" "set browser to librewolf")
(browse-url-secondary-browser-function 'browse-url-generic "set browser")
(browse-url-browser-function 'browse-url-generic "set browser")
- (default-frame-alist '((alpha-background . 80)
+ (default-frame-alist '((alpha-background . 100)
(vertical-scroll-bars)
(internal-border-width . 24)
(left-fringe . 8)
(right-fringe . 8)))
-
;; Mouse wheel
(mouse-wheel-scroll-amount '(1 ((shift) . 1)) "Nicer scrolling")
(mouse-wheel-progressive-speed nil "Make scrolling non laggy")
@@ -261,29 +376,38 @@ a variable an option. Often you will see a config section of a use-package decla
only one or two entries, which is intentional, as I've designed this configuration to put as
little in config as possible. I hardly consider most of this configuration to be imperative, but
of course Emacs was not designed to be fully imperative.
+** Network
+#+begin_src emacs-lisp :tangle ../nix/init.el
+(use-package enwc :custom (enwc-default-backend 'nm "use networkmanager backend"))
+#+end_src
+** System Monitor
+#+begin_src emacs-lisp :tangle ../nix/init.el
+(use-package proced
+ :custom (proced-enable-color-flag t "use colors in proced"))
+#+end_src
** Org Mode
This is my org mode configuration, which also configures latex.
#+begin_src emacs-lisp :tangle ../nix/init.el
- (use-package org
- :demand t
- :after (f s dash nix-mode)
- :hook
- ((org-mode . remove-annoying-pairing))
- :custom
- (org-export-allow-bind-keywords t "don't emit warnings")
- (org-confirm-babel-evaluate nil "I want to evaluate stuff when publishing")
- ;; Fix terrible indentation issues
- (org-edit-src-content-indentation 0)
- (org-src-tab-acts-natively t)
- (org-src-preserve-indentation t)
+(use-package org
+ :demand t
+ :after (f s dash nix-mode)
+ :hook
+ ((org-mode . remove-annoying-pairing))
+ :custom
+ (org-export-allow-bind-keywords t "don't emit warnings")
+ (org-confirm-babel-evaluate nil "I want to evaluate stuff when publishing")
+ ;; Fix terrible indentation issues
+ (org-edit-src-content-indentation 0)
+ (org-src-tab-acts-natively t)
+ (org-src-preserve-indentation t)
- (TeX-PDF-mode t)
- (org-confirm-babel-evaluate nil "Don't ask to evaluate code block")
- (org-export-with-broken-links t "publish website even with broken links")
- (org-src-fontify-natively t "Colors!")
+ (TeX-PDF-mode t)
+ (org-confirm-babel-evaluate nil "Don't ask to evaluate code block")
+ (org-export-with-broken-links t "publish website even with broken links")
+ (org-src-fontify-natively t "Colors!")
- ;; org-latex
- (org-format-latex-header "\\documentclass{article} \
+ ;; org-latex
+ (org-format-latex-header "\\documentclass{article} \
\\usepackage[usenames]{color} \
[DEFAULT-PACKAGES] \
[PACKAGES] \
@@ -303,187 +427,186 @@ This is my org mode configuration, which also configures latex.
\\addtolength{\\topmargin}{-2.54cm} \
\\usepackage{amsmath} \
")
- (org-preview-latex-image-directory (expand-file-name "~/.cache/ltximg/") "don't use weird cache location")
- (org-latex-preview-ltxpng-directory (expand-file-name "~/.cache/ltximg/") "don't use weird cache location")
- (org-latex-to-html-convert-command "printf '%%s' %i | pandoc -f latex -t html --mathml | tr -d '\\n' | sed -e 's/^<p>//' -e 's/<\\/p>$//'" "latex to MathML with special character handling")
- (org-latex-to-mathml-convert-command "printf '%%s' %i | pandoc -f latex -t html --mathml | tr -d '\\n' | sed -e 's/^<p>//' -e 's/<\\/p>$//'" "latex to MathML with special character handling")
-
- (TeX-engine 'xetex "set xelatex as default engine")
- (preview-default-option-list '("displaymath" "textmath" "graphics") "preview latex")
- ;; (preview-image-type 'png "Use PNGs")
- (org-preview-latex-default-process 'dvipng)
- (org-format-latex-options
- '(:foreground default
- :background default
- :scale 2
- :html-foreground "Black"
- :html-background "Transparent"
- :html-scale 1.5
- :matchers ("begin" "$1" "$" "$$" "\\(" "\\[")) "space latex better")
- (org-return-follows-link t "be able to follow links without mouse")
- (org-startup-indented t "Indent the headings")
- (org-image-actual-width '(300) "Cap width")
- (org-startup-with-latex-preview t "see latex previews on opening file")
- (org-startup-with-inline-images t "See images on opening file")
- (org-hide-emphasis-markers t "prettify org mode")
- (org-use-sub-superscripts "{}" "Only display superscripts and subscripts when enclosed in {}")
- (org-pretty-entities t "prettify org mode")
- (org-agenda-files (list "~/monorepo/agenda.org" "~/org/notes.org" "~/org/agenda.org") "set default org files")
- (org-default-notes-file (concat org-directory "/notes.org") "Notes file")
+ (org-preview-latex-image-directory (expand-file-name "~/.cache/ltximg/") "don't use weird cache location")
+ (org-latex-preview-ltxpng-directory (expand-file-name "~/.cache/ltximg/") "don't use weird cache location")
+ (org-latex-to-html-convert-command "printf '%%s' %i | pandoc -f latex -t html --mathml | tr -d '\\n' | sed -e 's/^<p>//' -e 's/<\\/p>$//'" "latex to MathML with special character handling")
+ (org-latex-to-mathml-convert-command "printf '%%s' %i | pandoc -f latex -t html --mathml | tr -d '\\n' | sed -e 's/^<p>//' -e 's/<\\/p>$//'" "latex to MathML with special character handling")
- ;; ricing
- (org-auto-align-tags nil)
- (org-tags-column 0)
- (org-catch-invisible-edits 'show-and-error)
- (org-special-ctrl-a/e t)
- (org-insert-heading-respect-content t)
- (org-hide-emphasis-markers t)
- (org-pretty-entities t)
- (org-agenda-tags-column 0)
- (org-ellipsis "…")
- :config
- (org-babel-do-load-languages 'org-babel-load-languages
- '((shell . t)
- (python . t)
- (nix . t)
- (scheme . t)
- (latex . t))))
+ (TeX-engine 'xetex "set xelatex as default engine")
+ (preview-default-option-list '("displaymath" "textmath" "graphics") "preview latex")
+ ;; (preview-image-type 'png "Use PNGs")
+ (org-preview-latex-default-process 'dvipng)
+ (org-format-latex-options
+ '(:foreground default
+ :background default
+ :scale 2
+ :html-foreground "Black"
+ :html-background "Transparent"
+ :html-scale 1.5
+ :matchers ("begin" "$1" "$" "$$" "\\(" "\\[")) "space latex better")
+ (org-return-follows-link t "be able to follow links without mouse")
+ (org-startup-indented t "Indent the headings")
+ (org-image-actual-width '(300) "Cap width")
+ (org-startup-with-latex-preview t "see latex previews on opening file")
+ (org-startup-with-inline-images t "See images on opening file")
+ (org-hide-emphasis-markers t "prettify org mode")
+ (org-use-sub-superscripts "{}" "Only display superscripts and subscripts when enclosed in {}")
+ (org-pretty-entities t "prettify org mode")
+ (org-agenda-files (list "~/monorepo/agenda.org" "~/org/notes.org" "~/org/agenda.org") "set default org files")
+ (org-default-notes-file (concat org-directory "/notes.org") "Notes file")
- (use-package org-tempo
- :after org)
+ ;; ricing
+ (org-auto-align-tags nil)
+ (org-tags-column 0)
+ (org-catch-invisible-edits 'show-and-error)
+ (org-special-ctrl-a/e t)
+ (org-insert-heading-respect-content t)
+ (org-hide-emphasis-markers t)
+ (org-pretty-entities t)
+ (org-agenda-tags-column 0)
+ (org-ellipsis "…")
+ :config
+ (org-babel-do-load-languages 'org-babel-load-languages
+ '((shell . t)
+ (python . t)
+ (nix . t)
+ (scheme . t)
+ (latex . t))))
- (use-package org-habit
- :after org
- :custom
- (org-habit-preceding-days 7 "See org habit entries")
- (org-habit-following-days 35 "See org habit entries")
- (org-habit-show-habits t "See org habit entries")
- (org-habit-show-habits-only-for-today nil "See org habit entries")
- (org-habit-show-all-today t "Show org habit graph"))
+(use-package org-tempo
+ :after org)
- (use-package htmlize
- :demand t
- :after (catppuccin-theme doom-themes yaml-mode))
+(use-package org-habit
+ :after org
+ :custom
+ (org-habit-preceding-days 7 "See org habit entries")
+ (org-habit-following-days 35 "See org habit entries")
+ (org-habit-show-habits t "See org habit entries")
+ (org-habit-show-habits-only-for-today nil "See org habit entries")
+ (org-habit-show-all-today t "Show org habit graph"))
- (unless noninteractive
- (use-package htmlize
- :after (doom-themes)))
+(use-package htmlize
+ :demand t
+ :after (catppuccin-theme doom-themes yaml-mode)
+ :config (advice-add 'face-attribute :around #'my-fix-htmlize-invalid-face-bug))
- (use-package ox-latex
- :after (org)
- :custom
- (org-latex-compiler "xelatex" "Use latex as default")
- (org-latex-pdf-process '("xelatex -interaction=nonstopmode -output-directory=%o %f") "set xelatex as default"))
+(use-package ox-latex
+ :after (org)
+ :custom
+ (org-latex-compiler "xelatex" "Use latex as default")
+ (org-latex-pdf-process '("xelatex -interaction=nonstopmode -output-directory=%o %f") "set xelatex as default"))
- (use-package ox-html
- :demand t
- :after (org htmlize)
- :custom
- (org-html-htmlize-output-type 'css "allow styling from CSS file")
- (org-html-with-latex 'html "let my html handler handle latex")
- (org-html-mathjax-options nil "disable mathjax, use MathML")
- (org-html-mathjax-template "" "disable mathjax, use MathML")
- (org-html-head-include-default-style nil "use my own css for everything")
- (org-html-head-include-scripts nil "use my own js for everything")
- (org-html-postamble (concat "Copyright © 2024 " system-fullname) "set copyright notice on bottom of site")
- (org-html-divs '((preamble "header" "preamble")
- (content "main" "content")
- (postamble "footer" "postamble")) "semantic html exports")
- (org-html-viewport '((width "device-width")
- (initial-scale "1.0")
- (minimum-scale "1.0")) "Prevent zooming out past default size")
- :config (advice-add 'org-html-latex-environment :around #'org-html-latex-environment-pandoc-fix))
+(use-package ox-html
+ :demand t
+ :after (org htmlize)
+ :custom
+ (org-html-htmlize-output-type 'css "allow styling from CSS file")
+ (org-html-with-latex 'html "let my html handler handle latex")
+ (org-html-mathjax-options nil "disable mathjax, use MathML")
+ (org-html-mathjax-template "" "disable mathjax, use MathML")
+ (org-html-head-include-default-style nil "use my own css for everything")
+ (org-html-head-include-scripts nil "use my own js for everything")
+ (org-html-postamble (concat "Copyright © 2024 " system-fullname) "set copyright notice on bottom of site")
+ (org-html-divs '((preamble "header" "preamble")
+ (content "main" "content")
+ (postamble "footer" "postamble")) "semantic html exports")
+ (org-html-viewport '((width "device-width")
+ (initial-scale "1.0")
+ (minimum-scale "1.0")) "Prevent zooming out past default size")
+ :config (advice-add 'org-html-latex-environment :around #'org-html-latex-environment-pandoc-fix))
- (use-package ox-rss
- :after org
- :demand t)
+(use-package ox-rss
+ :after org
+ :demand t)
- (use-package ox-publish
- :demand t
- :after (org f s dash ox-html ox-rss)
- :custom
- (org-publish-project-alist
- `(("website-org"
- :base-directory "~/monorepo"
- :base-extension "org"
- :exclude "nix/README\\.org\\|blog/rss\\.org\\|result/.*\\|nix/.*"
- :publishing-directory "~/website_html"
- :with-author t
- :with-date t
- :with-broken-links t
- :language en
+(use-package ox-publish
+ :demand t
+ :after (org f s dash ox-html ox-rss)
+ :custom
+ (org-publish-project-alist
+ `(("website-org"
+ :base-directory "~/monorepo"
+ :base-extension "org"
+ :exclude "nix/README\\.org\\|blog/rss\\.org\\|result/.*\\|nix/.*"
+ :publishing-directory "~/website_html"
+ :with-author t
+ :with-date t
+ :with-broken-links t
+ :language en
- :recursive t
- :publishing-function org-html-publish-to-html
- :headline-levels 4
- :html-footnotes-section "<div id=\"footnotes\"><hr><div id=\"text-footnotes\"><span class=\"footnotes-label-hidden\">%s</span>%s</div></div>"
- :html-head ,(concat "<meta name=\"theme-color\" content=\"#ffffff\">\n<link rel=\"preload\" href=\"/fonts/Inconsolata-Medium.woff2\" as=\"font\" type=\"font/woff2\" crossorigin>\n<meta name=\"theme-color\" content=\"#ffffff\">\n<link rel=\"preload\" href=\"/fonts/Lora-Medium.woff2\" as=\"font\" type=\"font/woff2\" crossorigin>\n<link rel=\"preload\" href=\"/fonts/CormorantGaramond-Bold.woff2\" as=\"font\" type=\"font/woff2\" crossorigin>\n<link rel=\"preload\" href=\"/fonts/CormorantGaramond-Medium.woff2\" as=\"font\" type=\"font/woff2\" crossorigin>\n<link rel=\"manifest\" href=\"/site.webmanifest\">\n<link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/favicon-16x16.png\">\n<link rel=\"mask-icon\" href=\"/safari-pinned-tab.svg\" color=\"#5bbad5\">\n<link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/favicon-32x32.png\">\n<link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"/apple-touch-icon.png\"><meta name=\"msapplication-TileColor\" content=\"#da532c\">\n"
- "<style>"
- (->> (create-htmlize-css)
- (s-replace-regexp "<style[^>]*>" "")
- (s-replace "</style>" "")
- (s-replace "<![CDATA[/*><![CDATA[/*>\n" "")
- (s-replace "/*]]>*/-->" "")
- (s-trim)
- (minify-css))
- (f-read-text "~/monorepo/style.css" 'utf-8)
- "</style>")
- :html-preamble t
- :html-preamble-format (("en" "<p class=\"preamble\"><a href=\"/index.html\">home</a> | <a href=\"./index.html\">section main page</a> | <a href=\"/blog/rss.xml\">rss feed</a></p><hr>"))
+ :recursive t
+ :publishing-function org-html-publish-to-html
+ :headline-levels 4
+ :html-footnotes-section "<div id=\"footnotes\"><hr><div id=\"text-footnotes\"><span class=\"footnotes-label-hidden\">%s</span>%s</div></div>"
+ :html-head ,(concat "<link rel=\"alternate\" type=\"application/rss+xml\" title=\"RSS Feed\" href=\"/blog/rss.xml\"><meta name=\"theme-color\" content=\"#ffffff\">\n<link rel=\"preload\" href=\"/fonts/Inconsolata-Medium.woff2\" as=\"font\" type=\"font/woff2\" crossorigin>\n<meta name=\"theme-color\" content=\"#ffffff\">\n<link rel=\"preload\" href=\"/fonts/Lora-Medium.woff2\" as=\"font\" type=\"font/woff2\" crossorigin>\n<link rel=\"preload\" href=\"/fonts/CormorantGaramond-Bold.woff2\" as=\"font\" type=\"font/woff2\" crossorigin>\n<link rel=\"preload\" href=\"/fonts/CormorantGaramond-Medium.woff2\" as=\"font\" type=\"font/woff2\" crossorigin>\n<link rel=\"manifest\" href=\"/site.webmanifest\">\n<link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/favicon-16x16.png\">\n<link rel=\"mask-icon\" href=\"/safari-pinned-tab.svg\" color=\"#5bbad5\">\n<link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/favicon-32x32.png\">\n<link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"/apple-touch-icon.png\"><meta name=\"msapplication-TileColor\" content=\"#da532c\">\n"
+ "<style>"
+ (or (ignore-errors
+ (->> (create-htmlize-css)
+ (s-replace-regexp "<style[^>]*>" "")
+ (s-replace "</style>" "")
+ (s-replace "<![CDATA[/*><![CDATA[/*>\n" "")
+ (s-replace "/*]]>*/-->" "")
+ (s-trim)
+ (minify-css)))
+ "/* HTMLIZE FAILED TO LOAD - CHECK EMACS INIT ERRORS */")
+ (f-read-text "~/monorepo/style.css" 'utf-8)
+ "</style>")
+ :html-preamble t
+ :html-preamble-format (("en" "<p class=\"preamble\"><a href=\"/index.html\">home</a> | <a href=\"./index.html\">section main page</a> | <a href=\"/blog/rss.xml\">rss feed</a></p><hr>"))
- ;; sitemap.html stuff
- :auto-sitemap t
- :sitemap-filename "sitemap.org"
- :sitemap-title "Site Index"
- :sitemap-style list
- :sitemap-sort-files anti-chronologically)
+ ;; sitemap.html stuff
+ :auto-sitemap t
+ :sitemap-filename "sitemap.org"
+ :sitemap-title "Site Index"
+ :sitemap-style list
+ :sitemap-sort-files anti-chronologically)
- ("website-blog-rss"
- :base-directory "~/monorepo/blog"
- :base-extension "org"
- :recursive nil
- :exclude "rss\\.org\\|index\\.org\\|404\\.org"
- :rss-extension "xml"
+ ("website-blog-rss"
+ :base-directory "~/monorepo/blog"
+ :base-extension "org"
+ :recursive nil
+ :exclude "rss\\.org\\|index\\.org\\|404\\.org"
+ :rss-extension "xml"
- :publishing-directory "~/website_html/blog"
- :publishing-function rp/org-rss-publish-to-rss
- :html-link-home "https://ret2pop.net/blog/"
- :html-link-use-abs-url t
+ :publishing-directory "~/website_html/blog"
+ :publishing-function rp/org-rss-publish-to-rss
+ :html-link-home "https://ret2pop.net/blog/"
+ :html-link-use-abs-url t
- ;; use custom sitemap functionality to publish rss feed
- :auto-sitemap t
- :sitemap-filename "rss.org"
- :sitemap-title "Blog Feed"
- :sitemap-style list
- :sitemap-sort-folders ignore
- :sitemap-sort-files anti-chronologically
- :sitemap-format-entry format-rss-feed-entry
- :sitemap-function format-rss-feed)
+ ;; use custom sitemap functionality to publish rss feed
+ :auto-sitemap t
+ :sitemap-filename "rss.org"
+ :sitemap-title "Blog Feed"
+ :sitemap-style list
+ :sitemap-sort-folders ignore
+ :sitemap-sort-files anti-chronologically
+ :sitemap-format-entry format-rss-feed-entry
+ :sitemap-function format-rss-feed)
- ("website-sitemap-xml"
- :base-directory "~/monorepo"
- :base-extension "org"
- :recursive t
- :exclude "nix/README\\.org\\|blog/rss\\.org"
- :publishing-directory "~/website_html"
- :publishing-function rp/org-sitemap-publish-function
- :auto-sitemap t
- :sitemap-filename "sitemap.xml"
- :sitemap-format-entry org-sitemap-format-entry-xml
- :sitemap-style list
- :sitemap-function org-sitemap-format-xml)
+ ("website-sitemap-xml"
+ :base-directory "~/monorepo"
+ :base-extension "org"
+ :recursive t
+ :exclude "nix/README\\.org\\|blog/rss\\.org"
+ :publishing-directory "~/website_html"
+ :publishing-function rp/org-sitemap-publish-function
+ :auto-sitemap t
+ :sitemap-filename "sitemap.xml"
+ :sitemap-format-entry org-sitemap-format-entry-xml
+ :sitemap-style list
+ :sitemap-function org-sitemap-format-xml)
- ("website-static"
- :base-directory "~/monorepo"
- :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf\\|ico\\|asc\\|pub\\|webmanifest\\|xml\\|svg\\|txt\\|webp\\|conf"
- :publishing-directory "~/website_html/"
- :recursive t
- :publishing-function org-publish-attachment)
+ ("website-static"
+ :base-directory "~/monorepo"
+ :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf\\|ico\\|asc\\|pub\\|webmanifest\\|xml\\|svg\\|txt\\|webp\\|conf"
+ :publishing-directory "~/website_html/"
+ :recursive t
+ :publishing-function org-publish-attachment)
- ("website"
- :auto-sitemap t
- :components ("website-org" "website-static" "website-blog-rss" "website-sitemap-xml")))
- "functions to publish website"))
+ ("website"
+ :auto-sitemap t
+ :components ("website-org" "website-static" "website-blog-rss" "website-sitemap-xml")))
+ "functions to publish website"))
#+end_src
As you can see, I only have one real entry in config here (I don't count requires even though
they have to be on the top)
@@ -712,6 +835,18 @@ Org superstar adds those nice looking utf-8 bullets:
:config
(global-org-modern-mode))
#+end_src
+** Notifications
+We use org-alert in order to give us notifications based on our org-agenda.
+#+begin_src emacs-lisp :tangle ../nix/init.el
+(use-package org-alert
+ :after (org ox-publish)
+ :custom
+ (alert-default-style 'libnotify)
+ (org-alert-interval 300)
+ (org-alert-notify-cutoff 10)
+ (org-alert-notify-after-event-cutoff 10)
+ :config (org-alert-enable))
+#+end_src
** LSP
We set up eglot, the LSP manager for emacs, now built in:
#+begin_src emacs-lisp :tangle ../nix/init.el
@@ -769,17 +904,39 @@ We want our emacs initialization to be pretty and display useful things.
(use-package dashboard
:after (projectile)
:custom
- (dashboard-banner-logo-title "Welcome, Commander!" "Set title for dashboard")
- (dashboard-icon-type 'nerd-icons "Use nerd icons")
- (dashboard-vertically-center-content t "Center content")
+ (dashboard-banner-logo-title "Introducing: Ret2pop" "Set title for dashboard")
+ (dashboard-startup-banner "/home/preston/monorepo/nix/data/logo.png")
+ (dashboard-icon-type 'all-the-icons "Use nerd icons")
+ (dashboard-center-content t "Center content")
(dashboard-set-init-info t)
+ (dashboard-set-heading-icons t)
+ (dashboard-set-file-icons t)
+
(dashboard-week-agenda t "Agenda in dashboard")
(dashboard-items '((recents . 5)
- (bookmarks . 5)
(projects . 5)
- (agenda . 5)
- (registers . 5)) "Look at some items")
- :config (unless noninteractive (dashboard-setup-startup-hook)))
+ (agenda . 5)) "Look at some items")
+ (dashboard-startupify-list '(dashboard-insert-banner
+ dashboard-insert-newline
+ dashboard-insert-banner-title
+ dashboard-insert-newline
+ dashboard-insert-navigator
+ dashboard-insert-newline
+ dashboard-insert-init-info
+ dashboard-insert-items
+ dashboard-insert-newline
+ dashboard-insert-footer))
+ :config
+ (unless noninteractive (dashboard-setup-startup-hook))
+
+ (my-fetch-weather-async)
+ (defvar my-weather-timer nil)
+ (when (timerp my-weather-timer)
+ (cancel-timer my-weather-timer))
+ (setq my-weather-timer (run-with-timer 900 900 #'my-fetch-weather-async))
+
+ (add-to-list 'dashboard-item-generators '(weather-clock . my-dashboard-insert-weather-clock))
+ (add-to-list 'dashboard-items '(weather-clock . 1)))
#+end_src
** Ivy
Ivy is a pretty cool general program for displaying stuff:
@@ -908,6 +1065,7 @@ emacs keybindings.
"o r s" '(elfeed :wk "rss feed")
"o a" '(org-agenda :wk "Open agenda")
"o w" '(eww :wk "web browser")
+ "o n" '(enwc :wk "NetworkManager Interface")
"m m" '(emms :wk "Music player")
"s m" '(proced :wk "System Manager")
"l p" '(list-processes :wk "List Emacs Processes")
@@ -1141,10 +1299,10 @@ elfeed to fetch feeds found on my website:
(use-package elfeed
:hook ((elfeed-search-mode . elfeed-update))
+ :general (:states 'normal :keymaps 'elfeed-search-mode-map "r" 'elfeed-update)
:custom
(elfeed-search-filter (format "@1-month-ago +unread !%s" (elfeed-final-filter elfeed-hn-filter-list)) "Only display unread articles from a month ago")
- (elfeed-curl-max-connections 8 "less max connections for less lag")
- :config (run-with-timer 0 (* 60 10) 'elfeed-update))
+ (elfeed-curl-max-connections 8 "less max connections for less lag"))
(use-package elfeed-org
:after (elfeed org)
@@ -1281,6 +1439,17 @@ Email in emacs can be done with Mu4e.
(use-package mu4e
:after smtpmail
+ :general
+ (:states '(normal motion) :keymaps 'mu4e-main-mode-map
+ "s" #'my-ivy-mu4e-search)
+
+ (:states '(normal motion) :keymaps 'mu4e-headers-mode-map
+ "s" #'my-ivy-mu4e-search
+ "/" #'my-mu4e-narrow-with-ivy)
+
+ (:states '(normal motion) :keymaps 'mu4e-thread-mode-map
+ "s" #'my-ivy-mu4e-search
+ "/" #'my-mu4e-narrow-with-ivy)
:hook
((mu4e-compose-mode . mml-secure-message-sign-pgpmime))
:custom
@@ -1297,6 +1466,7 @@ Email in emacs can be done with Mu4e.
(mu4e-compose-reply-ignore-address (list "no-?reply" system-email) "ignore my own address and noreply")
(mu4e-html2text-command "w3m -T text/html" "Use w3m to convert html to text")
(mu4e-update-interval 300 "Update duration")
+ (mu4e-completing-read-function 'ivy-completing-read)
(mu4e-headers-auto-update t "Auto-updates feed")
(mu4e-view-show-images t "Shows images")
(mu4e-compose-signature-auto-include nil)
diff --git a/config/nix.org b/config/nix.org
index 5690f7f..837d713 100644
--- a/config/nix.org
+++ b/config/nix.org
@@ -92,6 +92,10 @@ and now for the main flake:
url = "github:cachix/git-hooks.nix";
inputs.nixpkgs.follows = "nixpkgs";
};
+ catppuccin-qutebrowser = {
+ url = "github:catppuccin/qutebrowser";
+ flake = false;
+ };
};
outputs = {
@@ -2356,6 +2360,33 @@ We must put Nixpkgs in another configuration because we don't want to include it
};
}
#+end_src
+** QTile
+#+begin_src nix :tangle ../nix/modules/qtile.nix
+{ lib, config, ... }:
+{
+ services.xserver.windowManager.qtile = {
+ enable = lib.mkDefault config.monorepo.profiles.desktop.enable;
+
+ extraPackages = python3Packages: with python3Packages; [
+ qtile-extras
+ ];
+ };
+}
+#+end_src
+** Libinput
+#+begin_src nix :tangle ../nix/modules/libinput.nix
+{ lib, config, ... }:
+{
+ services.libinput = {
+ enable = lib.mkDefault config.monorepo.profiles.desktop.enable;
+ mouse = {
+ dev = "/dev/input/by-id/usb-047d_80fd-event-mouse";
+ scrollMethod = "button";
+ scrollButton = 276;
+ };
+ };
+}
+#+end_src
** Main Configuration
This is the backbone of the all the NixOS configurations, with all these options being shared
because they enhance security.
@@ -3352,7 +3383,7 @@ be straightforward.
#+end_src
*** QuteBrowser
#+begin_src nix :tangle ../nix/modules/home/qutebrowser.nix
-{ lib, config, ... }:
+{ lib, config, catppuccin-qutebrowser, ... }:
{
programs.qutebrowser = {
enable = lib.mkDefault config.monorepo.profiles.graphics.enable;
@@ -3365,7 +3396,27 @@ be straightforward.
};
settings = {
content.blocking.method = "both";
+ fonts.default_family = "Lora";
+ fonts.default_size = "12pt";
+
+ # Command/completion UI
+ fonts.statusbar = "12pt Lora";
+ fonts.completion.entry = "12pt Lora";
+ fonts.completion.category = "bold 12pt Lora";
+ fonts.prompts = "12pt Lora";
+
+ # Tabs
+ fonts.tabs.selected = "12pt Lora";
+ fonts.tabs.unselected = "12pt Lora";
+
+ # Hints
+ fonts.hints = "bold 12pt Lora";
};
+ extraConfig = (builtins.readFile "${catppuccin-qutebrowser}/setup.py") +
+''
+config.load_autoconfig()
+setup(c, "mocha", True)
+'';
};
}
#+end_src
@@ -3423,105 +3474,107 @@ as an org file which gets automatically tangled to an emacs-lisp file.
**** Emacs Packages
I want to separate out these packages so that my parent flake which builds my website has a list of my packages.
#+begin_src nix :tangle ../nix/modules/home/emacs-packages.nix
-epkgs: [
- epkgs.all-the-icons
- epkgs.agda2-mode
- epkgs.auctex
- epkgs.catppuccin-theme
- epkgs.company
- epkgs.company-box
- epkgs.company-solidity
- epkgs.counsel
- epkgs.centaur-tabs
- epkgs.dash
- epkgs.dashboard
- epkgs.doom-themes
- epkgs.doom-modeline
- epkgs.indent-bars
- epkgs.irony
- epkgs.elfeed
- epkgs.elfeed-org
- epkgs.elfeed-tube
- epkgs.elfeed-tube-mpv
- epkgs.elpher
- epkgs.ement
- epkgs.emmet-mode
- epkgs.emms
- epkgs.engrave-faces
- epkgs.enwc
- epkgs.evil
- epkgs.evil-collection
- epkgs.evil-commentary
- epkgs.evil-org
- epkgs.f
- epkgs.flycheck
- epkgs.geiser
- epkgs.geiser-chez
- epkgs.general
- epkgs.git-gutter
- epkgs.gptel
- epkgs.gruvbox-theme
- epkgs.haskell-mode
- epkgs.htmlize
- epkgs.idris-mode
- epkgs.irony-eldoc
- epkgs.ivy
- epkgs.ivy-posframe
- epkgs.latex-preview-pane
- epkgs.lsp-ivy
- epkgs.lsp-mode
- epkgs.lsp-haskell
- epkgs.lyrics-fetcher
- epkgs.mastodon
- epkgs.magit
- epkgs.magit-delta
- epkgs.mu4e
- epkgs.mixed-pitch
- epkgs.minuet
- epkgs.nix-mode
- epkgs.ox-rss
- epkgs.ob-nix
- epkgs.org-contrib
- epkgs.org-ql
- epkgs.org-super-agenda
- epkgs.org-fragtog
- epkgs.org-journal
- epkgs.org-modern
- epkgs.org-roam
- epkgs.org-roam-ui
- epkgs.page-break-lines
- epkgs.password-store
- epkgs.pdf-tools
- epkgs.pinentry
- epkgs.platformio-mode
- epkgs.projectile
- epkgs.rustic
- epkgs.s
- epkgs.solaire-mode
- epkgs.scad-mode
- epkgs.simple-httpd
- epkgs.solidity-flycheck
- epkgs.solidity-mode
- epkgs.sudo-edit
- epkgs.treemacs
- epkgs.treemacs-evil
- epkgs.treemacs-magit
- epkgs.treemacs-projectile
- epkgs.treemacs-all-the-icons
- epkgs.all-the-icons-ivy-rich
- epkgs.treesit-auto
- epkgs.typescript-mode
- epkgs.use-package
- epkgs.vterm
- epkgs.wgrep
- epkgs.web-mode
- epkgs.websocket
- epkgs.which-key
- epkgs.writegood-mode
- epkgs.writeroom-mode
- epkgs.yaml-mode
- epkgs.yasnippet
- epkgs.yasnippet-snippets
+epkgs: with epkgs; [
+ all-the-icons
+ agda2-mode
+ auctex
+ catppuccin-theme
+ company
+ company-box
+ company-solidity
+ counsel
+ centaur-tabs
+ dash
+ dashboard
+ doom-themes
+ doom-modeline
+ indent-bars
+ irony
+ elfeed
+ elfeed-org
+ elfeed-tube
+ elfeed-tube-mpv
+ elpher
+ ement
+ emmet-mode
+ emms
+ engrave-faces
+ enwc
+ evil
+ evil-collection
+ evil-commentary
+ evil-org
+ f
+ flycheck
+ geiser
+ geiser-chez
+ general
+ git-gutter
+ gptel
+ gruvbox-theme
+ haskell-mode
+ htmlize
+ idris-mode
+ irony-eldoc
+ ivy
+ ivy-posframe
+ latex-preview-pane
+ lsp-ivy
+ lsp-mode
+ lsp-haskell
+ lyrics-fetcher
+ mastodon
+ magit
+ magit-delta
+ mu4e
+ mixed-pitch
+ minuet
+ nix-mode
+ ox-rss
+ ob-nix
+ org-alert
+ org-contrib
+ org-ql
+ org-super-agenda
+ org-fragtog
+ org-journal
+ org-modern
+ org-roam
+ org-roam-ui
+ page-break-lines
+ password-store
+ pdf-tools
+ pinentry
+ platformio-mode
+ projectile
+ polymode
+ rustic
+ s
+ solaire-mode
+ scad-mode
+ simple-httpd
+ solidity-flycheck
+ solidity-mode
+ sudo-edit
+ treemacs
+ treemacs-evil
+ treemacs-magit
+ treemacs-projectile
+ treemacs-all-the-icons
+ all-the-icons-ivy-rich
+ treesit-auto
+ typescript-mode
+ use-package
+ vterm
+ wgrep
+ web-mode
+ websocket
+ which-key
+ writegood-mode
+ writeroom-mode
+ yaml-mode
+ yasnippet
+ yasnippet-snippets
]
#+end_src
*** Gammastep
@@ -3561,7 +3614,7 @@ declaratively, so in case element-desktop stops working because of lack of decla
settings = {
default_profile = "personal";
profiles.personal = {
- user_id = "${super.monorepo.vars.internetName}@matrix.${super.monorepo.vars.orgHost}";
+ user_id = "@${super.monorepo.vars.internetName}:matrix.${super.monorepo.vars.orgHost}";
};
image_preview.protocol = {
type = "kitty";
@@ -3641,208 +3694,6 @@ Make sure those are set correctly. I've set it to sign by default.
};
}
#+end_src
-*** Hyprland
-My compositor/window manager. This automatically starts on startup. Instructions on how
-to use this component will come soon.
-#+begin_src nix :tangle ../nix/modules/home/hyprland.nix
-{ lib, config, wallpapers, pkgs, scripts, ... }:
-{
- wayland.windowManager.hyprland = {
- enable = lib.mkDefault config.monorepo.profiles.hyprland.enable;
- package = pkgs.hyprland;
- xwayland.enable = true;
- systemd.enable = true;
- settings = {
- "$mod" = "SUPER";
- bezier = [
- "overshot, 0.05, 0.9, 0.1, 1.05"
- ];
- animation = [
- # "workspaces, 1, 10, overshot"
- "windows, 1, 2, default"
- "workspaces, 1, 2, default, slidefade 20%"
- ];
- exec-once = [
- "waybar"
- "swww-daemon --format xrgb"
- "sh -c 'swww img \"$(find ${wallpapers} -type f \\( -iname \"*.jpg\" -o -iname \"*.png\" \\) | shuf -n1)\"'"
- "fcitx5-remote -r"
- "fcitx5 -d --replace"
- "fcitx5-remote -r"
- "emacs"
- "qutebrowser"
- ];
- env = [
- "LIBVA_DRIVER_NAME,nvidia"
- "XDG_SESSION_TYPE,wayland"
- "GBM_BACKEND,nvidia-drm"
- "__GLX_VENDOR_LIBRARY_NAME,nvidia"
- "ELECTRON_OZONE_PLATFORM_HINT,auto"
- ];
-
- monitor = [
- "DP-4,2560x1440@165.000000,0x0,1"
- "Unknown-1,disable"
- ];
-
- layerrule = [
- {
- name = "waybar blur";
- "match:namespace" = "waybar";
- blur = "on";
- }
- ];
-
- windowrule = [
- {
- name = "emacs";
- "match:class" = "emacs";
- workspace = 1;
- }
- {
- name = "librewolf";
- "match:class" = "librewolf";
- workspace = 2;
- }
- {
- name = "qutebrowser";
- "match:class" = "qutebrowser";
- workspace = 2;
- }
- {
- name = "chromium-browser";
- "match:class" = "chromium-browser";
- workspace = 2;
- }
- {
- name = "signal";
- "match:class" = "signal";
- workspace = 3;
- }
- {
- name = "Element";
- "match:class" = "Element";
- workspace = 3;
- }
- {
- name = "pavucontrol";
- "match:class" = "pavucontrol";
- workspace = 4;
- }
- {
- name = "qpwgraph";
- "match:class" = "qpwgraph";
- workspace = 4;
- }
- {
- name = "mpv";
- "match:class" = "mpv";
- workspace = 4;
- }
- ];
-
- bind = [
- "$mod, F, exec, qutebrowser"
- "$mod, Return, exec, kitty"
- "$mod, E, exec, emacs"
- "$mod, B, exec, bitcoin-qt"
- "$mod, S, exec, pavucontrol"
- "$mod, M, exec, monero-wallet-gui"
- "$mod, V, exec, element-desktop"
- "$mod, C, exec, signal-desktop"
- "$mod, D, exec, wofi --show run"
- "$mod, P, exec, bash ${scripts}/powermenu.sh"
- "$mod, Q, killactive"
- "$mod SHIFT, H, movewindow, l"
- "$mod SHIFT, L, movewindow, r"
- "$mod SHIFT, K, movewindow, u"
- "$mod SHIFT, J, movewindow, d"
-
- "$mod SHIFT, T, togglefloating"
- "$mod SHIFT, F, fullscreen"
-
- "$mod, H, movefocus, l"
- "$mod, L, movefocus, r"
- "$mod, K, movefocus, u"
- "$mod, J, movefocus, d"
- ", XF86AudioPlay, exec, mpc toggle"
- ", Print, exec, grim"
-
- "$mod, right, resizeactive, 30 0"
- "$mod, left, resizeactive, -30 0"
- "$mod, up, resizeactive, 0 -30"
- "$mod, down, resizeactive, 0 30"
- ]
- ++ (
- builtins.concatLists (builtins.genList
- (
- x:
- let
- ws =
- let
- c = (x + 1) / 10;
- in
- builtins.toString (x + 1 - (c * 10));
- in
- [
- "$mod, ${ws}, workspace, ${toString (x + 1)}"
- "$mod SHIFT, ${ws}, movetoworkspace, ${toString (x + 1)}"
- ]
- )
- 10)
- );
- bindm = [
- "$mod, mouse:272, movewindow"
- "$mod, mouse:273, resizewindow"
- "$mod ALT, mouse:272, resizewindow"
- ];
- binde = [
- ", XF86AudioRaiseVolume, exec, wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+"
- ", XF86AudioLowerVolume, exec, wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%-"
- ", XF86AudioNext, exec, mpc next"
- ", XF86AudioPrev, exec, mpc prev"
- ", XF86MonBrightnessUp , exec, xbacklight -inc 10"
- ", XF86MonBrightnessDown, exec, xbacklight -dec 10"
- ];
- decoration = {
- blur = {
- enabled = true;
- size = 9;
- passes = 4;
- contrast = 0.8;
- brightness = 1.1;
- noise = 0.02;
- new_optimizations = true;
- ignore_opacity = true;
- xray = false;
- };
- rounding = 5;
- };
- input = {
- scroll_method = "on_button_down";
- scroll_button = 276;
- sensitivity = -0.5;
- kb_options = "caps:swapescape";
- repeat_delay = 300;
- repeat_rate = 50;
- natural_scroll = false;
- touchpad = {
- natural_scroll = true;
- disable_while_typing = true;
- tap-to-click = true;
- };
- };
- cursor = {
- no_hardware_cursors = true;
- };
- misc = {
- force_default_wallpaper = 0;
- disable_hyprland_logo = true;
- };
- };
- };
-}
-#+end_src
*** Kitty
I've set my terminal, kitty, to use catppuccin colors.
#+begin_src nix :tangle ../nix/modules/home/kitty.nix
@@ -3855,7 +3706,7 @@ I've set my terminal, kitty, to use catppuccin colors.
font_family = "Iosevka Nerd Font";
font_size = 14;
confirm_os_window_close = 0;
- background_opacity = "0.7";
+ background_opacity = "1";
# Catppuccin theme
foreground = "#cdd6f4";
background = "#1e1e2e";
@@ -3900,26 +3751,6 @@ I've set my terminal, kitty, to use catppuccin colors.
};
}
#+end_src
-*** Mako
-This is my notification system. My flake automatically fetches the notification sound, so you
-are all set from the get-go!
-#+begin_src nix :tangle ../nix/modules/home/mako.nix
-{ lib, config, sounds, ... }:
-{
- services.mako = {
- enable = lib.mkDefault config.monorepo.profiles.graphics.enable;
- settings = {
- on-notify = "exec mpv ${sounds}/polite.ogg --no-config --no-video";
- background-color = "#11111bf8";
- text-color = "#cdd6f4";
- border-color = "#89b4faff";
- border-radius = 1;
- font = "Fira Code 10";
- default-timeout = 3000;
- };
- };
-}
-#+end_src
*** Mbsync
Note that in order to use my email configuration, your imaps and smtps servers must be
encrypted. This module uses the ~vars.nix~ as well as the home ~default.nix~ options.
@@ -4051,7 +3882,6 @@ here:
profile = "gpu-hq";
force-window = true;
ytdl-format = "bestvideo+bestaudio";
- cache-default = 4000000;
};
};
}
@@ -4086,475 +3916,18 @@ here:
};
}
#+end_src
-*** Waybar
-This is the bar I use for my hyprland configuration. You will need to adjust the monitors field
-in the ~default.nix~ for it to really appear.
-#+begin_src nix :tangle ../nix/modules/home/waybar.nix
-{ lib, config, super, ... }:
-{
- programs.waybar = {
- enable = lib.mkDefault config.monorepo.profiles.hyprland.enable;
- style = ''
- ,* {
- border: none;
- border-radius: 0px;
- font-family: Iosevka Nerd Font, FontAwesome, Noto Sans CJK;
- font-size: 14px;
- font-style: normal;
- min-height: 0;
- }
-
- window#waybar {
- background: rgba(30, 30, 46, 0.5);
- border-bottom: 1px solid #45475a;
- color: #cdd6f4;
- }
-
- #workspaces {
- background: #45475a;
- margin: 5px 5px 5px 5px;
- padding: 0px 5px 0px 5px;
- border-radius: 16px;
- border: solid 0px #f4d9e1;
- font-weight: normal;
- font-style: normal;
- }
- #workspaces button {
- padding: 0px 5px;
- border-radius: 16px;
- color: #a6adc8;
- }
-
- #workspaces button.active {
- color: #f4d9e1;
- background-color: transparent;
- border-radius: 16px;
- }
-
- #workspaces button:hover {
- background-color: #cdd6f4;
- color: black;
- border-radius: 16px;
- }
-
- #custom-date, #clock, #battery, #pulseaudio, #network, #custom-randwall, #custom-launcher {
- background: transparent;
- padding: 5px 5px 5px 5px;
- margin: 5px 5px 5px 5px;
- border-radius: 8px;
- border: solid 0px #f4d9e1;
- }
-
- #custom-date {
- color: #D3869B;
- }
-
- #custom-power {
- color: #24283b;
- background-color: #db4b4b;
- border-radius: 5px;
- margin-right: 10px;
- margin-top: 5px;
- margin-bottom: 5px;
- margin-left: 0px;
- padding: 5px 10px;
- }
-
- #tray {
- background: #45475a;
- margin: 5px 5px 5px 5px;
- border-radius: 16px;
- padding: 0px 5px;
- /*border-right: solid 1px #282738;*/
- }
-
- #clock {
- color: #cdd6f4;
- background-color: #45475a;
- border-radius: 0px 0px 0px 24px;
- padding-left: 13px;
- padding-right: 15px;
- margin-right: 0px;
- margin-left: 10px;
- margin-top: 0px;
- margin-bottom: 0px;
- font-weight: bold;
- /*border-left: solid 1px #282738;*/
- }
-
- #battery {
- color: #89b4fa;
- }
-
- #battery.charging {
- color: #a6e3a1;
- }
-
- #battery.warning:not(.charging) {
- background-color: #f7768e;
- color: #f38ba8;
- border-radius: 5px 5px 5px 5px;
- }
-
- #backlight {
- background-color: #24283b;
- color: #db4b4b;
- border-radius: 0px 0px 0px 0px;
- margin: 5px;
- margin-left: 0px;
- margin-right: 0px;
- padding: 0px 0px;
- }
-
- #network {
- color: #f4d9e1;
- border-radius: 8px;
- margin-right: 5px;
- }
-
- #pulseaudio {
- color: #f4d9e1;
- border-radius: 8px;
- margin-left: 0px;
- }
-
- #pulseaudio.muted {
- background: transparent;
- color: #928374;
- border-radius: 8px;
- margin-left: 0px;
- }
-
- #custom-randwall {
- color: #f4d9e1;
- border-radius: 8px;
- margin-right: 0px;
- }
-
- #custom-launcher {
- color: #e5809e;
- background-color: #45475a;
- border-radius: 0px 24px 0px 0px;
- margin: 0px 0px 0px 0px;
- padding: 0 20px 0 13px;
- /*border-right: solid 1px #282738;*/
- font-size: 20px;
- }
-
- #custom-launcher button:hover {
- background-color: #FB4934;
- color: transparent;
- border-radius: 8px;
- margin-right: -5px;
- margin-left: 10px;
- }
-
- #custom-playerctl {
- background: #45475a;
- padding-left: 15px;
- padding-right: 14px;
- border-radius: 16px;
- /*border-left: solid 1px #282738;*/
- /*border-right: solid 1px #282738;*/
- margin-top: 5px;
- margin-bottom: 5px;
- margin-left: 0px;
- font-weight: normal;
- font-style: normal;
- font-size: 16px;
- }
-
- #custom-playerlabel {
- background: transparent;
- padding-left: 10px;
- padding-right: 15px;
- border-radius: 16px;
- /*border-left: solid 1px #282738;*/
- /*border-right: solid 1px #282738;*/
- margin-top: 5px;
- margin-bottom: 5px;
- font-weight: normal;
- font-style: normal;
- }
-
- #window {
- background: #45475a;
- padding-left: 15px;
- padding-right: 15px;
- border-radius: 16px;
- /*border-left: solid 1px #282738;*/
- /*border-right: solid 1px #282738;*/
- margin-top: 5px;
- margin-bottom: 5px;
- font-weight: normal;
- font-style: normal;
- }
-
- #custom-wf-recorder {
- padding: 0 20px;
- color: #e5809e;
- background-color: #1E1E2E;
- }
-
- #cpu {
- background-color: #45475a;
- /*color: #FABD2D;*/
- border-radius: 16px;
- margin: 5px;
- margin-left: 5px;
- margin-right: 5px;
- padding: 0px 10px 0px 10px;
- font-weight: bold;
- }
-
- #memory {
- background-color: #45475a;
- /*color: #83A598;*/
- border-radius: 16px;
- margin: 5px;
- margin-left: 5px;
- margin-right: 5px;
- padding: 0px 10px 0px 10px;
- font-weight: bold;
- }
-
- #disk {
- background-color: #45475a;
- /*color: #8EC07C;*/
- border-radius: 16px;
- margin: 5px;
- margin-left: 5px;
- margin-right: 5px;
- padding: 0px 10px 0px 10px;
- font-weight: bold;
- }
-
- #custom-hyprpicker {
- background-color: #45475a;
- /*color: #8EC07C;*/
- border-radius: 16px;
- margin: 5px;
- margin-left: 5px;
- margin-right: 5px;
- padding: 0px 11px 0px 9px;
- font-weight: bold;
- }
- '';
- settings = {
- mainBar = {
- layer = "top";
- position = "top";
- height = 50;
-
- output = super.monorepo.vars.monitors;
-
- modules-left = [ "hyprland/workspaces" ];
- modules-center = [ "hyprland/window" ];
- modules-right = [ "battery" "clock" ];
-
- battery = {
- format = "{icon} {capacity}%";
- format-icons = ["" "" "" "" "" ];
- };
-
- clock = {
- format = "⏰ {:%a %d, %b %H:%M}";
- };
- };
- };
- };
-}
-#+end_src
-*** Wofi
-This is a run launcher for wayland. I also use it for my powermenu.
-#+begin_src nix :tangle ../nix/modules/home/wofi.nix
-{ lib, config, ... }:
+*** QTile
+#+begin_src nix :tangle ../nix/modules/home/qtile.nix
+{ sounds, wallpapers, pkgs, ... }:
+let
+ qtilePaths = pkgs.writeText "qtile-paths.py" ''
+WALLPAPER = "${wallpapers}/pastel-city.png"
+SOUND = "${sounds}/nice.wav"
+ '';
+in
{
- programs.wofi = {
- enable = lib.mkDefault config.monorepo.profiles.graphics.enable;
- settings = {
- location = "bottom-right";
- allow_markup = true;
- show = "drun";
- width = 750;
- height = 400;
- always_parse_args = true;
- show_all = false;
- term = "kitty";
- hide_scroll = true;
- print_command = true;
- insensitive = true;
- prompt = "Run what, Commander?";
- columns = 2;
- };
-
- style = ''
- @define-color rosewater #f5e0dc;
- @define-color rosewater-rgb rgb(245, 224, 220);
- @define-color flamingo #f2cdcd;
- @define-color flamingo-rgb rgb(242, 205, 205);
- @define-color pink #f5c2e7;
- @define-color pink-rgb rgb(245, 194, 231);
- @define-color mauve #cba6f7;
- @define-color mauve-rgb rgb(203, 166, 247);
- @define-color red #f38ba8;
- @define-color red-rgb rgb(243, 139, 168);
- @define-color maroon #eba0ac;
- @define-color maroon-rgb rgb(235, 160, 172);
- @define-color peach #fab387;
- @define-color peach-rgb rgb(250, 179, 135);
- @define-color yellow #f9e2af;
- @define-color yellow-rgb rgb(249, 226, 175);
- @define-color green #a6e3a1;
- @define-color green-rgb rgb(166, 227, 161);
- @define-color teal #94e2d5;
- @define-color teal-rgb rgb(148, 226, 213);
- @define-color sky #89dceb;
- @define-color sky-rgb rgb(137, 220, 235);
- @define-color sapphire #74c7ec;
- @define-color sapphire-rgb rgb(116, 199, 236);
- @define-color blue #89b4fa;
- @define-color blue-rgb rgb(137, 180, 250);
- @define-color lavender #b4befe;
- @define-color lavender-rgb rgb(180, 190, 254);
- @define-color text #cdd6f4;
- @define-color text-rgb rgb(205, 214, 244);
- @define-color subtext1 #bac2de;
- @define-color subtext1-rgb rgb(186, 194, 222);
- @define-color subtext0 #a6adc8;
- @define-color subtext0-rgb rgb(166, 173, 200);
- @define-color overlay2 #9399b2;
- @define-color overlay2-rgb rgb(147, 153, 178);
- @define-color overlay1 #7f849c;
- @define-color overlay1-rgb rgb(127, 132, 156);
- @define-color overlay0 #6c7086;
- @define-color overlay0-rgb rgb(108, 112, 134);
- @define-color surface2 #585b70;
- @define-color surface2-rgb rgb(88, 91, 112);
- @define-color surface1 #45475a;
- @define-color surface1-rgb rgb(69, 71, 90);
- @define-color surface0 #313244;
- @define-color surface0-rgb rgb(49, 50, 68);
- @define-color base #1e1e2e;
- @define-color base-rgb rgb(30, 30, 46);
- @define-color mantle #181825;
- @define-color mantle-rgb rgb(24, 24, 37);
- @define-color crust #11111b;
- @define-color crust-rgb rgb(17, 17, 27);
-
- ,* {
- font-family: 'Iosevka Nerd Font', monospace;
- font-size: 14px;
- }
-
- /* Window */
- window {
- margin: 0px;
- padding: 10px;
- border: 0.16em solid @lavender;
- border-radius: 0.1em;
- background-color: @base;
- animation: slideIn 0.5s ease-in-out both;
- }
-
- /* Slide In */
- @keyframes slideIn {
- 0% {
- opacity: 0;
- }
-
- 100% {
- opacity: 1;
- }
- }
-
- /* Inner Box */
- #inner-box {
- margin: 5px;
- padding: 10px;
- border: none;
- background-color: @base;
- animation: fadeIn 0.5s ease-in-out both;
- }
-
- /* Fade In */
- @keyframes fadeIn {
- 0% {
- opacity: 0;
- }
-
- 100% {
- opacity: 1;
- }
- }
-
- /* Outer Box */
- #outer-box {
- margin: 5px;
- padding: 10px;
- border: none;
- background-color: @base;
- }
-
- /* Scroll */
- #scroll {
- margin: 0px;
- padding: 10px;
- border: none;
- background-color: @base;
- }
-
- /* Input */
- #input {
- margin: 5px 20px;
- padding: 10px;
- border: none;
- border-radius: 0.1em;
- color: @text;
- background-color: @base;
- animation: fadeIn 0.5s ease-in-out both;
- }
-
- #input image {
- border: none;
- color: @red;
- }
-
- #input * {
- outline: 4px solid @red!important;
- }
-
- /* Text */
- #text {
- margin: 5px;
- border: none;
- color: @text;
- animation: fadeIn 0.5s ease-in-out both;
- }
-
- #entry {
- background-color: @base;
- }
-
- #entry arrow {
- border: none;
- color: @lavender;
- }
-
- /* Selected Entry */
- #entry:selected {
- border: 0.11em solid @lavender;
- }
-
- #entry:selected #text {
- color: @mauve;
- }
-
- #entry:drop(active) {
- background-color: @lavender!important;
- }
- '';
- };
+ xdg.configFile."qtile/config.py".source = ../../qtile/config.py;
+ xdg.configFile."qtile/paths.py".source = qtilePaths;
}
#+end_src
*** yt-dlp
@@ -4643,7 +4016,7 @@ standard.
};
loginExtra = ''
if [[ "$(tty)" = "/dev/tty1" ]]; then
- exec start-hyprland
+ exec qtile start -b wayland
fi
'';
};
@@ -4816,17 +4189,17 @@ for these configurations.
'';
};
};
- xdg.mimeApps = {
+xdg.mimeApps = {
enable = lib.mkDefault config.monorepo.profiles.graphics.enable;
defaultApplications = {
"x-scheme-handler/mailto" = "emacsclient-mail.desktop";
- "text/html" = "qutebrowser.desktop";
- "text/xml" = "qutebrowser.desktop";
- "application/xhtml+xml" = "qutebrowser.desktop";
- "x-scheme-handler/http" = "qutebrowser.desktop";
- "x-scheme-handler/https" = "qutebrowser.desktop";
- "x-scheme-handler/about" = "qutebrowser.desktop";
- "x-scheme-handler/unknown" = "qutebrowser.desktop";
+ "text/html" = "org.qutebrowser.qutebrowser.desktop";
+ "text/xml" = "org.qutebrowser.qutebrowser.desktop";
+ "application/xhtml+xml" = "org.qutebrowser.qutebrowser.desktop";
+ "x-scheme-handler/http" = "org.qutebrowser.qutebrowser.desktop";
+ "x-scheme-handler/https" = "org.qutebrowser.qutebrowser.desktop";
+ "x-scheme-handler/about" = "org.qutebrowser.qutebrowser.desktop";
+ "x-scheme-handler/unknown" = "org.qutebrowser.qutebrowser.desktop";
};
};
diff --git a/config/qtile.org b/config/qtile.org
new file mode 100644
index 0000000..0f5c847
--- /dev/null
+++ b/config/qtile.org
@@ -0,0 +1,421 @@
+#+title: QTile Configuration
+#+author: Preston Pan
+#+description: My personal qtile configuration to be used with NixOS
+#+date: [2026-03-25 Wed]
+#+language: en
+
+#+OPTIONS: broken-links:t
+#+PROPERTY: header-args :tangle yes :comments link
+
+* Introduction
+This is a QTile configuration meant to be a monolithic configuration of QTile along with widgets i.e. run launcher, bar, and notification panel.
+This enables the window manager to be integrated with these things entirely, making for a unified experience in terms of configuration, styling,
+and functionality.
+
+This configuration imports ~WALLPAPER~ and ~SOUND~ from my [[file:./nix.org][NixOS Configuration]], and therefore if you use this standalone you must replace those variables.
+* Imports
+We start with imports:
+#+begin_src python :tangle ../nix/qtile/config.py
+from paths import WALLPAPER, SOUND
+from libqtile import bar, layout, widget, qtile
+from libqtile.config import Key, Group, Screen, Click, Drag, Match
+from libqtile.lazy import lazy
+from libqtile.backend.wayland import InputConfig
+from qtile_extras.layout.decorations import RoundedCorners
+
+import re
+#+end_src
+We're using wayland because it's better.
+* Config
+#+begin_src python :tangle ../nix/qtile/config.py
+
+mod = "mod4"
+terminal = "kitty"
+wallpaper = WALLPAPER
+
+colors = {
+ "rosewater": "#f5e0dc",
+ "flamingo": "#f2cdcd",
+ "pink": "#f5c2e7",
+ "mauve": "#cba6f7",
+ "red": "#f38ba8",
+ "maroon": "#eba0ac",
+ "peach": "#fab387",
+ "yellow": "#f9e2af",
+ "green": "#a6e3a1",
+ "teal": "#94e2d5",
+ "sky": "#89dceb",
+ "sapphire": "#74c7ec",
+ "blue": "#89b4fa",
+ "lavender": "#b4befe",
+ "text": "#cdd6f4",
+ "subtext1": "#bac2de",
+ "subtext0": "#a6adc8",
+ "overlay2": "#9399b2",
+ "overlay1": "#7f849c",
+ "overlay0": "#6c7086",
+ "surface2": "#585b70",
+ "surface1": "#45475a",
+ "surface0": "#313244",
+ "base": "#1e1e2e",
+ "mantle": "#181825",
+ "crust": "#11111b",
+}
+
+workspace_keys = {
+ "1": "1",
+ "2": "2",
+ "3": "3",
+ "4": "4",
+ "5": "5",
+ "6": "6",
+ "7": "7",
+ "8": "8",
+ "9": "9",
+}
+
+groups = [
+ Group("1", matches=[Match(wm_class=re.compile(r"^emacs$", re.IGNORECASE))]),
+ Group("2", matches=[Match(wm_class=re.compile(r"(qutebrowser|org\.qutebrowser\.qutebrowser)", re.IGNORECASE))]),
+ Group(
+ "3",
+ matches=[
+ Match(wm_class=re.compile(r"^signal.*", re.IGNORECASE)),
+ Match(wm_class=re.compile(r"^element.*", re.IGNORECASE)),
+ ],
+ ),
+ Group("4", matches=[Match(wm_class=re.compile(r"(pavucontrol|org\.pulseaudio\.pavucontrol)", re.IGNORECASE))]),
+ Group("5"),
+ Group("6"),
+ Group("7"),
+ Group("8"),
+ Group("9"),
+]
+
+wl_input_rules = {
+ "type:keyboard": InputConfig(
+ kb_options="caps:escape",
+ kb_repeat_rate=50,
+ kb_repeat_delay=250,
+ ),
+
+ "type:pointer": InputConfig(
+ scroll_method="on_button_down",
+ scroll_button=276, # Your exact trackball button code
+ ),
+}
+
+class QuietBattery(widget.Battery):
+ def poll(self):
+ try:
+ status = self._battery.update_status()
+ except RuntimeError:
+ return ""
+ return self.build_string(status)
+
+def logout():
+ qtile.stop()
+
+
+def reboot():
+ qtile.spawn("systemctl reboot")
+
+
+def shutdown():
+ qtile.spawn("systemctl poweroff")
+
+
+def workspace_bindings():
+ bindings = []
+ for group_name, key_name in workspace_keys.items():
+ bindings.append(Key([mod], key_name, lazy.group[group_name].toscreen()))
+ bindings.append(Key([mod, "shift"], key_name, lazy.window.togroup(group_name)))
+ return bindings
+
+
+keys = [
+ # apps / session
+ Key([mod], "Return", lazy.spawn(terminal)),
+ Key([mod], "d", lazy.spawncmd()),
+ Key([mod], "q", lazy.window.kill()),
+ Key([mod], "f", lazy.window.toggle_fullscreen()),
+ Key([mod], "Tab", lazy.next_layout()),
+ Key([mod, "control"], "r", lazy.reload_config()),
+ Key([mod], "t", lazy.window.toggle_floating()),
+
+ # focus
+ Key([mod], "h", lazy.layout.left()),
+ Key([mod], "j", lazy.layout.down()),
+ Key([mod], "k", lazy.layout.up()),
+ Key([mod], "l", lazy.layout.right()),
+
+ # move windows
+ Key([mod, "shift"], "h", lazy.layout.shuffle_left()),
+ Key([mod, "shift"], "j", lazy.layout.shuffle_down()),
+ Key([mod, "shift"], "k", lazy.layout.shuffle_up()),
+ Key([mod, "shift"], "l", lazy.layout.shuffle_right()),
+
+ # resize windows
+ Key([mod, "control"], "h", lazy.layout.grow_left()),
+ Key([mod, "control"], "j", lazy.layout.grow_down()),
+ Key([mod, "control"], "k", lazy.layout.grow_up()),
+ Key([mod, "control"], "l", lazy.layout.grow_right()),
+ Key([mod], "n", lazy.layout.normalize()),
+
+ # layout helpers
+ Key([mod], "space", lazy.layout.next()),
+ Key([mod, "shift"], "space", lazy.layout.toggle_split()),
+
+ # session shortcuts
+ Key([mod, "shift"], "q", lazy.shutdown()),
+ Key([mod, "control"], "Delete", lazy.spawn("systemctl reboot")),
+ Key([mod, "shift"], "Delete", lazy.spawn("systemctl poweroff")),
+
+ # app launchers
+ Key([mod], "e", lazy.spawn("emacs")),
+ Key([mod], "w", lazy.spawn("qutebrowser")),
+ Key([mod], "c", lazy.spawn("signal-desktop")),
+ Key([mod], "v", lazy.spawn("element-desktop")),
+ Key([mod], "s", lazy.spawn("pavucontrol")),
+
+ Key([], "XF86AudioPlay", lazy.spawn("mpc toggle")),
+ Key([], "XF86AudioNext", lazy.spawn("mpc next")),
+ Key([], "XF86AudioPrev", lazy.spawn("mpc prev")),
+ Key([], "XF86AudioStop", lazy.spawn("mpc stop")),
+
+ Key([], "XF86AudioRaiseVolume", lazy.spawn("wpctl set-volume -l 1.0 @DEFAULT_AUDIO_SINK@ 5%+")),
+ Key([], "XF86AudioLowerVolume", lazy.spawn("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-")),
+ Key([], "XF86AudioMute", lazy.spawn("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle")),
+ Key([], "Print", lazy.spawn("sh -c 'grim ~/screenshot-$(date +%Y%m%d-%H%M%S).png'")),
+] + workspace_bindings()
+
+layouts = [
+ layout.Columns(
+ border_focus=colors["blue"],
+ border_normal=colors["surface0"],
+
+ border_focus_stack=colors["mauve"],
+ border_normal_stack=colors["surface1"],
+
+ border_width=3,
+ margin=8,
+ insert_position=1,
+ ),
+ layout.Max(
+ border_focus=colors["blue"],
+ border_normal=colors["surface0"],
+ border_width=3,
+ margin=8,
+ ),
+]
+
+widget_defaults = {
+ "font": "Iosevka Nerd Font",
+ "fontsize": 13,
+ "padding": 6,
+ "background": colors["mantle"],
+ "foreground": colors["text"],
+}
+extension_defaults = widget_defaults.copy()
+
+mouse = [
+ Drag(
+ [mod],
+ "Button1",
+ lazy.window.set_position_floating(),
+ start=lazy.window.get_position(),
+ ),
+ Drag(
+ [mod],
+ "Button3",
+ lazy.window.set_size_floating(),
+ start=lazy.window.get_size(),
+ ),
+ Click(
+ [mod],
+ "Button2",
+ lazy.window.bring_to_front(),
+ ),
+]
+
+
+def segment_icon(text, color, background=None, padding=8, font=None, fontsize=None):
+ return widget.TextBox(
+ text=text,
+ foreground=color,
+ background=background or colors["surface0"],
+ padding=padding,
+ font=font or "Iosevka Nerd Font",
+ fontsize=fontsize,
+ )
+
+
+def segment_sep(padding=6):
+ return widget.Sep(
+ linewidth=0,
+ padding=padding,
+ background=colors["mantle"],
+ )
+
+
+power_widget = widget.WidgetBox(
+ text_closed="󰐥",
+ text_open="󰐥",
+ close_button_location="right",
+ background=colors["mantle"],
+ font="Iosevka Nerd Font",
+ widgets=[
+ widget.TextBox(
+ text=" 󰑐 ",
+ foreground=colors["blue"],
+ background=colors["surface0"],
+ padding=8,
+ font="Iosevka Nerd Font",
+ mouse_callbacks={"Button1": reboot},
+ ),
+ widget.TextBox(
+ text=" 󰍃 ",
+ foreground=colors["mauve"],
+ background=colors["surface0"],
+ padding=8,
+ font="Iosevka Nerd Font",
+ mouse_callbacks={"Button1": logout},
+ ),
+ widget.TextBox(
+ text=" 󰐥 ",
+ foreground=colors["red"],
+ background=colors["surface0"],
+ padding=8,
+ font="Iosevka Nerd Font",
+ mouse_callbacks={"Button1": shutdown},
+ ),
+ ],
+)
+
+screens = [
+ Screen(
+ wallpaper=wallpaper,
+ wallpaper_mode="fill",
+ top=bar.Bar(
+ [
+ widget.GroupBox(
+ font="Iosevka Nerd Font",
+ fontsize=13,
+ background=colors["mantle"],
+ active=colors["text"],
+ inactive=colors["overlay0"],
+ highlight_method="line",
+ highlight_color=[colors["mantle"], colors["mantle"]],
+ this_current_screen_border=colors["lavender"],
+ other_current_screen_border=colors["blue"],
+ this_screen_border=colors["surface2"],
+ other_screen_border=colors["surface1"],
+ urgent_border=colors["red"],
+ urgent_text=colors["red"],
+ borderwidth=2,
+ rounded=False,
+ disable_drag=True,
+ spacing=8,
+ padding_x=8,
+ padding_y=5,
+ margin_y=2,
+ margin_x=0,
+ ),
+ widget.Spacer(length=10),
+ widget.Prompt(
+ name="prompt",
+ prompt="❯ ",
+ cursor_color=colors["blue"],
+ foreground=colors["text"],
+ background=colors["surface0"],
+ padding=10,
+ font="Iosevka Nerd Font",
+ ),
+ widget.Spacer(),
+
+ segment_icon("󰖙", colors["blue"]),
+ widget.Wttr(
+ background=colors["surface0"],
+ format="%l: %t %C",
+ update_interval=1800,
+ font="Iosevka Nerd Font",
+ foreground=colors["teal"],
+ ),
+ segment_sep(),
+
+ segment_icon("󰎆", colors["green"]),
+ widget.Mpd2(
+ background=colors["surface0"],
+ foreground=colors["green"],
+ status_format="{play_status} {artist} - {title}",
+ idle_format=" idle",
+ idle_message="idle",
+ max_chars=40,
+ padding=10,
+ hide_crash=True,
+ font="Iosevka Nerd Font",
+ ),
+ segment_sep(),
+
+ segment_icon("󰂄", colors["yellow"]),
+ QuietBattery(
+ background=colors["surface0"],
+ foreground=colors["yellow"],
+ format="{percent:2.0%}",
+ charge_char="󰂄",
+ discharge_char="󰁹",
+ full_char="󰁹",
+ empty_char="󰂎",
+ update_interval=30,
+ padding=10,
+ font="Iosevka Nerd Font",
+ ),
+ segment_sep(),
+
+ segment_icon("󰂚", colors["peach"]),
+ widget.Notify(
+ foreground=colors["peach"],
+ background=colors["surface0"],
+ default_timeout=10,
+ audiofile=SOUND,
+ padding=10,
+ font="Iosevka Nerd Font",
+ ),
+ segment_sep(),
+
+ segment_icon("󰃭", colors["lavender"]),
+ widget.Clock(
+ format="%a %d %b",
+ foreground=colors["lavender"],
+ background=colors["surface0"],
+ padding=10,
+ font="Lora",
+ ),
+ segment_icon("󰥔", colors["blue"]),
+ widget.Clock(
+ format="%H:%M",
+ foreground=colors["blue"],
+ background=colors["surface0"],
+ padding=10,
+ font="Iosevka Nerd Font",
+ ),
+
+ widget.Spacer(length=10),
+ power_widget,
+ widget.Spacer(length=10),
+ ],
+ 30,
+ margin=[8, 10, 0, 10],
+ background=colors["mantle"],
+ opacity=0.97,
+ ),
+ ),
+]
+
+follow_mouse_focus = True
+bring_front_click = False
+cursor_warp = False
+auto_fullscreen = True
+auto_minimize = True
+wmname = "Qtile"
+#+end_src
diff --git a/config/qutebrowser.org b/config/qutebrowser.org
index 2a3e180..da7dccb 100644
--- a/config/qutebrowser.org
+++ b/config/qutebrowser.org
@@ -5,101 +5,8 @@
#+auto_tangle: t
* Configuration
-** Imports
-We start with imports:
+This is my qutebrowser configuration, meant to be used with my [[file:./nix.org][NixOS Configuration]], and is extra configuration on top of what I have there.
#+begin_src python :tangle ../nix/qutebrowser.py
-from pathlib import Path
-from urllib.parse import urlparse
-# import catppuccin
-#+end_src
-We import pathlib to get our home directory.
-** Theming
-I am experimenting with many themes right now, and one of them is the [[https://github.com/gicrisf/qute-city-lights][city-lights]] theme.
-Another one I have used is the [[https://github.com/catppuccin/catppuccin][catppuccin]] theme.
-#+begin_src python :tangle config.py
-# config.source('themes/qute-city-lights/city-lights-theme.py')
-config.source('gruvbox.py')
-#+end_src
-** Variables
-We need the location of the home directory.
-#+begin_src python :tangle config.py
-home = str(Path.home())
-#+end_src
-** Fonts
-We are using Fira Code for the font in all the non-webpage ui elements.
-#+begin_src python :tangle config.py
-c.fonts.hints = '14pt FiraCode Nerd Font'
-c.fonts.keyhint = '14pt FiraCode Nerd Font'
-c.fonts.prompts = '14pt FiraCode Nerd Font'
-c.fonts.downloads = '14pt FiraCode Nerd Font'
-c.fonts.statusbar = '14pt FiraCode Nerd Font'
-c.fonts.contextmenu = '14pt FiraCode Nerd Font'
-c.fonts.messages.info = '14pt FiraCode Nerd Font'
-c.fonts.debug_console = '14pt FiraCode Nerd Font'
-c.fonts.completion.entry = '14pt FiraCode Nerd Font'
-c.fonts.completion.category = '14pt FiraCode Nerd Font'
-c.fonts.tabs.selected = '14pt FiraCode Nerd Font'
-c.fonts.tabs.unselected = '14pt FiraCode Nerd Font'
-#+end_src
-** Search Engine
-We should set our default search engine to google because duckduckgo is useless, and
-we should give other search engine bang options.
-#+begin_src python :tangle config.py
-c.url.searchengines = {
- 'DEFAULT': 'https://google.com/search?hl=en&q={}',
- '!a': 'https://www.amazon.com/s?k={}',
- '!d': 'https://duckduckgo.com/?ia=web&q={}',
- '!dd': 'https://thefreedictionary.com/{}',
- '!e': 'https://www.ebay.com/sch/i.html?_nkw={}',
- '!fb': 'https://www.facebook.com/s.php?q={}',
- '!gh': 'https://github.com/search?o=desc&q={}&s=stars',
- '!gist': 'https://gist.github.com/search?q={}',
- '!gi': 'https://www.google.com/search?tbm=isch&q={}&tbs=imgo:1',
- '!gn': 'https://news.google.com/search?q={}',
- '!ig': 'https://www.instagram.com/explore/tags/{}',
- '!m': 'https://www.google.com/maps/search/{}',
- '!p': 'https://pry.sh/{}',
- '!r': 'https://www.reddit.com/search?q={}',
- '!sd': 'https://slickdeals.net/newsearch.php?q={}&searcharea=deals&searchin=first',
- '!t': 'https://www.thesaurus.com/browse/{}',
- '!tw': 'https://twitter.com/search?q={}',
- '!w': 'https://en.wikipedia.org/wiki/{}',
- '!yelp': 'https://www.yelp.com/search?find_desc={}',
- '!yt': 'https://www.youtube.com/results?search_query={}'
-}
-#+end_src
-** Start Page
-Set the default start page to my own website.
-#+begin_src python :tangle config.py
-c.url.start_pages = ["file:///home/preston/website_html/index.html"]
-c.url.default_page = "file:///home/preston/website_html/index.html"
-#+end_src
-** Keybindings
-Now we define our keybindings for useful programs while browsing:
-#+begin_src python :tangle config.py
-config.bind('xm', 'hint links spawn mpv {hint-url}')
-config.bind('xy', 'hint links spawn yt-dlp {hint-url} -o "~/videos/youtube/%(title)s.%(ext)s"')
-config.bind('xr', 'hint links spawn bash -c "echo \'*** {hint-url}\' >> ~/org/elfeed.org"')
-config.bind('xj', 'spawn bash -c "echo {url} >> ~/.config/qutebrowser/js_blacklist.txt"')
-#+end_src
-** Paywall Bypassing
-Sometimes websites like the New York Times try to make money. I won't let that happen.
-#+begin_src python :tangle config.py
-with open(f"{home}/.config/qutebrowser/js_blacklist.txt") as f:
- js_blacklist = f.read().splitlines()
-
-for item in js_blacklist:
- domain = urlparse(item).netloc
- config.set('content.javascript.enabled', False, f"*://{domain}/*")
- config.set('content.javascript.enabled', False, f"*://www.{domain}/*")
-#+end_src
-** Misc.
-Doing mundane things like setting the downloads directory to not use an upper case letter.
-#+begin_src python :tangle config.py
-c.downloads.location.directory = "~/Downloads"
-#+end_src
-** End of Config
-#+begin_src python :tangle config.py
-config.load_autoconfig()
-# catppuccin.setup(c, 'mocha', False)
+config.bind(",m", "spawn mpv {url}")
+config.bind(",M", "hint links spawn mpv {hint-url}")
#+end_src
diff --git a/journal/20260324.org b/journal/20260324.org
new file mode 100644
index 0000000..f8cf22f
--- /dev/null
+++ b/journal/20260324.org
@@ -0,0 +1,10 @@
+#+TITLE: Daily Journal
+#+STARTUP: showeverything
+#+DESCRIPTION: My daily journal entry
+#+AUTHOR: Preston Pan
+#+date: 2026-03-24
+#+options: broken-links:t
+* Tuesday, 24 March 2026
+** 22:46
+I made my Org mode workflow a lot better today, which is really great. I'm going to work on more mathematics, and perhaps rice my setup more as i
+think it would be worthwhile.
diff --git a/nix b/nix
-Subproject 6ce29a77b651e25d252007afb997cac3d493ecb
+Subproject a455ea205a3edf3910f82e7e442c8b6f5f805fb
diff --git a/robots.txt b/robots.txt
index eb05362..b7965e8 100644
--- a/robots.txt
+++ b/robots.txt
@@ -1,2 +1,4 @@
User-agent: *
Disallow:
+
+Sitemap: https://ret2pop.net/sitemap.xml