diff options
| author | cashmere <cashmere@autistici.org> | 2026-02-18 02:46:37 +0100 |
|---|---|---|
| committer | cashmere <cashmere@autistici.org> | 2026-02-18 02:46:37 +0100 |
| commit | 0c4ef333c7fff5764864f92c332fc1752ba393af (patch) | |
| tree | 5ddacc5915144480b371ac030d0b4a0af621cdc7 | |
| parent | 8a0fdace8a1328edd312b3da0ea51fd11948d661 (diff) | |
| download | emacs-0c4ef333c7fff5764864f92c332fc1752ba393af.tar.gz | |
sync config: org agenda rewrite, denote task->agenda, ui tweaks
- Rewrite org-agenda views: simplified to 3 views (today/week/projects)
- Rename denote 'task' tag to 'agenda' throughout
- Remove PLAN todo state, daily-review and reflection functions
- Consolidate capture templates into single definition block
- Add denote journal template auto-insertion
- Enable vertico-posframe
- Add eee.el terminal integration
- Switch font to Maple Mono NF at height 180
- Add org-clock and tmr segments to modeline
- Improve eldoc-and-jump for GUI and terminal
- Update noctalia theme
- Disable frame transparency
- Switch vterm shell to fish
- Tangle config.el to match config.org
| -rw-r--r-- | config.el | 891 | ||||
| -rw-r--r-- | config.org | 893 | ||||
| -rw-r--r-- | custom-vars.el | 30 | ||||
| -rw-r--r-- | themes/noctalia-theme.el | 337 |
4 files changed, 785 insertions, 1366 deletions
@@ -133,8 +133,8 @@ (scroll-bar-mode -1) (add-to-list 'default-frame-alist '(vertical-scroll-bars . nil)) (add-to-list 'default-frame-alist '(horizontal-scroll-bars . nil)) - (set-frame-parameter (selected-frame) 'alpha-background 80) - (add-to-list 'default-frame-alist '(alpha-background . 80)) + ;; (set-frame-parameter (selected-frame) 'alpha-background 80) + ;; (add-to-list 'default-frame-alist '(alpha-background . 80)) (global-hl-line-mode -1) ;; Disable highlight of the current line (global-auto-revert-mode 1) ;; Enable global auto-revert mode to keep buffers up to date with their corresponding files. (indent-tabs-mode -1) ;; Disable the use of tabs for indentation (use spaces instead). @@ -294,13 +294,13 @@ (setq dashboard-image-banner-max-height 256) (setq dashboard-bookmarks-show-base t) (setq dashboard-bookmarks-item-format "%s") - (setq dashboard-projects-backend 'projectile) + (setq dashboard-projects-backend 'project-el) (setq dashboard-items '((bookmarks . 5) (projects . 5) (recents . 5))) (setq dashboard-projects-switch-function (lambda (proj) - (projectile-switch-project-by-name proj))) + (project-switch-project proj))) (setq dashboard-center-content t) (setq dashboard-set-file-icons t) (setq dashboard-set-heading-icons t) @@ -571,40 +571,6 @@ (setq gptel-default-mode 'markdown-mode) (setq gptel-backends (list my/openrouter-backend))) -(use-package claude-code - :ensure t - :straight (:type git :host github :repo "stevemolitor/claude-code.el" :branch "main" :depth 1 - :files ("*.el" (:exclude "images/*"))) - :bind-keymap - ("C-c c" . claude-code-command-map) ;; or your preferred key - ;; Optionally define a repeat map so that "M" will cycle thru Claude auto-accept/plan/confirm modes after invoking claude-code-cycle-mode / C-c M. - :bind - (:repeat-map my-claude-code-map ("M" . claude-code-cycle-mode)) - :config - ;; optional IDE integration with Monet - (add-hook 'claude-code-process-environment-functions #'monet-start-server-function) - (monet-mode 1) - (setq claude-code-terminal-backend 'vterm) - (claude-code-mode)) - -(use-package inheritenv - :ensure t - :straight (:type git :host github :repo "purcell/inheritenv")) - -(use-package monet - :ensure t - :straight (:host github :repo "stevemolitor/monet")) - -(use-package agent-shell - :ensure t - ;; Add agent installation configs here - :config - (setq agent-shell-highlight-blocks t) - ) - -(use-package acp - :ensure t) - (use-package eldoc :straight nil :ensure t @@ -829,13 +795,13 @@ and convert it to Org using the pandoc utility." org-log-reschedule 'time org-log-into-drawer t org-enforce-todo-dependencies t) - + ;; Update TODO keywords to require notes for WAIT and CANCELLED ;; @ means: prompt for note when entering state ;; ! means: timestamp when leaving state (setq org-todo-keywords - '((sequence "TODO(t)" "NEXT(n)" "ACTIVE(a!)" "WAIT(w@/!)" "PLAN(p)" "|" "DONE(d!)" "CANCELLED(c@)"))) - + '((sequence "TODO(t)" "NEXT(n)" "ACTIVE(a!)" "WAIT(w@/!)" "|" "DONE(d!)" "CANCELLED(c@)"))) + ;; Customize note prompts (setq org-log-note-headings '((done . "CLOSING NOTE %t") @@ -862,7 +828,7 @@ and convert it to Org using the pandoc utility." org-clock-out-when-done t org-clock-persist t org-clock-persist-query-resume nil) - + ;; Helper function: detect if heading is a project (defun my/is-project-p () "Any task with a todo keyword subtask." @@ -911,23 +877,20 @@ Skips capture tasks and projects." ((and (member (org-get-todo-state) (list "ACTIVE")) (my/is-project-p)) "TODO")))) - + :bind (("<f11>" . org-clock-goto) ("C-c C-x C-i" . org-clock-in) ("C-c C-x C-o" . org-clock-out))) (with-eval-after-load 'org - ;; Update effort values for longer focus sessions (night owl, deep work) - ;; Added 4h, 8h, 16h, 40h for multi-hour deep work blocks (setq org-global-properties - '(("EFFORT_ALL" . "0:30 1:00 2:00 4:00 8:00 16:00 40:00") + '(("EFFORT_ALL" . "0:15 0:30 1:00 2:00 3:00 5:00 8:00") ("COMPLEXITY_ALL" . "low medium high") - ("PRIORITY_ALL" . "A B C D"))) - - ;; Enhanced column view format with clocksum comparison + ("PRIORITY_ALL" . "A B C"))) + (setq org-columns-default-format "%40ITEM(Task) %TODO %10EFFORT{+} %10CLOCKSUM %10PROGRESS %COMPLEXITY %DEADLINE") - + ;; Auto-set effort from complexity (already exists, keeping it here for reference) ;; Low complexity = 30 min, Medium = 2h, High = 5h (defun my/org-set-effort-from-complexity () @@ -940,7 +903,7 @@ Skips capture tasks and projects." ((string= complexity "low") (org-set-property "EFFORT" "0:30")) ((string= complexity "medium") (org-set-property "EFFORT" "2:00")) ((string= complexity "high") (org-set-property "EFFORT" "5:00")))))) - + ;; Keybinding for manual effort setting (define-key org-mode-map (kbd "C-c e") 'my/org-set-effort-from-complexity)) @@ -948,9 +911,9 @@ Skips capture tasks and projects." "Create a new project file with denote and comprehensive project structure." (interactive) (let* ((project-name (read-string "Project name: ")) - (tags (completing-read-multiple "Additional tags (comma-separated): " + (tags (completing-read-multiple "Additional tags (comma-separated): " '("work" "personal" "university" "learning"))) - (all-tags (cons "project" tags)) + (all-tags (append '("project" "agenda") tags)) (deadline-str (org-read-date nil nil nil "Project deadline (optional, RET to skip): ")) (effort-str (completing-read "Estimated total effort: " '("10h" "20h" "40h" "80h" "160h") nil nil "40h")) @@ -965,15 +928,15 @@ Skips capture tasks and projects." (insert ":EFFORT: " effort-str "\n") (insert ":PROGRESS: 0%\n") (insert ":END:\n\n") - + (insert "** Overview\n\n") (insert "- Goal :: \n") (insert "- Why :: \n") (insert "- Success Criteria :: \n") (insert "- Status :: Planning\n\n") - + (insert "** Phases\n\n") - (insert "*** PLAN Phase 1: Planning & Research\n") + (insert "*** TODO Phase 1: Planning & Research\n") (when (and deadline-str (not (string-empty-p deadline-str))) (insert "DEADLINE: <" deadline-str ">\n")) (insert ":PROPERTIES:\n") @@ -982,266 +945,89 @@ Skips capture tasks and projects." (insert "- [ ] Define scope\n") (insert "- [ ] Research requirements\n") (insert "- [ ] Break down into tasks\n\n") - - (insert "*** PLAN Phase 2: Implementation\n") + + (insert "*** TODO Phase 2: Implementation\n") (insert ":PROPERTIES:\n") (insert ":CREATED: " (format-time-string "[%Y-%m-%d %a %H:%M]") "\n") (insert ":END:\n\n") - - (insert "*** PLAN Phase 3: Review & Polish\n") + + (insert "*** TODO Phase 3: Review & Polish\n") (insert ":PROPERTIES:\n") (insert ":CREATED: " (format-time-string "[%Y-%m-%d %a %H:%M]") "\n") (insert ":END:\n\n") - + (insert "** Resources\n\n") (insert "- Links :: \n") (insert "- Files :: \n") (insert "- References :: \n\n") - + (insert "** Time Tracking\n\n") (insert "#+BEGIN: clocktable :scope file :maxlevel 3 :emphasize nil :link t\n") (insert "#+END:\n\n") (insert "Update with C-c C-c on the BEGIN line\n\n") - + (insert "** Status Updates\n\n") (insert "Use =C-c C-x C-c= for column view to update PROGRESS and see overview.\n\n") - + (insert "** Retrospective\n\n") (insert "- What worked :: \n") (insert "- What didn't :: \n") (insert "- Lessons learned :: \n") (insert "- Would do differently :: \n") - - (org-mode) - (goto-char (point-min)) - (search-forward "- Goal :: " nil t))) - -(defun my/daily-review () - "Append a simple daily review to today's journal - whenever you feel like it." - (interactive) - (require 'denote) - (require 'denote-journal) - (let* ((today (format-time-string "%Y-%m-%d")) - (journal-files (denote-directory-files "journal")) - (today-journal (seq-find - (lambda (file) - (string-match-p today (file-name-nondirectory file))) - journal-files))) - - ;; Create or open today's journal - (if today-journal - (find-file today-journal) - (denote-journal-new-or-existing-entry)) - - ;; Go to end and add review section - (goto-char (point-max)) - (unless (save-excursion - (beginning-of-line) - (looking-at "^\\*\\* Day Closed")) - (insert "\n** Day Closed " (format-time-string "[%H:%M]") "\n\n")) - - (insert "*** What I did today\n") - (insert "#+BEGIN: clocktable :scope agenda :maxlevel 2 :block today\n") - (insert "#+END:\n\n") - - (insert "*** Brain dump\n") - (insert "Thoughts, notes, captures, whatever:\n\n") - - (insert "*** Projects check\n") - (insert "Quick status (or skip if nothing changed):\n") - (insert "- \n\n") - - (insert "*** Tomorrow\n") - (insert "What to focus on (1-3 things):\n") - (insert "- \n\n") - - (insert "*** How I felt\n") - (insert "- Energy: \n") - (insert "- Focus: \n") - (insert "- Notes: \n\n") - - (org-mode) - (goto-char (point-max)) - (search-backward "*** Brain dump" nil t) - (forward-line 2) - (end-of-line))) -(defun my/reflection () - "Create a reflection note - use whenever you feel like reviewing progress." - (interactive) - (require 'denote) - (let* ((title (read-string "Reflection on: " "Recent progress")) - (file-name (denote title '("reflection")))) - (find-file file-name) - (goto-char (point-max)) - (insert "\n* " title "\n\n") - - (insert "** Time spent recently\n\n") - (insert "#+BEGIN: clocktable :scope agenda :maxlevel 2 :block thisweek\n") - (insert "#+END:\n\n") - (insert "Or change to :block lastweek, :block thismonth, etc.\n\n") - - (insert "** What's working?\n") - (insert "- \n\n") - - (insert "** What's not working?\n") - (insert "- \n\n") - - (insert "** Projects status\n") - (insert "#+BEGIN: columnview :id global :match \"project\" :format \"%ITEM %PROGRESS %EFFORT\"\n") - (insert "#+END:\n\n") - - (insert "** What needs attention?\n") - (insert "- \n\n") - - (insert "** Ideas / Changes\n") - (insert "- \n") - (org-mode) (goto-char (point-min)) - (search-forward "** What's working?" nil t) - (forward-line 1) - (end-of-line))) + (search-forward "- Goal :: " nil t))) (defun my/org-capture-timeblock-to-journal () - "Capture a time block to today's journal (refile later if needed)." + "Capture function: jump to today's journal for a timeblock." (require 'denote) (require 'denote-journal) - (let* ((description (read-string "What: ")) - (datetime (org-read-date t nil nil "When (date + time): ")) - (duration (completing-read "Duration: " - '("30m" "1h" "1h30m" "2h" "3h" "4h" "6h" "8h") - nil nil "2h")) - (type (completing-read "Type: " - '("Work" "Personal" "Meal" "Break" "Focus" "Learning" "Exercise") - nil nil "Work")) - (today (format-time-string "%Y-%m-%d")) + (let* ((today (format-time-string "%Y-%m-%d")) (journal-files (denote-directory-files "journal")) (today-journal (seq-find (lambda (file) (string-match-p today (file-name-nondirectory file))) journal-files))) - - ;; Open or create today's journal (if today-journal (find-file today-journal) (denote-journal-new-or-existing-entry)) - - ;; Go to end and add time block (goto-char (point-max)) - (insert "\n* TODO " description "\n") - (insert "SCHEDULED: <" datetime ">\n") - (insert ":PROPERTIES:\n") - (insert ":DURATION: " duration "\n") - (insert ":TYPE: " type "\n") - (insert ":CREATED: " (format-time-string "[%Y-%m-%d %a %H:%M]") "\n") - (insert ":END:\n\n") - (insert "Capture in journal - refile with C-c C-w if needed\n") - (current-buffer))) + (insert "\n* Timeblock\n"))) (defun my/org-capture-recurring-to-journal () - "Capture a recurring time block to today's journal (habits like meals, exercise)." + "Capture function: jump to today's journal for a recurring task." (require 'denote) (require 'denote-journal) - (let* ((description (read-string "What (recurring): ")) - (start-date (org-read-date nil nil nil "Start date: ")) - (time (read-string "Time (HH:MM): " "12:00")) - (repeat (completing-read "Repeat: " - '(".+1d" ".+2d" ".+1w" ".+1m") - nil nil ".+1d")) - (duration (completing-read "Duration: " - '("15m" "30m" "1h" "1h30m" "2h") - nil nil "1h")) - (type (completing-read "Type: " - '("Meal" "Exercise" "Break" "Routine") - nil nil "Meal")) - (today (format-time-string "%Y-%m-%d")) + (let* ((today (format-time-string "%Y-%m-%d")) (journal-files (denote-directory-files "journal")) (today-journal (seq-find (lambda (file) (string-match-p today (file-name-nondirectory file))) journal-files))) - - ;; Open or create today's journal (if today-journal (find-file today-journal) (denote-journal-new-or-existing-entry)) - - ;; Go to end and add recurring block (goto-char (point-max)) - (insert "\n* TODO " description "\n") - (insert "SCHEDULED: <" start-date " " time " " repeat ">\n") - (insert ":PROPERTIES:\n") - (insert ":STYLE: habit\n") - (insert ":DURATION: " duration "\n") - (insert ":TYPE: " type "\n") - (insert ":CREATED: " (format-time-string "[%Y-%m-%d %a %H:%M]") "\n") - (insert ":END:\n\n") - (insert "Recurring habit - tracked with org-habit. Refile with C-c C-w if needed.\n") - (current-buffer))) + (insert "\n* Recurring\n"))) (defun my/org-capture-meeting-to-journal () - "Capture a meeting to today's journal (can refile to separate file later if needed)." + "Capture function: jump to today's journal for a meeting note." (require 'denote) (require 'denote-journal) - (let* ((topic (read-string "Meeting topic: ")) - (datetime (org-read-date t nil nil "When (date + time): ")) - (duration (completing-read "Duration: " - '("15m" "30m" "1h" "1h30m" "2h") - nil nil "1h")) - (participants (read-string "Participants (optional): ")) - (today (format-time-string "%Y-%m-%d")) + (let* ((today (format-time-string "%Y-%m-%d")) (journal-files (denote-directory-files "journal")) (today-journal (seq-find (lambda (file) (string-match-p today (file-name-nondirectory file))) journal-files))) - - ;; Open or create today's journal (if today-journal (find-file today-journal) (denote-journal-new-or-existing-entry)) - - ;; Go to end and add meeting (goto-char (point-max)) - (insert "\n* Meeting: " topic "\n") - (insert "SCHEDULED: <" datetime ">\n") - (insert ":PROPERTIES:\n") - (insert ":DURATION: " duration "\n") - (insert ":TYPE: Meeting\n") - (insert ":CREATED: " (format-time-string "[%Y-%m-%d %a %H:%M]") "\n") - (insert ":END:\n\n") - (when (and participants (not (string-empty-p participants))) - (insert "** Attendees\n") - (insert "- " participants "\n\n")) - (insert "** Agenda\n") - (insert "- \n\n") - (insert "** Notes\n\n") - (insert "** Action Items\n") - (insert "- [ ] \n\n") - (insert "Captured in journal - refile to separate meeting file with C-c C-w if needed\n") - (org-mode) - (search-backward "** Agenda" nil t) - (forward-line 1) - (end-of-line) - (current-buffer))) + (insert "\n* Meeting: "))) -;; Add to org-capture-templates (captures to journal, refile later if needed) -(with-eval-after-load 'org-capture - (add-to-list 'org-capture-templates - '("b" "Time Block" plain - (function my/org-capture-timeblock-to-journal) - "" :immediate-finish t :jump-to-captured t)) - - (add-to-list 'org-capture-templates - '("r" "Recurring Block" plain - (function my/org-capture-recurring-to-journal) - "" :immediate-finish t :jump-to-captured t)) - - (add-to-list 'org-capture-templates - '("m" "Meeting" plain - (function my/org-capture-meeting-to-journal) - "" :immediate-finish nil :jump-to-captured t))) +;; capture templates are merged in the org-capture section below (use-package org-noter :ensure t @@ -1274,7 +1060,7 @@ Skips capture tasks and projects." (defun my/org-capture-denote-deadline () (let* ((context (read-string "Task with deadline: ")) (deadline (org-read-date t nil nil "Deadline: ")) - (file-name (denote nil '("task")))) + (file-name (denote nil '("agenda")))) (find-file file-name) (goto-char (point-min)) (forward-line 4) @@ -1284,7 +1070,7 @@ Skips capture tasks and projects." (defun my/org-capture-denote-scheduled () (let* ((context (read-string "Scheduled task: ")) (schedule (org-read-date t nil nil "Schedule: ")) - (file-name (denote nil '("task")))) + (file-name (denote nil '("agenda")))) (find-file file-name) (goto-char (point-min)) (forward-line 4) @@ -1294,8 +1080,8 @@ Skips capture tasks and projects." (defun my/org-capture-denote-task () (let* ((context (read-string "Task: ")) (todo-state (completing-read "TODO state: " - '("ACTIVE" "NEXT" "TODO" "WAIT" "PLAN"))) - (file-name (denote nil '("task")))) + '("ACTIVE" "NEXT" "TODO" "WAIT"))) + (file-name (denote nil '("agenda")))) (find-file file-name) (goto-char (point-min)) (forward-line 4) @@ -1312,7 +1098,16 @@ Skips capture tasks and projects." "" :immediate-finish t :jump-to-captured t) ("s" "Scheduled" plain (function my/org-capture-denote-scheduled) - "" :immediate-finish t :jump-to-captured t)))) + "" :immediate-finish t :jump-to-captured t) + ("b" "Timeblock" plain + (function my/org-capture-timeblock-to-journal) + "" :immediate-finish nil :jump-to-captured t) + ("r" "Recurring" plain + (function my/org-capture-recurring-to-journal) + "" :immediate-finish t :jump-to-captured t) + ("m" "Meeting" plain + (function my/org-capture-meeting-to-journal) + "" :immediate-finish nil :jump-to-captured t)))) (use-package org-super-agenda :after org-agenda @@ -1324,275 +1119,173 @@ Skips capture tasks and projects." :ensure t :after org-super-agenda) +;;; --- Agenda display settings --- + +(setq org-agenda-window-setup 'current-window + org-agenda-inhibit-startup t + org-agenda-remove-tags t + org-agenda-dim-blocked-tasks nil + org-agenda-skip-scheduled-if-done t + org-agenda-skip-deadline-if-done t) + +(setq org-agenda-time-grid + '((daily today require-timed) + (800 1000 1200 1400 1600 1800 2000) + "......" "________________")) + +(setq org-agenda-current-time-string + "--- NOW ---------------") + +(setq org-agenda-prefix-format + '((agenda . " %i %?-12t% s") + (todo . " %i ") + (tags . " %i ") + (search . " %i "))) + +;;; --- Agenda views --- +;; +;; d - Today: daily driver, what to focus on now +;; w - Week: calendar + upcoming + backlog +;; p - Projects: all project tasks by state + (setq org-agenda-custom-commands '( - ("d" "Daily Dashboard" + ;; ── Today ────────────────────────────────────────────── + ("d" "Today" ( - (org-ql-block '(and (scheduled :to today) - (not (done))) - ((org-ql-block-header "📅 Today's Schedule") + ;; Block 1: standard agenda — time-grid, NOW line, scheduled + deadlines + (agenda "" + ((org-agenda-span 1) + (org-agenda-start-day ".") + (org-deadline-warning-days 3) + (org-scheduled-past-days 0) + (org-agenda-day-face-function (lambda (date) 'org-agenda-date)) + (org-agenda-overriding-header "") (org-super-agenda-groups - '( - (:name "🌙 Night (00:00-06:00)" - :and (:scheduled today :time-grid t) - :pred (lambda (item) - (when-let ((time (org-get-scheduled-time (point)))) - (let ((hour (nth 2 (decode-time time)))) - (and (>= hour 0) (< hour 6))))) + '((:name "Overdue" + :scheduled past + :deadline past + :order 0) + (:name "Schedule" + :time-grid t :order 1) - (:name "🌅 Morning (06:00-12:00)" - :and (:scheduled today :time-grid t) - :pred (lambda (item) - (when-let ((time (org-get-scheduled-time (point)))) - (let ((hour (nth 2 (decode-time time)))) - (and (>= hour 6) (< hour 12))))) + (:name "Deadlines" + :deadline today :order 2) - (:name "☀️ Afternoon (12:00-18:00)" - :and (:scheduled today :time-grid t) - :pred (lambda (item) - (when-let ((time (org-get-scheduled-time (point)))) - (let ((hour (nth 2 (decode-time time)))) - (and (>= hour 12) (< hour 18))))) - :order 3) - (:name "🌆 Evening (18:00-00:00)" - :and (:scheduled today :time-grid t) - :pred (lambda (item) - (when-let ((time (org-get-scheduled-time (point)))) - (let ((hour (nth 2 (decode-time time)))) - (and (>= hour 18) (< hour 24))))) - :order 4) (:discard (:anything t)))))) - (org-ql-block '(and (or (tags "self") - (tags "university")) - (not (scheduled)) - (not (tags "project")) + ;; Block 2: active + next tasks (what you can work on right now) + (org-ql-block '(and (todo "ACTIVE" "NEXT") (not (done))) - ((org-ql-block-header "📋 Unscheduled Tasks") + ((org-ql-block-header "In Progress") (org-super-agenda-groups - '( - (:name "🔥 ACTIVE (Currently Working)" + '((:name "ACTIVE" :todo "ACTIVE" :order 1) - (:name "⏭️ NEXT (Ready to Start)" + (:name "NEXT" :todo "NEXT" :order 2) - (:name "📝 TODO (Backlog)" - :todo "TODO" - :order 3) - (:name "⏸️ WAIT (Blocked)" - :todo "WAIT" - :order 4) (:discard (:anything t)))))) - (org-ql-block '(and (tags "project") + ;; Block 3: waiting items + (org-ql-block '(and (todo "WAIT") (not (done))) - ((org-ql-block-header "🎯 Project Tasks") + ((org-ql-block-header "Waiting On") (org-super-agenda-groups - '( - (:name "🔥 ACTIVE Projects" - :todo "ACTIVE" - :order 1) - (:name "⏭️ NEXT Up" - :todo "NEXT" - :order 2) - (:name "📝 TODO" - :todo "TODO" - :order 3) - (:discard (:anything t))))))) - ((org-agenda-span 'day))) - - ("p" "Project Overview" - ((org-ql-block '(and (tags "project") - (not (done))) - ((org-ql-block-header "All Project Tasks") - (org-super-agenda-groups - '( - (:name "ACTIVE" - :todo "ACTIVE" - :order 1) - (:name "NEXT" - :todo "NEXT" - :order 2) - (:name "TODO" - :todo "TODO" - :order 3) - (:name "WAIT" - :todo "WAIT" - :order 4) - (:discard (:anything t))))))) - ((org-agenda-span 'day))) + '((:anything t))))))) - ("e" "Evaluation Mode - Failed Tasks" - ((org-ql-block '(and (scheduled :to yesterday) - (not (done)) - (not (habit))) - ((org-ql-block-header "Overdue Tasks") - (org-super-agenda-groups - '( - (:name "ACTIVE" - :todo "ACTIVE" - :order 1) - (:name "NEXT" - :todo "NEXT" - :order 2) - (:name "TODO" - :todo "TODO" - :order 3) - (:discard (:anything t)))))) - - (org-ql-block '(and (scheduled :from -7 :to -1) - (not (done)) - (not (habit))) - ((org-ql-block-header "This Week's Unfinished") - (org-super-agenda-groups - '( - (:name "By Day" - :scheduled t - :order 1) - (:discard (:anything t))))))) - ((org-agenda-span 'week))) - - ("w" "Weekly Overview" - ((org-ql-block '(and (or (deadline auto) - (scheduled :to 7)) - (or (tags "self") - (tags "university")) - (not (tags "project")) - (not (done)) - (not (habit))) - ((org-ql-block-header "Upcoming Deadlines & Scheduled") - (org-super-agenda-groups - '( - (:name "Deadlines" - :deadline t - :order 1) - (:name "Scheduled" - :scheduled t - :order 2) - (:discard (:anything t)))))) - - (org-ql-block '(and (ts-active :from today :to 7 :with-time t) - (or (tags "self") - (tags "university")) - (not (tags "project")) - (not (done))) - ((org-ql-block-header "Appointments This Week") - (org-super-agenda-groups - '( - (:name "By Time" - :anything t - :order 1))))) + ;; ── Week ─────────────────────────────────────────────── + ("w" "Week" + ( + ;; Block 1: today in detail + (agenda "" + ((org-agenda-span 1) + (org-deadline-warning-days 0) + (org-scheduled-past-days 0) + (org-agenda-day-face-function (lambda (date) 'org-agenda-date)) + (org-agenda-overriding-header "Today") + (org-super-agenda-groups + '((:name "Overdue" + :scheduled past + :deadline past + :order 0) + (:name "Schedule" + :time-grid t + :order 1) + (:discard (:anything t)))))) - (org-ql-block '(and (habit) - (or (tags "self") - (tags "university")) - (not (tags "project"))) - ((org-ql-block-header "Habits") - (org-super-agenda-groups - '( - (:name "Daily Habits" - :habit t - :order 1) - (:discard (:anything t))))))) - ((org-agenda-span 'week))) + ;; Block 2: next 6 days + (agenda "" + ((org-agenda-start-on-weekday nil) + (org-agenda-start-day "+1d") + (org-agenda-span 6) + (org-deadline-warning-days 0) + (org-agenda-overriding-header "Next 6 Days") + (org-super-agenda-groups + '((:anything t))))) - ("s" "Self & University Tasks" - ((org-ql-block '(and (or (tags "self") - (tags "university")) - (not (tags "project")) - (not (done))) - ((org-ql-block-header "All Self & University Tasks") - (org-super-agenda-groups - '( - (:name "ACTIVE" - :todo "ACTIVE" - :order 1) - (:name "NEXT" - :todo "NEXT" - :order 2) - (:name "TODO" - :todo "TODO" - :order 3) - (:name "WAIT" - :todo "WAIT" - :order 4) - (:discard (:anything t)))))))) + ;; Block 3: upcoming deadlines beyond this week + (agenda "" + ((org-agenda-time-grid nil) + (org-agenda-start-on-weekday nil) + (org-agenda-start-day "+7d") + (org-agenda-span 14) + (org-agenda-show-all-dates nil) + (org-agenda-entry-types '(:deadline)) + (org-agenda-overriding-header "Upcoming Deadlines (+14d)") + (org-super-agenda-groups + '((:anything t))))) - ("c" "Complexity Matrix" - ((org-ql-block '(and (property "COMPLEXITY" "high") - (property "EFFORT") - (not (done))) - ((org-ql-block-header "High Complexity Tasks") - (org-super-agenda-groups - '( - (:name "ACTIVE" - :todo "ACTIVE" - :order 1) - (:name "NEXT" - :todo "NEXT" - :order 2) - (:discard (:anything t)))))) + ;; Block 4: unscheduled backlog + (org-ql-block '(and (todo) + (not (done)) + (not (scheduled)) + (not (deadline))) + ((org-ql-block-header "Backlog (unscheduled)") + (org-super-agenda-groups + '((:name "ACTIVE" :todo "ACTIVE" :order 1) + (:name "NEXT" :todo "NEXT" :order 2) + (:name "TODO" :todo "TODO" :order 3) + (:name "WAIT" :todo "WAIT" :order 4) + (:discard (:anything t)))))))) - (org-ql-block '(and (property "COMPLEXITY" "low") - (property "EFFORT") + ;; ── Projects ─────────────────────────────────────────── + ("p" "Projects" + ((org-ql-block '(and (tags "project") (not (done))) - ((org-ql-block-header "Quick Wins - Low Complexity") + ((org-ql-block-header "All Project Tasks") (org-super-agenda-groups - '( - (:name "Tasks" - :not (:todo "WAIT") - :order 1) + '((:name "ACTIVE" :todo "ACTIVE" :order 1) + (:name "NEXT" :todo "NEXT" :order 2) + (:name "TODO" :todo "TODO" :order 3) + (:name "WAIT" :todo "WAIT" :order 4) (:discard (:anything t)))))))))) -(setq org-agenda-remove-tags t) - -;; (setq split-width-threshold 0) -;; (setq split-height-threshold nil) - -(setq org-priority-faces - '((?A . (:foreground "#ff6b6b" :weight bold)) - (?B . (:foreground "#ffd93d" :weight bold)) - (?C . (:foreground "#6bcf7f" :weight bold)))) - -(setq org-columns-default-format - "%40ITEM(Task) %10TODO(State) %10EFFORT(Effort) %10COMPLEXITY(Complexity) %PRIORITY") - -;; org-global-properties now defined in workflow enhancements section above - -(setq org-agenda-time-grid - '((daily today require-timed) - (800 1000 1200 1400 1600 1800 2000) - "......" "________________")) - -(setq org-agenda-current-time-string - "--- NOW ---------------") - -;; org-todo-keywords now defined in workflow enhancements section above +;;; --- Theme-adaptive TODO keyword faces --- (setq org-todo-keyword-faces - '(("TODO" . (:inherit (warning org-todo))) - ("NEXT" . (:inherit (font-lock-type-face org-todo))) - ("ACTIVE" . (:inherit (bold org-todo))) - ("WAIT" . (:inherit (shadow org-todo))) - ("DONE" . (:inherit (success org-todo))) + '(("TODO" . (:inherit (warning org-todo))) + ("NEXT" . (:inherit (font-lock-type-face org-todo))) + ("ACTIVE" . (:inherit (bold org-todo))) + ("WAIT" . (:inherit (shadow org-todo))) + ("DONE" . (:inherit (success org-todo))) ("CANCELLED" . (:inherit (shadow org-done))))) (defun my/update-org-modern-faces () (setq org-modern-todo-faces - `(("TODO" :background ,(face-attribute 'warning :foreground) - :foreground ,(face-attribute 'default :background)) - ("ACTIVE" :background ,(face-attribute 'error :foreground) - :foreground ,(face-attribute 'default :background)) - ("DONE" :background ,(face-attribute 'success :foreground) - :foreground ,(face-attribute 'default :background)) + `(("TODO" :background ,(face-attribute 'warning :foreground) + :foreground ,(face-attribute 'default :background)) + ("ACTIVE" :background ,(face-attribute 'error :foreground) + :foreground ,(face-attribute 'default :background)) + ("DONE" :background ,(face-attribute 'success :foreground) + :foreground ,(face-attribute 'default :background)) ("CANCELLED" :background ,(face-attribute 'shadow :foreground) - :foreground ,(face-attribute 'default :background))))) + :foreground ,(face-attribute 'default :background))))) (add-hook 'after-load-theme-hook #'my/update-org-modern-faces) (my/update-org-modern-faces) -;; org-set-effort-from-complexity now defined in workflow enhancements section above +;;; --- Tag cleanup in agenda buffer --- (defun my/org-agenda-remove-tags () (save-excursion @@ -1680,7 +1373,7 @@ Skips capture tasks and projects." :ensure t :after org :config - (setq denote-agenda-include-regexp "task") + (setq denote-agenda-include-regexp "_agenda") (denote-agenda-insinuate)) (use-package denote-journal @@ -1688,10 +1381,33 @@ Skips capture tasks and projects." :config (setopt denote-journal-title-format 'day-date-month-year)) -(defcustom my/denote-task-filename-component-regexp - "\\(?:[-_.]\\|:\\)task\\(?:[-_.]\\|:\\|$\\)" - "Regexp matching a filename component that denotes the 'task' tag. -Works on the base filename (without extension), e.g. matches \"-task\", \":task:\", \"_task_\"." +(defun my/denote-journal-template () + "Insert journal structure into a new journal entry. +Only inserts when the buffer has just the front-matter (fresh file)." + (when (and (buffer-file-name) + (string-match-p "journal" (buffer-file-name)) + (<= (count-lines (point-min) (point-max)) 6)) + (goto-char (point-max)) + (insert + "\n* \n" + "\n#+BEGIN: clocktable :scope file :maxlevel 3 :emphasize nil :link t\n" + "#+END:\n" + "\n* \n" + "\n** Plan the day\n" + ":LOGBOOK:\n" + ":END:\n" + "\n* \n" + ":PROPERTIES:\n" + ":VISIBILITY: folded\n" + ":END:\n"))) + +(advice-add 'denote-journal-new-or-existing-entry :after + (lambda (&rest _) (my/denote-journal-template))) + +(defcustom my/denote-agenda-filename-component-regexp + "\\(?:[-_.]\\|:\\)agenda\\(?:[-_.]\\|:\\|$\\)" + "Regexp matching a filename component that denotes the 'agenda' tag. +Works on the base filename (without extension), e.g. matches \"-agenda\", \":agenda:\", \"_agenda_\"." :type 'string) (defun my/denote--make-unique-filename (dir base ext) @@ -1704,8 +1420,8 @@ Works on the base filename (without extension), e.g. matches \"-task\", \":task: (setq count (1+ count))) candidate)) -(defun my/denote-remove-task-filetag-and-silent-rename () - "If current headline became DONE in a Denote note, remove :task: filetag and remove 'task' from filename silently. +(defun my/denote-remove-agenda-filetag-and-silent-rename () + "If current headline became DONE in a Denote note, remove :agenda: filetag and remove 'agenda' from filename silently. - Only acts if there are no other non-DONE TODOs in the same file. - Does not call Denote's interactive rename command (no buffers opened)." (when (and (derived-mode-p 'org-mode) @@ -1726,12 +1442,12 @@ Works on the base filename (without extension), e.g. matches \"-task\", \":task: nil 'file) nil))) (unless has-other - ;; 1) Remove :task: from #+filetags: + ;; 1) Remove :agenda: from #+filetags: (save-excursion (goto-char (point-min)) (when (re-search-forward "^#\\+filetags:\\s-*\\(.*\\)$" nil t) (let* ((tags (match-string 1)) - (clean (replace-regexp-in-string ":task:" "" tags)) + (clean (replace-regexp-in-string ":agenda:" "" tags)) (clean (replace-regexp-in-string "::+" ":" clean)) (clean (replace-regexp-in-string "^:\\|:$" "" clean))) (if (string-empty-p clean) @@ -1745,15 +1461,15 @@ Works on the base filename (without extension), e.g. matches \"-task\", \":task: (name (file-name-nondirectory file)) (ext (file-name-extension name)) ;; "org" (base (file-name-sans-extension name)) - ;; remove the task component from the base - (new-base (replace-regexp-in-string my/denote-task-filename-component-regexp - "" - base))) + ;; remove the agenda component from the base + (new-base (replace-regexp-in-string my/denote-agenda-filename-component-regexp + "" + base))) (when (and new-base (not (string= new-base base))) ;; cleanup repeated separators: convert multiple '-'/'_'/'..' to single '-' (setq new-base (replace-regexp-in-string "[-_.:]+" - "-" - new-base)) + "-" + new-base)) ;; strip leading/trailing separators (setq new-base (replace-regexp-in-string "\\`[-_.:-]+" "" new-base)) (setq new-base (replace-regexp-in-string "[-_.:-]+\\'" "" new-base)) @@ -1761,16 +1477,16 @@ Works on the base filename (without extension), e.g. matches \"-task\", \":task: (let ((target (my/denote--make-unique-filename dir new-base ext))) (condition-case err (progn - (rename-file file target 1) ;; 1 = ok to overwrite, but we avoid collisions by uniqueness + (rename-file file target 1) ;; update current buffer to visit the new filename silently (set-visited-file-name target t t) ;; save changes (filetags update + new filename) (save-buffer) - (message "Denote: removed 'task' component from filename -> %s" (file-name-nondirectory target))) + (message "Denote: removed 'agenda' component from filename -> %s" (file-name-nondirectory target))) (error (message "Denote rename failed: %s" (error-message-string err))))))))))) -(add-hook 'org-after-todo-state-change-hook #'my/denote-remove-task-filetag-and-silent-rename) +(add-hook 'org-after-todo-state-change-hook #'my/denote-remove-agenda-filetag-and-silent-rename) (use-package denote-menu :ensure t @@ -1841,7 +1557,7 @@ Works on the base filename (without extension), e.g. matches \"-task\", \":task: (setq tmr-sound-file "/usr/share/sounds/freedesktop/stereo/alarm-clock-elapsed.oga" tmr-notification-urgency 'normal tmr-description-list 'tmr-description-history) - + (tmr-mode-line-mode 1) (define-key global-map (kbd "C-c t") #'tmr-prefix-map)) (use-package which-key @@ -1858,7 +1574,7 @@ Works on the base filename (without extension), e.g. matches \"-task\", \":task: :hook (after-init . vertico-mode) :custom - (vertico-count 16) + (vertico-count 10) (vertico-resize nil) (vertico-cycle nil) :bind (:map vertico-map @@ -1879,11 +1595,11 @@ Works on the base filename (without extension), e.g. matches \"-task\", \":task: (setq vertico-posframe-parameters '((left-fringe . 12) ;; Fringes (right-fringe . 12) (accept-focus . t))) - (undecorated . nil) ;; Rounded frame + ;; (undecorated . nil) ;; Rounded frame :config (vertico-posframe-mode 1) - (setq vertico-posframe-width 124 ;; Narrow frame + (setq vertico-posframe-width 96 ;; Narrow frame vertico-posframe-height vertico-count ;; Default height ;; Don't create posframe for these commands vertico-multiform-commands '((consult-line (:not posframe)) @@ -2059,11 +1775,10 @@ completion-category-overrides '((file (styles partial-completion))))) ;; Customi (setq eglot-events-buffer-size 0) (setq eglot-report-progress nil) - (add-hook 'eglot-managed-mode-hook - (lambda () + (add-hook 'eglot-managed-mode-hook + (lambda () (eglot-inlay-hints-mode -1) - (when (fboundp 'eglot-semantic-tokens-mode) - (eglot-semantic-tokens-mode 1)))) + (eglot-semantic-tokens-mode 1))) (setq eglot-ignored-server-capabilities '(:inlayhintprovider :documenthighlightprovider))) @@ -2278,12 +1993,24 @@ completion-category-overrides '((file (styles partial-completion))))) ;; Customi (use-package vterm :ensure t :config - (setq vterm-timer-delay 0.001)) + (setq vterm-timer-delay 0.0001) + (setq vterm-shell "fish")) (use-package multi-vterm :ensure t :defer t) +(use-package eee + :ensure t + :straight (:type git :host github :repo "eval-exec/eee.el" + :files (:defaults "*.el" "*.sh")) + :config + (setq ee-terminal-command "kitty")) + +(setq eaf-pyqterminal-font-size 20 + eaf-pyqterminal-refresh-ms 3 + eaf-pyqterminal-font-family "Maple Mono NF") + (use-package olivetti :custom (olivetti-style 'fancy) ; Keep margins visible @@ -2408,20 +2135,14 @@ completion-category-overrides '((file (styles partial-completion))))) ;; Customi (modify-syntax-entry ?_ "w") -;; (defun my/eldoc-and-jump () -;; (interactive) -;; (if (display-graphic-p) -;; (call-interactively 'eldoc-box-help-at-point) -;; (progn -;; (eldoc-doc-buffer) -;; (when-let ((eldoc-win (get-buffer-window "*eldoc*"))) -;; (select-window eldoc-win))))) - (defun my/eldoc-and-jump () + "Show documentation at point. Works in both GUI and terminal." (interactive) - (call-interactively 'eldoc-box-help-at-point)) + (if (display-graphic-p) + (eldoc-box-help-at-point) + (eldoc-doc-buffer t))) -;; (define-key evil-normal-state-map (kbd "K") #'my/eldoc-and-jump) +(define-key evil-normal-state-map (kbd "K") #'my/eldoc-and-jump) ;; (setq select-enable-clipboard nil) ;; (setq select-enable-primary nil) @@ -2549,32 +2270,37 @@ completion-category-overrides '((file (styles partial-completion))))) ;; Customi (define-key evil-visual-state-map (kbd "I") 'my/evil-mc-visual-block-insert) (define-key evil-visual-state-map (kbd "A") 'my/evil-mc-visual-block-append)) -(use-package avy +(use-package flash :ensure t - :straight t + :straight (:host github :repo "Prgebish/flash") :after evil - :general - ;; (general-nmap "s" 'avy-goto-char-timer) - ;; (general-omap "s" 'evil-avy-goto-char-timer) + :custom + (flash-multi-window t) + (flash-backdrop t) + (flash-case-fold t) + (flash-autojump nil) + (flash-highlight-matches t) + (flash-label-position 'overlay) + (flash-jump-position 'start) + (flash-char-jump-labels t) + (flash-char-multi-line nil) + (flash-nohlsearch t) + (flash-jumplist t) :config - (setq avy-all-windows t - avy-all-windows-alt t - avy-background t - avy-case-fold-search t - avy-timeout-seconds 0.3 - avy-style 'at-full - avy-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)) + ;; Evil integration: binds gs in normal/visual/operator + enhanced f/t/F/T + (require 'flash-evil) + (flash-evil-setup t) - (evil-define-avy-motion emacs-flash-jump inclusive)) - -(use-package flash-emacs - :ensure t - :straight (:host github :repo "JiaweiChenC/flash-emacs")) + ;; Restore ; and , after flash-char overwrites them + ;; ; is used as prefix for prev-navigation (;b, ;d) + ;; , is the local leader + (evil-define-key* '(normal visual motion) 'global + (kbd ";") nil + (kbd ",") nil) -;; ZenScriptor/avy-flash -(use-package avy-flash - :ensure t - :straight (:host github :repo "ZenScriptor/avy-flash")) + ;; Search integration: labels during C-s, /, ? + (require 'flash-isearch) + (flash-isearch-mode 1)) (use-package undo-tree :defer t @@ -2777,7 +2503,7 @@ completion-category-overrides '((file (styles partial-completion))))) ;; Customi :straight (:host github :repo "honmaple/emacs-maple-modeline") :hook (after-init . maple-modeline-mode) :config - (setq maple-modeline-separator 'arrow) + (setq maple-modeline-separator 'nil) (setq maple-modeline-height 25) (setq maple-modeline-icon t) @@ -2791,6 +2517,27 @@ completion-category-overrides '((file (styles partial-completion))))) ;; Customi :format (propertize (downcase (format-time-string " %I:%M %p ")) 'face 'bold)) + (maple-modeline-define-segment org-clock-task + :if (and (fboundp 'org-clocking-p) (org-clocking-p)) + :format + (let ((heading (truncate-string-to-width + (substring-no-properties org-clock-heading) 35 nil nil "..."))) + (concat + (maple-modeline--concat-or + (maple-modeline--icon 'mdicon "nf-md-clock_outline" face) + "CLK") + " " (propertize heading 'face face + 'mouse-face 'mode-line-highlight + 'help-echo "Go to clocked task" + 'local-map (make-mode-line-mouse-map 'mouse-1 'org-clock-goto))))) + + (maple-modeline-define-segment tmr-timer + :if (and (bound-and-true-p tmr-mode-line-mode) + (fboundp 'tmr-mode-line--get-active-timers) + (tmr-mode-line--get-active-timers)) + :format + (string-trim (or tmr-mode-line-string ""))) + (maple-modeline-define my-custom-style :left ((evil :left (bar :left "")) macro @@ -2799,8 +2546,9 @@ completion-category-overrides '((file (styles partial-completion))))) ;; Customi version-control remote-host region) - :right (misc-info - narrow + :right (narrow + org-clock-task + tmr-timer python my-modeline-time process @@ -2848,9 +2596,9 @@ completion-category-overrides '((file (styles partial-completion))))) ;; Customi (blink-cursor-mode 0) (setq-default cursor-type 'box) -(defvar cashmere/font-height 140) +(defvar cashmere/font-height 180) -(set-face-attribute 'default nil :family "MonoLisa Nerd Font" :weight 'regular :height cashmere/font-height) +(set-face-attribute 'default nil :family "Maple Mono NF" :weight 'regular :height cashmere/font-height) (set-face-attribute 'fixed-pitch nil :family "RobotoMono Nerd Font" :weight 'regular) (set-face-attribute 'variable-pitch nil :family "Poppins" :weight 'regular :height 1.1) @@ -3356,13 +3104,6 @@ completion-category-overrides '((file (styles partial-completion))))) ;; Customi ;; Optional: Cache expires after 5 minutes for security. (setq auth-source-cache-expiry 300))) -(use-package eshell - :ensure nil - :straight nil) - -(use-package eshell-prompt-extras - :ensure t) - (use-package zoom :ensure t) (custom-set-variables @@ -3410,13 +3151,9 @@ completion-category-overrides '((file (styles partial-completion))))) ;; Customi "d" '(:ignore t :wk "denote") "dj" '(denote-journal-new-or-existing-entry :wk "journal") "dd" '(denote-menu-list-notes t :wk "List all notes") - "dl" '(denote-link t :wk "Link note") "dg" '(consult-denote-grep t :wk "Search") "dn" '(denote t :wk "Create a new note") "dr" '(denote-rename-file t :wk "Rename Note") - "dp" '(my/create-project :wk "Create project") - "dR" '(my/daily-review :wk "Daily review") - "dD" '(my/reflection :wk "Reflection") "dtl" '(tmr-list-timers :wk "list timer") "dtt" '(tmr :wk "set timer") @@ -3465,13 +3202,7 @@ completion-category-overrides '((file (styles partial-completion))))) ;; Customi "gs" '(magit-file-stage :wk "stage file") "gb" '(vc-annotate :wk "blame") - "o" '(:ignore t :wk "org/open") - "oa" '(:ignore t :wk "agenda") - "oad" '(org-agenda :wk "daily dashboard") - "oaw" '((lambda () (interactive) (org-agenda nil "w")) :wk "weekly overview") - "oap" '((lambda () (interactive) (org-agenda nil "p")) :wk "projects") - "oae" '((lambda () (interactive) (org-agenda nil "e")) :wk "evaluation") - "oac" '((lambda () (interactive) (org-agenda nil "c")) :wk "complexity matrix") + "o" '(:ignore t :wk "open") "h" '(:ignore t :wk "help") "hm" '(describe-mode :wk "mode") @@ -3511,22 +3242,25 @@ completion-category-overrides '((file (styles partial-completion))))) ;; Customi "a" '(embark-act :wk "embark") "u" '(undo-tree-visualize :wk "undo tree") - "P" '(consult-yank-from-kill-ring :wk "paste history")) + "P" '(consult-yank-from-kill-ring :wk "paste history") + + "t" '(:ignore t :wk "treesitter") + "ts" '(flash-treesitter :wk "flash treesitter")) -(defun my/avy-enabled-p () -(and (not (derived-mode-p 'magit-mode 'dired-mode 'ibuffer-mode)) -(not (eq major-mode 'dirvish-mode)))) +(defun my/flash-enabled-p () + (and (not (derived-mode-p 'magit-mode 'dired-mode 'ibuffer-mode)) + (not (eq major-mode 'dirvish-mode)))) (defun my/s-key-dispatch () (interactive) (if (derived-mode-p 'magit-mode) (call-interactively 'magit-stage) - (when (my/avy-enabled-p) + (when (my/flash-enabled-p) (let ((scroll-margin 0) (maximum-scroll-margin 0)) - (call-interactively 'flash-emacs-jump))))) + (call-interactively 'flash-evil-jump))))) -(general-def '(normal visual) 'override +(general-def '(normal visual operator) 'override "s" 'my/s-key-dispatch) @@ -3864,9 +3598,6 @@ completion-category-overrides '((file (styles partial-completion))))) ;; Customi (use-package emacs-everywhere :ensure t) -(use-package rg - :ensure t) - ;; (profiler-start 'cpu) ;; (org-agenda nil "c") ;; (profiler-report) @@ -1,7 +1,7 @@ #+title: config.org #+date: [2025-10-20 Mon 08:33] #+identifier: 20251020T083323 -#+PROPERTY: header-args +#+PROPERTY: header-args :tangle config.el #+STARTUP: content * early-init @@ -150,8 +150,8 @@ (scroll-bar-mode -1) (add-to-list 'default-frame-alist '(vertical-scroll-bars . nil)) (add-to-list 'default-frame-alist '(horizontal-scroll-bars . nil)) - (set-frame-parameter (selected-frame) 'alpha-background 80) - (add-to-list 'default-frame-alist '(alpha-background . 80)) + ;; (set-frame-parameter (selected-frame) 'alpha-background 80) + ;; (add-to-list 'default-frame-alist '(alpha-background . 80)) (global-hl-line-mode -1) ;; Disable highlight of the current line (global-auto-revert-mode 1) ;; Enable global auto-revert mode to keep buffers up to date with their corresponding files. (indent-tabs-mode -1) ;; Disable the use of tabs for indentation (use spaces instead). @@ -339,13 +339,13 @@ (setq dashboard-image-banner-max-height 256) (setq dashboard-bookmarks-show-base t) (setq dashboard-bookmarks-item-format "%s") - (setq dashboard-projects-backend 'projectile) + (setq dashboard-projects-backend 'project-el) (setq dashboard-items '((bookmarks . 5) (projects . 5) (recents . 5))) (setq dashboard-projects-switch-function (lambda (proj) - (projectile-switch-project-by-name proj))) + (project-switch-project proj))) (setq dashboard-center-content t) (setq dashboard-set-file-icons t) (setq dashboard-set-heading-icons t) @@ -386,8 +386,6 @@ (message "centered-cursor on")))) #+end_src -* - * cursory #+begin_src emacs-lisp @@ -669,59 +667,6 @@ Not necessary but an eyecandy to look at! (setq gptel-backends (list my/openrouter-backend))) #+end_src -** claude-code - -#+begin_src emacs-lisp -(use-package claude-code - :ensure t - :straight (:type git :host github :repo "stevemolitor/claude-code.el" :branch "main" :depth 1 - :files ("*.el" (:exclude "images/*"))) - :bind-keymap - ("C-c c" . claude-code-command-map) ;; or your preferred key - ;; Optionally define a repeat map so that "M" will cycle thru Claude auto-accept/plan/confirm modes after invoking claude-code-cycle-mode / C-c M. - :bind - (:repeat-map my-claude-code-map ("M" . claude-code-cycle-mode)) - :config - ;; optional IDE integration with Monet - (add-hook 'claude-code-process-environment-functions #'monet-start-server-function) - (monet-mode 1) - (setq claude-code-terminal-backend 'vterm) - (claude-code-mode)) -#+end_src - -*** inheritenv - -#+begin_src emacs-lisp -(use-package inheritenv - :ensure t - :straight (:type git :host github :repo "purcell/inheritenv")) -#+end_src - -** monet - -#+begin_src emacs-lisp -(use-package monet - :ensure t - :straight (:host github :repo "stevemolitor/monet")) -#+end_src - -* agent-shell - -#+begin_src emacs-lisp -(use-package agent-shell - :ensure t - ;; Add agent installation configs here - :config - (setq agent-shell-highlight-blocks t) - ) -#+end_src - -** acp - -#+begin_src emacs-lisp -(use-package acp - :ensure t) -#+end_src * eldoc @@ -1038,13 +983,13 @@ Track when and why tasks change state - essential for accountability and retrosp org-log-reschedule 'time org-log-into-drawer t org-enforce-todo-dependencies t) - + ;; Update TODO keywords to require notes for WAIT and CANCELLED ;; @ means: prompt for note when entering state ;; ! means: timestamp when leaving state (setq org-todo-keywords - '((sequence "TODO(t)" "NEXT(n)" "ACTIVE(a!)" "WAIT(w@/!)" "PLAN(p)" "|" "DONE(d!)" "CANCELLED(c@)"))) - + '((sequence "TODO(t)" "NEXT(n)" "ACTIVE(a!)" "WAIT(w@/!)" "|" "DONE(d!)" "CANCELLED(c@)"))) + ;; Customize note prompts (setq org-log-note-headings '((done . "CLOSING NOTE %t") @@ -1077,7 +1022,7 @@ Automatic task state management when clocking in/out. Tasks automatically become org-clock-out-when-done t org-clock-persist t org-clock-persist-query-resume nil) - + ;; Helper function: detect if heading is a project (defun my/is-project-p () "Any task with a todo keyword subtask." @@ -1126,29 +1071,24 @@ Skips capture tasks and projects." ((and (member (org-get-todo-state) (list "ACTIVE")) (my/is-project-p)) "TODO")))) - + :bind (("<f11>" . org-clock-goto) ("C-c C-x C-i" . org-clock-in) ("C-c C-x C-o" . org-clock-out))) #+end_src -*** effort and complexity enhancements - -Better effort estimates for deep work sessions and automatic complexity mapping. +*** effort and complexity management #+begin_src emacs-lisp (with-eval-after-load 'org - ;; Update effort values for longer focus sessions (night owl, deep work) - ;; Added 4h, 8h, 16h, 40h for multi-hour deep work blocks (setq org-global-properties - '(("EFFORT_ALL" . "0:30 1:00 2:00 4:00 8:00 16:00 40:00") + '(("EFFORT_ALL" . "0:15 0:30 1:00 2:00 3:00 5:00 8:00") ("COMPLEXITY_ALL" . "low medium high") - ("PRIORITY_ALL" . "A B C D"))) - - ;; Enhanced column view format with clocksum comparison + ("PRIORITY_ALL" . "A B C"))) + (setq org-columns-default-format "%40ITEM(Task) %TODO %10EFFORT{+} %10CLOCKSUM %10PROGRESS %COMPLEXITY %DEADLINE") - + ;; Auto-set effort from complexity (already exists, keeping it here for reference) ;; Low complexity = 30 min, Medium = 2h, High = 5h (defun my/org-set-effort-from-complexity () @@ -1161,23 +1101,21 @@ Better effort estimates for deep work sessions and automatic complexity mapping. ((string= complexity "low") (org-set-property "EFFORT" "0:30")) ((string= complexity "medium") (org-set-property "EFFORT" "2:00")) ((string= complexity "high") (org-set-property "EFFORT" "5:00")))))) - + ;; Keybinding for manual effort setting (define-key org-mode-map (kbd "C-c e") 'my/org-set-effort-from-complexity)) #+end_src -*** project templates - -Interactive project creation with denote - includes structure, deadlines, timers, and clocktables. +*** my/create-project #+begin_src emacs-lisp (defun my/create-project () "Create a new project file with denote and comprehensive project structure." (interactive) (let* ((project-name (read-string "Project name: ")) - (tags (completing-read-multiple "Additional tags (comma-separated): " + (tags (completing-read-multiple "Additional tags (comma-separated): " '("work" "personal" "university" "learning"))) - (all-tags (cons "project" tags)) + (all-tags (append '("project" "agenda") tags)) (deadline-str (org-read-date nil nil nil "Project deadline (optional, RET to skip): ")) (effort-str (completing-read "Estimated total effort: " '("10h" "20h" "40h" "80h" "160h") nil nil "40h")) @@ -1192,15 +1130,15 @@ Interactive project creation with denote - includes structure, deadlines, timers (insert ":EFFORT: " effort-str "\n") (insert ":PROGRESS: 0%\n") (insert ":END:\n\n") - + (insert "** Overview\n\n") (insert "- Goal :: \n") (insert "- Why :: \n") (insert "- Success Criteria :: \n") (insert "- Status :: Planning\n\n") - + (insert "** Phases\n\n") - (insert "*** PLAN Phase 1: Planning & Research\n") + (insert "*** TODO Phase 1: Planning & Research\n") (when (and deadline-str (not (string-empty-p deadline-str))) (insert "DEADLINE: <" deadline-str ">\n")) (insert ":PROPERTIES:\n") @@ -1209,287 +1147,97 @@ Interactive project creation with denote - includes structure, deadlines, timers (insert "- [ ] Define scope\n") (insert "- [ ] Research requirements\n") (insert "- [ ] Break down into tasks\n\n") - - (insert "*** PLAN Phase 2: Implementation\n") + + (insert "*** TODO Phase 2: Implementation\n") (insert ":PROPERTIES:\n") (insert ":CREATED: " (format-time-string "[%Y-%m-%d %a %H:%M]") "\n") (insert ":END:\n\n") - - (insert "*** PLAN Phase 3: Review & Polish\n") + + (insert "*** TODO Phase 3: Review & Polish\n") (insert ":PROPERTIES:\n") (insert ":CREATED: " (format-time-string "[%Y-%m-%d %a %H:%M]") "\n") (insert ":END:\n\n") - + (insert "** Resources\n\n") (insert "- Links :: \n") (insert "- Files :: \n") (insert "- References :: \n\n") - + (insert "** Time Tracking\n\n") (insert "#+BEGIN: clocktable :scope file :maxlevel 3 :emphasize nil :link t\n") (insert "#+END:\n\n") (insert "Update with C-c C-c on the BEGIN line\n\n") - + (insert "** Status Updates\n\n") (insert "Use =C-c C-x C-c= for column view to update PROGRESS and see overview.\n\n") - + (insert "** Retrospective\n\n") (insert "- What worked :: \n") (insert "- What didn't :: \n") (insert "- Lessons learned :: \n") (insert "- Would do differently :: \n") - + (org-mode) (goto-char (point-min)) (search-forward "- Goal :: " nil t))) #+end_src -*** daily review - your way - -Flexible end-of-day closure ritual. Use whenever you feel like wrapping up the day. - -#+begin_src emacs-lisp -(defun my/daily-review () - "Append a simple daily review to today's journal - whenever you feel like it." - (interactive) - (require 'denote) - (require 'denote-journal) - (let* ((today (format-time-string "%Y-%m-%d")) - (journal-files (denote-directory-files "journal")) - (today-journal (seq-find - (lambda (file) - (string-match-p today (file-name-nondirectory file))) - journal-files))) - - ;; Create or open today's journal - (if today-journal - (find-file today-journal) - (denote-journal-new-or-existing-entry)) - - ;; Go to end and add review section - (goto-char (point-max)) - (unless (save-excursion - (beginning-of-line) - (looking-at "^\\*\\* Day Closed")) - (insert "\n** Day Closed " (format-time-string "[%H:%M]") "\n\n")) - - (insert "*** What I did today\n") - (insert "#+BEGIN: clocktable :scope agenda :maxlevel 2 :block today\n") - (insert "#+END:\n\n") - - (insert "*** Brain dump\n") - (insert "Thoughts, notes, captures, whatever:\n\n") - - (insert "*** Projects check\n") - (insert "Quick status (or skip if nothing changed):\n") - (insert "- \n\n") - - (insert "*** Tomorrow\n") - (insert "What to focus on (1-3 things):\n") - (insert "- \n\n") - - (insert "*** How I felt\n") - (insert "- Energy: \n") - (insert "- Focus: \n") - (insert "- Notes: \n\n") - - (org-mode) - (goto-char (point-max)) - (search-backward "*** Brain dump" nil t) - (forward-line 2) - (end-of-line))) -#+end_src - -*** reflection template - -For when YOU feel like doing a bigger review - no schedule, no pressure. - -#+begin_src emacs-lisp -(defun my/reflection () - "Create a reflection note - use whenever you feel like reviewing progress." - (interactive) - (require 'denote) - (let* ((title (read-string "Reflection on: " "Recent progress")) - (file-name (denote title '("reflection")))) - (find-file file-name) - (goto-char (point-max)) - (insert "\n* " title "\n\n") - - (insert "** Time spent recently\n\n") - (insert "#+BEGIN: clocktable :scope agenda :maxlevel 2 :block thisweek\n") - (insert "#+END:\n\n") - (insert "Or change to :block lastweek, :block thismonth, etc.\n\n") - - (insert "** What's working?\n") - (insert "- \n\n") - - (insert "** What's not working?\n") - (insert "- \n\n") - - (insert "** Projects status\n") - (insert "#+BEGIN: columnview :id global :match \"project\" :format \"%ITEM %PROGRESS %EFFORT\"\n") - (insert "#+END:\n\n") - - (insert "** What needs attention?\n") - (insert "- \n\n") - - (insert "** Ideas / Changes\n") - (insert "- \n") - - (org-mode) - (goto-char (point-min)) - (search-forward "** What's working?" nil t) - (forward-line 1) - (end-of-line))) -#+end_src - -*** time block captures - -Schedule everything - work, meals, personal time - with interactive time blocks. +*** org-capture helpers #+begin_src emacs-lisp (defun my/org-capture-timeblock-to-journal () - "Capture a time block to today's journal (refile later if needed)." + "Capture function: jump to today's journal for a timeblock." (require 'denote) (require 'denote-journal) - (let* ((description (read-string "What: ")) - (datetime (org-read-date t nil nil "When (date + time): ")) - (duration (completing-read "Duration: " - '("30m" "1h" "1h30m" "2h" "3h" "4h" "6h" "8h") - nil nil "2h")) - (type (completing-read "Type: " - '("Work" "Personal" "Meal" "Break" "Focus" "Learning" "Exercise") - nil nil "Work")) - (today (format-time-string "%Y-%m-%d")) + (let* ((today (format-time-string "%Y-%m-%d")) (journal-files (denote-directory-files "journal")) (today-journal (seq-find (lambda (file) (string-match-p today (file-name-nondirectory file))) journal-files))) - - ;; Open or create today's journal (if today-journal (find-file today-journal) (denote-journal-new-or-existing-entry)) - - ;; Go to end and add time block (goto-char (point-max)) - (insert "\n* TODO " description "\n") - (insert "SCHEDULED: <" datetime ">\n") - (insert ":PROPERTIES:\n") - (insert ":DURATION: " duration "\n") - (insert ":TYPE: " type "\n") - (insert ":CREATED: " (format-time-string "[%Y-%m-%d %a %H:%M]") "\n") - (insert ":END:\n\n") - (insert "Capture in journal - refile with C-c C-w if needed\n") - (current-buffer))) + (insert "\n* Timeblock\n"))) (defun my/org-capture-recurring-to-journal () - "Capture a recurring time block to today's journal (habits like meals, exercise)." + "Capture function: jump to today's journal for a recurring task." (require 'denote) (require 'denote-journal) - (let* ((description (read-string "What (recurring): ")) - (start-date (org-read-date nil nil nil "Start date: ")) - (time (read-string "Time (HH:MM): " "12:00")) - (repeat (completing-read "Repeat: " - '(".+1d" ".+2d" ".+1w" ".+1m") - nil nil ".+1d")) - (duration (completing-read "Duration: " - '("15m" "30m" "1h" "1h30m" "2h") - nil nil "1h")) - (type (completing-read "Type: " - '("Meal" "Exercise" "Break" "Routine") - nil nil "Meal")) - (today (format-time-string "%Y-%m-%d")) + (let* ((today (format-time-string "%Y-%m-%d")) (journal-files (denote-directory-files "journal")) (today-journal (seq-find (lambda (file) (string-match-p today (file-name-nondirectory file))) journal-files))) - - ;; Open or create today's journal (if today-journal (find-file today-journal) (denote-journal-new-or-existing-entry)) - - ;; Go to end and add recurring block (goto-char (point-max)) - (insert "\n* TODO " description "\n") - (insert "SCHEDULED: <" start-date " " time " " repeat ">\n") - (insert ":PROPERTIES:\n") - (insert ":STYLE: habit\n") - (insert ":DURATION: " duration "\n") - (insert ":TYPE: " type "\n") - (insert ":CREATED: " (format-time-string "[%Y-%m-%d %a %H:%M]") "\n") - (insert ":END:\n\n") - (insert "Recurring habit - tracked with org-habit. Refile with C-c C-w if needed.\n") - (current-buffer))) + (insert "\n* Recurring\n"))) (defun my/org-capture-meeting-to-journal () - "Capture a meeting to today's journal (can refile to separate file later if needed)." + "Capture function: jump to today's journal for a meeting note." (require 'denote) (require 'denote-journal) - (let* ((topic (read-string "Meeting topic: ")) - (datetime (org-read-date t nil nil "When (date + time): ")) - (duration (completing-read "Duration: " - '("15m" "30m" "1h" "1h30m" "2h") - nil nil "1h")) - (participants (read-string "Participants (optional): ")) - (today (format-time-string "%Y-%m-%d")) + (let* ((today (format-time-string "%Y-%m-%d")) (journal-files (denote-directory-files "journal")) (today-journal (seq-find (lambda (file) (string-match-p today (file-name-nondirectory file))) journal-files))) - - ;; Open or create today's journal (if today-journal (find-file today-journal) (denote-journal-new-or-existing-entry)) - - ;; Go to end and add meeting (goto-char (point-max)) - (insert "\n* Meeting: " topic "\n") - (insert "SCHEDULED: <" datetime ">\n") - (insert ":PROPERTIES:\n") - (insert ":DURATION: " duration "\n") - (insert ":TYPE: Meeting\n") - (insert ":CREATED: " (format-time-string "[%Y-%m-%d %a %H:%M]") "\n") - (insert ":END:\n\n") - (when (and participants (not (string-empty-p participants))) - (insert "** Attendees\n") - (insert "- " participants "\n\n")) - (insert "** Agenda\n") - (insert "- \n\n") - (insert "** Notes\n\n") - (insert "** Action Items\n") - (insert "- [ ] \n\n") - (insert "Captured in journal - refile to separate meeting file with C-c C-w if needed\n") - (org-mode) - (search-backward "** Agenda" nil t) - (forward-line 1) - (end-of-line) - (current-buffer))) + (insert "\n* Meeting: "))) -;; Add to org-capture-templates (captures to journal, refile later if needed) -(with-eval-after-load 'org-capture - (add-to-list 'org-capture-templates - '("b" "Time Block" plain - (function my/org-capture-timeblock-to-journal) - "" :immediate-finish t :jump-to-captured t)) - - (add-to-list 'org-capture-templates - '("r" "Recurring Block" plain - (function my/org-capture-recurring-to-journal) - "" :immediate-finish t :jump-to-captured t)) - - (add-to-list 'org-capture-templates - '("m" "Meeting" plain - (function my/org-capture-meeting-to-journal) - "" :immediate-finish nil :jump-to-captured t))) +;; capture templates are merged in the org-capture section below #+end_src + ** notation *** org-noter @@ -1541,7 +1289,7 @@ Schedule everything - work, meals, personal time - with interactive time blocks. (defun my/org-capture-denote-deadline () (let* ((context (read-string "Task with deadline: ")) (deadline (org-read-date t nil nil "Deadline: ")) - (file-name (denote nil '("task")))) + (file-name (denote nil '("agenda")))) (find-file file-name) (goto-char (point-min)) (forward-line 4) @@ -1551,7 +1299,7 @@ Schedule everything - work, meals, personal time - with interactive time blocks. (defun my/org-capture-denote-scheduled () (let* ((context (read-string "Scheduled task: ")) (schedule (org-read-date t nil nil "Schedule: ")) - (file-name (denote nil '("task")))) + (file-name (denote nil '("agenda")))) (find-file file-name) (goto-char (point-min)) (forward-line 4) @@ -1561,8 +1309,8 @@ Schedule everything - work, meals, personal time - with interactive time blocks. (defun my/org-capture-denote-task () (let* ((context (read-string "Task: ")) (todo-state (completing-read "TODO state: " - '("ACTIVE" "NEXT" "TODO" "WAIT" "PLAN"))) - (file-name (denote nil '("task")))) + '("ACTIVE" "NEXT" "TODO" "WAIT"))) + (file-name (denote nil '("agenda")))) (find-file file-name) (goto-char (point-min)) (forward-line 4) @@ -1579,7 +1327,16 @@ Schedule everything - work, meals, personal time - with interactive time blocks. "" :immediate-finish t :jump-to-captured t) ("s" "Scheduled" plain (function my/org-capture-denote-scheduled) - "" :immediate-finish t :jump-to-captured t)))) + "" :immediate-finish t :jump-to-captured t) + ("b" "Timeblock" plain + (function my/org-capture-timeblock-to-journal) + "" :immediate-finish nil :jump-to-captured t) + ("r" "Recurring" plain + (function my/org-capture-recurring-to-journal) + "" :immediate-finish t :jump-to-captured t) + ("m" "Meeting" plain + (function my/org-capture-meeting-to-journal) + "" :immediate-finish nil :jump-to-captured t)))) #+end_src ** org-super-agenda @@ -1601,278 +1358,176 @@ Schedule everything - work, meals, personal time - with interactive time blocks. #+end_src -** new agenda +** agenda #+begin_src emacs-lisp +;;; --- Agenda display settings --- + +(setq org-agenda-window-setup 'current-window + org-agenda-inhibit-startup t + org-agenda-remove-tags t + org-agenda-dim-blocked-tasks nil + org-agenda-skip-scheduled-if-done t + org-agenda-skip-deadline-if-done t) + +(setq org-agenda-time-grid + '((daily today require-timed) + (800 1000 1200 1400 1600 1800 2000) + "......" "________________")) + +(setq org-agenda-current-time-string + "--- NOW ---------------") + +(setq org-agenda-prefix-format + '((agenda . " %i %?-12t% s") + (todo . " %i ") + (tags . " %i ") + (search . " %i "))) + +;;; --- Agenda views --- +;; +;; d - Today: daily driver, what to focus on now +;; w - Week: calendar + upcoming + backlog +;; p - Projects: all project tasks by state + (setq org-agenda-custom-commands '( - ("d" "Daily Dashboard" + ;; ── Today ────────────────────────────────────────────── + ("d" "Today" ( - (org-ql-block '(and (scheduled :to today) - (not (done))) - ((org-ql-block-header "📅 Today's Schedule") + ;; Block 1: standard agenda — time-grid, NOW line, scheduled + deadlines + (agenda "" + ((org-agenda-span 1) + (org-agenda-start-day ".") + (org-deadline-warning-days 3) + (org-scheduled-past-days 0) + (org-agenda-day-face-function (lambda (date) 'org-agenda-date)) + (org-agenda-overriding-header "") (org-super-agenda-groups - '( - (:name "🌙 Night (00:00-06:00)" - :and (:scheduled today :time-grid t) - :pred (lambda (item) - (when-let ((time (org-get-scheduled-time (point)))) - (let ((hour (nth 2 (decode-time time)))) - (and (>= hour 0) (< hour 6))))) + '((:name "Overdue" + :scheduled past + :deadline past + :order 0) + (:name "Schedule" + :time-grid t :order 1) - (:name "🌅 Morning (06:00-12:00)" - :and (:scheduled today :time-grid t) - :pred (lambda (item) - (when-let ((time (org-get-scheduled-time (point)))) - (let ((hour (nth 2 (decode-time time)))) - (and (>= hour 6) (< hour 12))))) + (:name "Deadlines" + :deadline today :order 2) - (:name "☀️ Afternoon (12:00-18:00)" - :and (:scheduled today :time-grid t) - :pred (lambda (item) - (when-let ((time (org-get-scheduled-time (point)))) - (let ((hour (nth 2 (decode-time time)))) - (and (>= hour 12) (< hour 18))))) - :order 3) - (:name "🌆 Evening (18:00-00:00)" - :and (:scheduled today :time-grid t) - :pred (lambda (item) - (when-let ((time (org-get-scheduled-time (point)))) - (let ((hour (nth 2 (decode-time time)))) - (and (>= hour 18) (< hour 24))))) - :order 4) (:discard (:anything t)))))) - (org-ql-block '(and (or (tags "self") - (tags "university")) - (not (scheduled)) - (not (tags "project")) + ;; Block 2: active + next tasks (what you can work on right now) + (org-ql-block '(and (todo "ACTIVE" "NEXT") (not (done))) - ((org-ql-block-header "📋 Unscheduled Tasks") + ((org-ql-block-header "In Progress") (org-super-agenda-groups - '( - (:name "🔥 ACTIVE (Currently Working)" + '((:name "ACTIVE" :todo "ACTIVE" :order 1) - (:name "⏭️ NEXT (Ready to Start)" + (:name "NEXT" :todo "NEXT" :order 2) - (:name "📝 TODO (Backlog)" - :todo "TODO" - :order 3) - (:name "⏸️ WAIT (Blocked)" - :todo "WAIT" - :order 4) (:discard (:anything t)))))) - (org-ql-block '(and (tags "project") + ;; Block 3: waiting items + (org-ql-block '(and (todo "WAIT") (not (done))) - ((org-ql-block-header "🎯 Project Tasks") + ((org-ql-block-header "Waiting On") (org-super-agenda-groups - '( - (:name "🔥 ACTIVE Projects" - :todo "ACTIVE" - :order 1) - (:name "⏭️ NEXT Up" - :todo "NEXT" - :order 2) - (:name "📝 TODO" - :todo "TODO" - :order 3) - (:discard (:anything t))))))) - ((org-agenda-span 'day))) - - ("p" "Project Overview" - ((org-ql-block '(and (tags "project") - (not (done))) - ((org-ql-block-header "All Project Tasks") - (org-super-agenda-groups - '( - (:name "ACTIVE" - :todo "ACTIVE" - :order 1) - (:name "NEXT" - :todo "NEXT" - :order 2) - (:name "TODO" - :todo "TODO" - :order 3) - (:name "WAIT" - :todo "WAIT" - :order 4) - (:discard (:anything t))))))) - ((org-agenda-span 'day))) - - ("e" "Evaluation Mode - Failed Tasks" - ((org-ql-block '(and (scheduled :to yesterday) - (not (done)) - (not (habit))) - ((org-ql-block-header "Overdue Tasks") - (org-super-agenda-groups - '( - (:name "ACTIVE" - :todo "ACTIVE" - :order 1) - (:name "NEXT" - :todo "NEXT" - :order 2) - (:name "TODO" - :todo "TODO" - :order 3) - (:discard (:anything t)))))) - - (org-ql-block '(and (scheduled :from -7 :to -1) - (not (done)) - (not (habit))) - ((org-ql-block-header "This Week's Unfinished") - (org-super-agenda-groups - '( - (:name "By Day" - :scheduled t - :order 1) - (:discard (:anything t))))))) - ((org-agenda-span 'week))) - - ("w" "Weekly Overview" - ((org-ql-block '(and (or (deadline auto) - (scheduled :to 7)) - (or (tags "self") - (tags "university")) - (not (tags "project")) - (not (done)) - (not (habit))) - ((org-ql-block-header "Upcoming Deadlines & Scheduled") - (org-super-agenda-groups - '( - (:name "Deadlines" - :deadline t - :order 1) - (:name "Scheduled" - :scheduled t - :order 2) - (:discard (:anything t)))))) + '((:anything t))))))) - (org-ql-block '(and (ts-active :from today :to 7 :with-time t) - (or (tags "self") - (tags "university")) - (not (tags "project")) - (not (done))) - ((org-ql-block-header "Appointments This Week") - (org-super-agenda-groups - '( - (:name "By Time" - :anything t - :order 1))))) + ;; ── Week ─────────────────────────────────────────────── + ("w" "Week" + ( + ;; Block 1: today in detail + (agenda "" + ((org-agenda-span 1) + (org-deadline-warning-days 0) + (org-scheduled-past-days 0) + (org-agenda-day-face-function (lambda (date) 'org-agenda-date)) + (org-agenda-overriding-header "Today") + (org-super-agenda-groups + '((:name "Overdue" + :scheduled past + :deadline past + :order 0) + (:name "Schedule" + :time-grid t + :order 1) + (:discard (:anything t)))))) - (org-ql-block '(and (habit) - (or (tags "self") - (tags "university")) - (not (tags "project"))) - ((org-ql-block-header "Habits") - (org-super-agenda-groups - '( - (:name "Daily Habits" - :habit t - :order 1) - (:discard (:anything t))))))) - ((org-agenda-span 'week))) + ;; Block 2: next 6 days + (agenda "" + ((org-agenda-start-on-weekday nil) + (org-agenda-start-day "+1d") + (org-agenda-span 6) + (org-deadline-warning-days 0) + (org-agenda-overriding-header "Next 6 Days") + (org-super-agenda-groups + '((:anything t))))) - ("s" "Self & University Tasks" - ((org-ql-block '(and (or (tags "self") - (tags "university")) - (not (tags "project")) - (not (done))) - ((org-ql-block-header "All Self & University Tasks") - (org-super-agenda-groups - '( - (:name "ACTIVE" - :todo "ACTIVE" - :order 1) - (:name "NEXT" - :todo "NEXT" - :order 2) - (:name "TODO" - :todo "TODO" - :order 3) - (:name "WAIT" - :todo "WAIT" - :order 4) - (:discard (:anything t)))))))) + ;; Block 3: upcoming deadlines beyond this week + (agenda "" + ((org-agenda-time-grid nil) + (org-agenda-start-on-weekday nil) + (org-agenda-start-day "+7d") + (org-agenda-span 14) + (org-agenda-show-all-dates nil) + (org-agenda-entry-types '(:deadline)) + (org-agenda-overriding-header "Upcoming Deadlines (+14d)") + (org-super-agenda-groups + '((:anything t))))) - ("c" "Complexity Matrix" - ((org-ql-block '(and (property "COMPLEXITY" "high") - (property "EFFORT") - (not (done))) - ((org-ql-block-header "High Complexity Tasks") - (org-super-agenda-groups - '( - (:name "ACTIVE" - :todo "ACTIVE" - :order 1) - (:name "NEXT" - :todo "NEXT" - :order 2) - (:discard (:anything t)))))) + ;; Block 4: unscheduled backlog + (org-ql-block '(and (todo) + (not (done)) + (not (scheduled)) + (not (deadline))) + ((org-ql-block-header "Backlog (unscheduled)") + (org-super-agenda-groups + '((:name "ACTIVE" :todo "ACTIVE" :order 1) + (:name "NEXT" :todo "NEXT" :order 2) + (:name "TODO" :todo "TODO" :order 3) + (:name "WAIT" :todo "WAIT" :order 4) + (:discard (:anything t)))))))) - (org-ql-block '(and (property "COMPLEXITY" "low") - (property "EFFORT") + ;; ── Projects ─────────────────────────────────────────── + ("p" "Projects" + ((org-ql-block '(and (tags "project") (not (done))) - ((org-ql-block-header "Quick Wins - Low Complexity") + ((org-ql-block-header "All Project Tasks") (org-super-agenda-groups - '( - (:name "Tasks" - :not (:todo "WAIT") - :order 1) + '((:name "ACTIVE" :todo "ACTIVE" :order 1) + (:name "NEXT" :todo "NEXT" :order 2) + (:name "TODO" :todo "TODO" :order 3) + (:name "WAIT" :todo "WAIT" :order 4) (:discard (:anything t)))))))))) -(setq org-agenda-remove-tags t) - -;; (setq split-width-threshold 0) -;; (setq split-height-threshold nil) - -(setq org-priority-faces - '((?A . (:foreground "#ff6b6b" :weight bold)) - (?B . (:foreground "#ffd93d" :weight bold)) - (?C . (:foreground "#6bcf7f" :weight bold)))) - -(setq org-columns-default-format - "%40ITEM(Task) %10TODO(State) %10EFFORT(Effort) %10COMPLEXITY(Complexity) %PRIORITY") - -;; org-global-properties now defined in workflow enhancements section above - -(setq org-agenda-time-grid - '((daily today require-timed) - (800 1000 1200 1400 1600 1800 2000) - "......" "________________")) - -(setq org-agenda-current-time-string - "--- NOW ---------------") - -;; org-todo-keywords now defined in workflow enhancements section above +;;; --- Theme-adaptive TODO keyword faces --- (setq org-todo-keyword-faces - '(("TODO" . (:inherit (warning org-todo))) - ("NEXT" . (:inherit (font-lock-type-face org-todo))) - ("ACTIVE" . (:inherit (bold org-todo))) - ("WAIT" . (:inherit (shadow org-todo))) - ("DONE" . (:inherit (success org-todo))) + '(("TODO" . (:inherit (warning org-todo))) + ("NEXT" . (:inherit (font-lock-type-face org-todo))) + ("ACTIVE" . (:inherit (bold org-todo))) + ("WAIT" . (:inherit (shadow org-todo))) + ("DONE" . (:inherit (success org-todo))) ("CANCELLED" . (:inherit (shadow org-done))))) (defun my/update-org-modern-faces () (setq org-modern-todo-faces - `(("TODO" :background ,(face-attribute 'warning :foreground) - :foreground ,(face-attribute 'default :background)) - ("ACTIVE" :background ,(face-attribute 'error :foreground) - :foreground ,(face-attribute 'default :background)) - ("DONE" :background ,(face-attribute 'success :foreground) - :foreground ,(face-attribute 'default :background)) + `(("TODO" :background ,(face-attribute 'warning :foreground) + :foreground ,(face-attribute 'default :background)) + ("ACTIVE" :background ,(face-attribute 'error :foreground) + :foreground ,(face-attribute 'default :background)) + ("DONE" :background ,(face-attribute 'success :foreground) + :foreground ,(face-attribute 'default :background)) ("CANCELLED" :background ,(face-attribute 'shadow :foreground) - :foreground ,(face-attribute 'default :background))))) + :foreground ,(face-attribute 'default :background))))) (add-hook 'after-load-theme-hook #'my/update-org-modern-faces) (my/update-org-modern-faces) -;; org-set-effort-from-complexity now defined in workflow enhancements section above +;;; --- Tag cleanup in agenda buffer --- (defun my/org-agenda-remove-tags () (save-excursion @@ -2000,7 +1655,7 @@ Denote fitself focused on the last versions to have a core for note taking and t :ensure t :after org :config - (setq denote-agenda-include-regexp "task") + (setq denote-agenda-include-regexp "_agenda") (denote-agenda-insinuate)) #+end_src @@ -2011,15 +1666,38 @@ Denote fitself focused on the last versions to have a core for note taking and t :ensure t :config (setopt denote-journal-title-format 'day-date-month-year)) + +(defun my/denote-journal-template () + "Insert journal structure into a new journal entry. +Only inserts when the buffer has just the front-matter (fresh file)." + (when (and (buffer-file-name) + (string-match-p "journal" (buffer-file-name)) + (<= (count-lines (point-min) (point-max)) 6)) + (goto-char (point-max)) + (insert + "\n* \n" + "\n#+BEGIN: clocktable :scope file :maxlevel 3 :emphasize nil :link t\n" + "#+END:\n" + "\n* \n" + "\n** Plan the day\n" + ":LOGBOOK:\n" + ":END:\n" + "\n* \n" + ":PROPERTIES:\n" + ":VISIBILITY: folded\n" + ":END:\n"))) + +(advice-add 'denote-journal-new-or-existing-entry :after + (lambda (&rest _) (my/denote-journal-template))) #+end_src ** config #+begin_src emacs-lisp -(defcustom my/denote-task-filename-component-regexp - "\\(?:[-_.]\\|:\\)task\\(?:[-_.]\\|:\\|$\\)" - "Regexp matching a filename component that denotes the 'task' tag. -Works on the base filename (without extension), e.g. matches \"-task\", \":task:\", \"_task_\"." +(defcustom my/denote-agenda-filename-component-regexp + "\\(?:[-_.]\\|:\\)agenda\\(?:[-_.]\\|:\\|$\\)" + "Regexp matching a filename component that denotes the 'agenda' tag. +Works on the base filename (without extension), e.g. matches \"-agenda\", \":agenda:\", \"_agenda_\"." :type 'string) (defun my/denote--make-unique-filename (dir base ext) @@ -2032,8 +1710,8 @@ Works on the base filename (without extension), e.g. matches \"-task\", \":task: (setq count (1+ count))) candidate)) -(defun my/denote-remove-task-filetag-and-silent-rename () - "If current headline became DONE in a Denote note, remove :task: filetag and remove 'task' from filename silently. +(defun my/denote-remove-agenda-filetag-and-silent-rename () + "If current headline became DONE in a Denote note, remove :agenda: filetag and remove 'agenda' from filename silently. - Only acts if there are no other non-DONE TODOs in the same file. - Does not call Denote's interactive rename command (no buffers opened)." (when (and (derived-mode-p 'org-mode) @@ -2054,12 +1732,12 @@ Works on the base filename (without extension), e.g. matches \"-task\", \":task: nil 'file) nil))) (unless has-other - ;; 1) Remove :task: from #+filetags: + ;; 1) Remove :agenda: from #+filetags: (save-excursion (goto-char (point-min)) (when (re-search-forward "^#\\+filetags:\\s-*\\(.*\\)$" nil t) (let* ((tags (match-string 1)) - (clean (replace-regexp-in-string ":task:" "" tags)) + (clean (replace-regexp-in-string ":agenda:" "" tags)) (clean (replace-regexp-in-string "::+" ":" clean)) (clean (replace-regexp-in-string "^:\\|:$" "" clean))) (if (string-empty-p clean) @@ -2073,15 +1751,15 @@ Works on the base filename (without extension), e.g. matches \"-task\", \":task: (name (file-name-nondirectory file)) (ext (file-name-extension name)) ;; "org" (base (file-name-sans-extension name)) - ;; remove the task component from the base - (new-base (replace-regexp-in-string my/denote-task-filename-component-regexp - "" - base))) + ;; remove the agenda component from the base + (new-base (replace-regexp-in-string my/denote-agenda-filename-component-regexp + "" + base))) (when (and new-base (not (string= new-base base))) ;; cleanup repeated separators: convert multiple '-'/'_'/'..' to single '-' (setq new-base (replace-regexp-in-string "[-_.:]+" - "-" - new-base)) + "-" + new-base)) ;; strip leading/trailing separators (setq new-base (replace-regexp-in-string "\\`[-_.:-]+" "" new-base)) (setq new-base (replace-regexp-in-string "[-_.:-]+\\'" "" new-base)) @@ -2089,16 +1767,16 @@ Works on the base filename (without extension), e.g. matches \"-task\", \":task: (let ((target (my/denote--make-unique-filename dir new-base ext))) (condition-case err (progn - (rename-file file target 1) ;; 1 = ok to overwrite, but we avoid collisions by uniqueness + (rename-file file target 1) ;; update current buffer to visit the new filename silently (set-visited-file-name target t t) ;; save changes (filetags update + new filename) (save-buffer) - (message "Denote: removed 'task' component from filename -> %s" (file-name-nondirectory target))) + (message "Denote: removed 'agenda' component from filename -> %s" (file-name-nondirectory target))) (error (message "Denote rename failed: %s" (error-message-string err))))))))))) -(add-hook 'org-after-todo-state-change-hook #'my/denote-remove-task-filetag-and-silent-rename) +(add-hook 'org-after-todo-state-change-hook #'my/denote-remove-agenda-filetag-and-silent-rename) #+end_src ** denote-menu @@ -2207,7 +1885,7 @@ Some goodies for better integration with org files. (setq tmr-sound-file "/usr/share/sounds/freedesktop/stereo/alarm-clock-elapsed.oga" tmr-notification-urgency 'normal tmr-description-list 'tmr-description-history) - + (tmr-mode-line-mode 1) (define-key global-map (kbd "C-c t") #'tmr-prefix-map)) #+end_src @@ -2233,7 +1911,7 @@ Some goodies for better integration with org files. :hook (after-init . vertico-mode) :custom - (vertico-count 16) + (vertico-count 10) (vertico-resize nil) (vertico-cycle nil) :bind (:map vertico-map @@ -2258,11 +1936,11 @@ Some goodies for better integration with org files. (setq vertico-posframe-parameters '((left-fringe . 12) ;; Fringes (right-fringe . 12) (accept-focus . t))) - (undecorated . nil) ;; Rounded frame + ;; (undecorated . nil) ;; Rounded frame :config (vertico-posframe-mode 1) - (setq vertico-posframe-width 124 ;; Narrow frame + (setq vertico-posframe-width 96 ;; Narrow frame vertico-posframe-height vertico-count ;; Default height ;; Don't create posframe for these commands vertico-multiform-commands '((consult-line (:not posframe)) @@ -2482,11 +2160,10 @@ completion-category-overrides '((file (styles partial-completion))))) ;; Customi (setq eglot-events-buffer-size 0) (setq eglot-report-progress nil) - (add-hook 'eglot-managed-mode-hook - (lambda () + (add-hook 'eglot-managed-mode-hook + (lambda () (eglot-inlay-hints-mode -1) - (when (fboundp 'eglot-semantic-tokens-mode) - (eglot-semantic-tokens-mode 1)))) + (eglot-semantic-tokens-mode 1))) (setq eglot-ignored-server-capabilities '(:inlayhintprovider :documenthighlightprovider))) @@ -2800,7 +2477,8 @@ ily <3. (use-package vterm :ensure t :config - (setq vterm-timer-delay 0.001)) + (setq vterm-timer-delay 0.0001) + (setq vterm-shell "fish")) #+end_src ** multi-vterm @@ -2811,6 +2489,25 @@ ily <3. :defer t) #+end_src +** eee.el + +#+begin_src emacs-lisp +(use-package eee + :ensure t + :straight (:type git :host github :repo "eval-exec/eee.el" + :files (:defaults "*.el" "*.sh")) + :config + (setq ee-terminal-command "kitty")) +#+end_src + +* pyqt + +#+begin_src emacs-lisp +(setq eaf-pyqterminal-font-size 20 + eaf-pyqterminal-refresh-ms 3 + eaf-pyqterminal-font-family "Maple Mono NF") +#+end_src + * olivetti #+begin_src emacs-lisp @@ -2972,20 +2669,14 @@ ily <3. (modify-syntax-entry ?_ "w") -;; (defun my/eldoc-and-jump () -;; (interactive) -;; (if (display-graphic-p) -;; (call-interactively 'eldoc-box-help-at-point) -;; (progn -;; (eldoc-doc-buffer) -;; (when-let ((eldoc-win (get-buffer-window "*eldoc*"))) -;; (select-window eldoc-win))))) - (defun my/eldoc-and-jump () + "Show documentation at point. Works in both GUI and terminal." (interactive) - (call-interactively 'eldoc-box-help-at-point)) + (if (display-graphic-p) + (eldoc-box-help-at-point) + (eldoc-doc-buffer t))) -;; (define-key evil-normal-state-map (kbd "K") #'my/eldoc-and-jump) +(define-key evil-normal-state-map (kbd "K") #'my/eldoc-and-jump) #+end_src *** evil yank/paste keymaps @@ -3724,7 +3415,7 @@ ily <3. :straight (:host github :repo "honmaple/emacs-maple-modeline") :hook (after-init . maple-modeline-mode) :config - (setq maple-modeline-separator 'arrow) + (setq maple-modeline-separator 'nil) (setq maple-modeline-height 25) (setq maple-modeline-icon t) @@ -3738,6 +3429,27 @@ ily <3. :format (propertize (downcase (format-time-string " %I:%M %p ")) 'face 'bold)) + (maple-modeline-define-segment org-clock-task + :if (and (fboundp 'org-clocking-p) (org-clocking-p)) + :format + (let ((heading (truncate-string-to-width + (substring-no-properties org-clock-heading) 35 nil nil "..."))) + (concat + (maple-modeline--concat-or + (maple-modeline--icon 'mdicon "nf-md-clock_outline" face) + "CLK") + " " (propertize heading 'face face + 'mouse-face 'mode-line-highlight + 'help-echo "Go to clocked task" + 'local-map (make-mode-line-mouse-map 'mouse-1 'org-clock-goto))))) + + (maple-modeline-define-segment tmr-timer + :if (and (bound-and-true-p tmr-mode-line-mode) + (fboundp 'tmr-mode-line--get-active-timers) + (tmr-mode-line--get-active-timers)) + :format + (string-trim (or tmr-mode-line-string ""))) + (maple-modeline-define my-custom-style :left ((evil :left (bar :left "")) macro @@ -3746,8 +3458,9 @@ ily <3. version-control remote-host region) - :right (misc-info - narrow + :right (narrow + org-clock-task + tmr-timer python my-modeline-time process @@ -3805,9 +3518,9 @@ ily <3. (blink-cursor-mode 0) (setq-default cursor-type 'box) -(defvar cashmere/font-height 140) +(defvar cashmere/font-height 180) -(set-face-attribute 'default nil :family "MonoLisa Nerd Font" :weight 'regular :height cashmere/font-height) +(set-face-attribute 'default nil :family "Maple Mono NF" :weight 'regular :height cashmere/font-height) (set-face-attribute 'fixed-pitch nil :family "RobotoMono Nerd Font" :weight 'regular) (set-face-attribute 'variable-pitch nil :family "Poppins" :weight 'regular :height 1.1) @@ -4407,16 +4120,6 @@ ily <3. (setq auth-source-cache-expiry 300))) #+end_src -* eshell -#+begin_src emacs-lisp -(use-package eshell - :ensure nil - :straight nil) - -(use-package eshell-prompt-extras - :ensure t) -#+end_src - * zoom #+begin_src emacs-lisp @@ -4479,13 +4182,9 @@ ily <3. "d" '(:ignore t :wk "denote") "dj" '(denote-journal-new-or-existing-entry :wk "journal") "dd" '(denote-menu-list-notes t :wk "List all notes") - "dl" '(denote-link t :wk "Link note") "dg" '(consult-denote-grep t :wk "Search") "dn" '(denote t :wk "Create a new note") "dr" '(denote-rename-file t :wk "Rename Note") - "dp" '(my/create-project :wk "Create project") - "dR" '(my/daily-review :wk "Daily review") - "dD" '(my/reflection :wk "Reflection") "dtl" '(tmr-list-timers :wk "list timer") "dtt" '(tmr :wk "set timer") @@ -4534,13 +4233,7 @@ ily <3. "gs" '(magit-file-stage :wk "stage file") "gb" '(vc-annotate :wk "blame") - "o" '(:ignore t :wk "org/open") - "oa" '(:ignore t :wk "agenda") - "oad" '(org-agenda :wk "daily dashboard") - "oaw" '((lambda () (interactive) (org-agenda nil "w")) :wk "weekly overview") - "oap" '((lambda () (interactive) (org-agenda nil "p")) :wk "projects") - "oae" '((lambda () (interactive) (org-agenda nil "e")) :wk "evaluation") - "oac" '((lambda () (interactive) (org-agenda nil "c")) :wk "complexity matrix") + "o" '(:ignore t :wk "open") "h" '(:ignore t :wk "help") "hm" '(describe-mode :wk "mode") @@ -4686,7 +4379,6 @@ ily <3. "mC" '(rust-check :wk "check")) #+end_src - ** denote-menu keymaps #+begin_src emacs-lisp @@ -5017,13 +4709,6 @@ this package provides the ability to display rgb and hex colors. -* rg - -#+begin_src emacs-lisp -(use-package rg - :ensure t) -#+end_src - * profiler #+begin_src emacs-lisp diff --git a/custom-vars.el b/custom-vars.el new file mode 100644 index 0000000..57fbd53 --- /dev/null +++ b/custom-vars.el @@ -0,0 +1,30 @@ +;;; -*- lexical-binding: t -*- +(custom-set-variables + ;; custom-set-variables was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + '(custom-safe-themes + '("ba97af9709a771a2150e4bd79b7fc5312e4e7ea8ea0b07a1a87ed43f613dd197" + "d43860349c9f7a5b96a090ecf5f698ff23a8eb49cd1e5c8a83bb2068f24ea563" + default)) + '(safe-local-variable-values + '((eval progn + (add-to-list 'auto-mode-alist '("\\.html\\'" . jinja2-mode)) + (add-to-list 'auto-mode-alist '("\\.j2\\'" . jinja2-mode))))) + '(zoom-size '(0.382 . 0.618))) +(custom-set-faces + ;; custom-set-faces was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + '(org-document-title ((t (:height 1.6)))) + '(outline-1 ((t (:height 1.25)))) + '(outline-2 ((t (:height 1.2)))) + '(outline-3 ((t (:height 1.2)))) + '(outline-4 ((t (:height 1.2)))) + '(outline-5 ((t (:height 1.2)))) + '(outline-6 ((t (:height 1.2)))) + '(outline-7 ((t (:height 1.2)))) + '(outline-8 ((t (:height 1.2)))) + '(outline-9 ((t (:height 1.2))))) diff --git a/themes/noctalia-theme.el b/themes/noctalia-theme.el index 9518af8..08055f1 100644 --- a/themes/noctalia-theme.el +++ b/themes/noctalia-theme.el @@ -1,100 +1,78 @@ -;;; noctalia-theme.el --- Theme using Template SCSS variables -*- lexical-binding: t -*- +;;; noctalia-theme.el --- Noctalia theme for Emacs -*- lexical-binding: t -*- -;; Copyright (C) 2025 +;; Copyright (C) 2025 -;; Author: Generated (Improved) -;; Version: 1.2 +;; Author: Noctalia User Template (Fixed) +;; Version: 2.0 ;; Package-Requires: ((emacs "24.1")) ;; Keywords: faces ;;; Commentary: -;; A theme using Template SCSS variables with quality of life improvements: -;; - Better source block distinction -;; - Improved text visibility when selected -;; - Refined org-mode styling with hidden asterisks -;; - Enhanced contrast and readability -;; - Seamless integration of source blocks with consistent styling +;; Noctalia Emacs theme generated via user template. +;; Fixes the built-in template's misuse of MD3 container colors as foreground +;; text. All heading and text faces use surface-readable colors only. ;;; Code: -(deftheme noctalia "Theme using Template variables with quality of life improvements.") +(deftheme noctalia "Noctalia theme with proper color contrast.") -;; Define all the color variables (replaced by template processor) -(let* ((bg "#f6f2ee") - (err "#a5222f") - (err-container "#db9ea4") - (on-background "#3d2b5a") - (on-err "#f6f2ee") - (on-err-container "#3f0d12") - (on-primary "#f6f2ee") - (on-primary-container "#0f1a3e") - (on-secondary "#f6f2ee") - (on-secondary-container "#1b3122") - (on-surface "#3d2b5a") - (on-surface-variant "#534c45") - (on-tertiary "#f6f2ee") - (on-tertiary-container "#210f3e") - (outline-color "#824d5b") - (outline-variant "#ab7180") - (primary "#2848a9") - (primary-container "#a8b5db") - (secondary "#396847") - (secondary-container "#90c39f") - (shadow "#d3c7bb") - (surface "#f6f2ee") - (surface-container "#d3c7bb") - (surface-container-high "#cbbdaf") - (surface-container-highest "#c3b3a2") - (surface-container-low "#e4dcd4") - (surface-container-lowest "#efe9e3") - (surface-variant "#d3c7bb") - (tertiary "#6e33ce") - (tertiary-container "#d5c9e9") - ;; Map success colors to tertiary (as used in other templates) - (success "#6e33ce") - (on-success "#f6f2ee") - (success-container "#d5c9e9") - (on-success-container "#210f3e") - ;; Map fixed colors to regular colors - (primary-fixed "#2848a9") - (primary-fixed-dim "#a8b5db") - (secondary-fixed "#396847") - (secondary-fixed-dim "#90c39f") - (tertiary-fixed "#6e33ce") - (tertiary-fixed-dim "#d5c9e9") - (on-primary-fixed "#f6f2ee") - (on-primary-fixed-variant "#0f1a3e") - (on-secondary-fixed "#f6f2ee") - (on-secondary-fixed-variant "#1b3122") - (on-tertiary-fixed "#f6f2ee") - (on-tertiary-fixed-variant "#210f3e") - ;; Map inverse colors to surface variants - (inverse-on-surface "#3d2b5a") - (inverse-primary "#2848a9") - (inverse-surface "#f6f2ee") - ;; Map terminal colors (term0-term15) to available colors - (term0 "#f6f2ee") - (term1 "#a5222f") - (term2 "#6e33ce") - (term3 "#396847") - (term4 "#2848a9") - (term5 "#d5c9e9") - (term6 "#90c39f") - (term7 "#3d2b5a") - (term8 "#824d5b") - (term9 "#a5222f") - (term10 "#6e33ce") - (term11 "#396847") - (term12 "#2848a9") - (term13 "#d5c9e9") - (term14 "#90c39f") - (term15 "#3d2b5a")) +(let* (;; Core surface colors + (bg "#232136") + (fg "#e0def4") + (surface "#232136") + (on-surface "#e0def4") + (on-surface-variant "#cdcbe0") + (surface-variant "#373354") + (surface-container "#373354") + (surface-container-low "#2d2a45") + (surface-container-lowest "#27243c") + (surface-container-high "#3f3b61") + (surface-container-highest "#48426d") + + ;; Accent colors (always readable on surface) + (primary "#569fba") + (secondary "#a3be8c") + (tertiary "#c4a7e7") + (err "#eb6f92") + + ;; Container colors (for BACKGROUNDS only, never as foreground text) + (primary-container "#143b49") + (secondary-container "#496c2b") + (tertiary-container "#661fbd") + (err-container "#a00833") + + ;; On-color text (for text ON accent backgrounds) + (on-primary "#232136") + (on-secondary "#232136") + (on-tertiary "#232136") + (on-err "#232136") + + ;; On-container text (for text on container backgrounds) + (on-primary-container "#dbeaf0") + (on-secondary-container "#e5edde") + (on-tertiary-container "#e4d7f4") + (on-err-container "#f9d2dd") + + ;; Outline colors + (outline-color "#6b63af") + (outline-variant "#4a4383") + + ;; Shadow + (shadow "#000000") + + ;; Auto-lightness variants: lighten in dark mode, darken in light mode + ;; Used for heading levels 5-7, rainbow delimiters 5-7, terminal variants + (primary-variant "#39758b") + (secondary-variant "#7ca25c") + (tertiary-variant "#9c6bd7") + (err-variant "#e22c5f")) (custom-theme-set-faces 'noctalia - ;; Basic faces - `(default ((t (:background ,bg :foreground ,on-background)))) + + ;; === Basic faces === + `(default ((t (:background ,bg :foreground ,fg)))) `(cursor ((t (:background ,primary)))) `(highlight ((t (:background ,surface-container-high)))) `(region ((t (:background ,primary-container :foreground ,on-primary-container :extend t)))) @@ -107,12 +85,12 @@ `(shadow ((t (:foreground ,outline-variant)))) `(link ((t (:foreground ,primary :underline t)))) `(link-visited ((t (:foreground ,tertiary :underline t)))) - `(success ((t (:foreground ,success)))) + `(success ((t (:foreground ,tertiary)))) `(warning ((t (:foreground ,secondary)))) `(error ((t (:foreground ,err)))) `(match ((t (:background ,secondary-container :foreground ,on-secondary-container)))) - - ;; Font-lock + + ;; === Font-lock === `(font-lock-builtin-face ((t (:foreground ,primary)))) `(font-lock-comment-face ((t (:foreground ,outline-color :slant italic)))) `(font-lock-comment-delimiter-face ((t (:foreground ,outline-variant)))) @@ -121,69 +99,69 @@ `(font-lock-function-name-face ((t (:foreground ,primary :weight bold)))) `(font-lock-keyword-face ((t (:foreground ,secondary :weight bold)))) `(font-lock-string-face ((t (:foreground ,tertiary)))) - `(font-lock-type-face ((t (:foreground ,primary-fixed)))) + `(font-lock-type-face ((t (:foreground ,primary)))) `(font-lock-variable-name-face ((t (:foreground ,on-surface)))) `(font-lock-warning-face ((t (:foreground ,err :weight bold)))) - `(font-lock-preprocessor-face ((t (:foreground ,secondary-fixed-dim)))) - `(font-lock-negation-char-face ((t (:foreground ,tertiary-fixed)))) + `(font-lock-preprocessor-face ((t (:foreground ,on-surface-variant)))) ;; FIX: was secondary_fixed_dim (invisible) + `(font-lock-negation-char-face ((t (:foreground ,tertiary)))) - ;; Show paren + ;; === Show paren === `(show-paren-match ((t (:background ,primary-container :foreground ,on-primary-container :weight bold)))) `(show-paren-mismatch ((t (:background ,err-container :foreground ,on-err-container :weight bold)))) - - ;; Mode line - improved status bar styling + + ;; === Mode line === `(mode-line ((t (:background ,surface-container-high :foreground ,on-surface :box nil)))) `(mode-line-inactive ((t (:background ,surface :foreground ,on-surface-variant :box nil)))) `(mode-line-buffer-id ((t (:foreground ,primary :weight bold)))) `(mode-line-emphasis ((t (:foreground ,primary :weight bold)))) `(mode-line-highlight ((t (:foreground ,primary :box nil)))) - - ;; Improved Source blocks - make them integrated with the theme + + ;; === Org source blocks === `(org-block ((t (:background ,surface-container-low :extend t :inherit fixed-pitch)))) - `(org-block-begin-line ((t (:background ,surface-container-low :foreground ,primary-fixed-dim :extend t :slant italic :inherit fixed-pitch)))) - `(org-block-end-line ((t (:background ,surface-container-low :foreground ,primary-fixed-dim :extend t :slant italic :inherit fixed-pitch)))) - `(org-code ((t (:background ,surface-container-low :foreground ,tertiary-fixed :inherit fixed-pitch)))) - `(org-verbatim ((t (:background ,surface-container-low :foreground ,primary-fixed :inherit fixed-pitch)))) + `(org-block-begin-line ((t (:background ,surface-container-low :foreground ,outline-color :extend t :slant italic :inherit fixed-pitch)))) ;; FIX: was primary_fixed_dim + `(org-block-end-line ((t (:background ,surface-container-low :foreground ,outline-color :extend t :slant italic :inherit fixed-pitch)))) ;; FIX: was primary_fixed_dim + `(org-code ((t (:background ,surface-container-low :foreground ,tertiary :inherit fixed-pitch)))) + `(org-verbatim ((t (:background ,surface-container-low :foreground ,primary :inherit fixed-pitch)))) `(org-meta-line ((t (:foreground ,outline-color :slant italic)))) - - ;; Org mode with hidden asterisks + + ;; === Org headings - FIXED: 4 distinct hues + variants, all surface-readable === `(org-level-1 ((t (:foreground ,primary :weight bold :height 1.2)))) - `(org-level-2 ((t (:foreground ,primary-container :weight bold :height 1.1)))) - `(org-level-3 ((t (:foreground ,secondary :weight bold)))) - `(org-level-4 ((t (:foreground ,secondary-container :weight bold)))) - `(org-level-5 ((t (:foreground ,tertiary :weight bold)))) - `(org-level-6 ((t (:foreground ,tertiary-container :weight bold)))) - `(org-level-7 ((t (:foreground ,primary-fixed :weight bold)))) - `(org-level-8 ((t (:foreground ,primary-fixed-dim :weight bold)))) + `(org-level-2 ((t (:foreground ,secondary :weight bold :height 1.1)))) ;; FIX: was primary_container + `(org-level-3 ((t (:foreground ,tertiary :weight bold)))) ;; FIX: was secondary + `(org-level-4 ((t (:foreground ,err :weight bold)))) ;; FIX: was secondary_container + `(org-level-5 ((t (:foreground ,primary-variant :weight bold)))) ;; FIX: was tertiary + `(org-level-6 ((t (:foreground ,secondary-variant :weight bold)))) ;; FIX: was tertiary_container + `(org-level-7 ((t (:foreground ,tertiary-variant :weight bold)))) ;; FIX: was primary_fixed (= primary duplicate) + `(org-level-8 ((t (:foreground ,on-surface-variant :weight bold)))) ;; FIX: was primary_fixed_dim `(org-document-title ((t (:foreground ,primary :weight bold :height 1.3)))) - `(org-document-info ((t (:foreground ,primary-container)))) + `(org-document-info ((t (:foreground ,on-surface-variant)))) ;; FIX: was primary_container `(org-todo ((t (:foreground ,err :weight bold)))) - `(org-done ((t (:foreground ,success :weight bold)))) + `(org-done ((t (:foreground ,tertiary :weight bold)))) `(org-headline-done ((t (:foreground ,on-surface-variant)))) - `(org-hide ((t (:foreground ,bg)))) ;; Hide leading asterisks - `(org-ellipsis ((t (:foreground ,tertiary :underline nil)))) ;; Style for folded content indicator - `(org-table ((t (:foreground ,secondary-fixed :inherit fixed-pitch)))) + `(org-hide ((t (:foreground ,bg)))) + `(org-ellipsis ((t (:foreground ,tertiary :underline nil)))) + `(org-table ((t (:foreground ,secondary :inherit fixed-pitch)))) `(org-formula ((t (:foreground ,tertiary :inherit fixed-pitch)))) `(org-checkbox ((t (:foreground ,primary :weight bold :inherit fixed-pitch)))) - `(org-date ((t (:foreground ,secondary-fixed :underline t)))) + `(org-date ((t (:foreground ,secondary :underline t)))) `(org-special-keyword ((t (:foreground ,on-surface-variant :slant italic)))) `(org-tag ((t (:foreground ,outline-color :weight normal)))) - - ;; Magit + + ;; === Magit === `(magit-section-highlight ((t (:background ,surface-container-low)))) `(magit-diff-hunk-heading ((t (:background ,surface-container :foreground ,on-surface-variant)))) `(magit-diff-hunk-heading-highlight ((t (:background ,surface-container-high :foreground ,on-surface)))) `(magit-diff-context ((t (:foreground ,on-surface-variant)))) `(magit-diff-context-highlight ((t (:background ,surface-container-low :foreground ,on-surface)))) - `(magit-diff-added ((t (:background ,success-container :foreground ,on-success-container)))) - `(magit-diff-added-highlight ((t (:background ,success-container :foreground ,on-success-container :weight bold)))) + `(magit-diff-added ((t (:background ,tertiary-container :foreground ,on-tertiary-container)))) + `(magit-diff-added-highlight ((t (:background ,tertiary-container :foreground ,on-tertiary-container :weight bold)))) `(magit-diff-removed ((t (:background ,err-container :foreground ,on-err-container)))) `(magit-diff-removed-highlight ((t (:background ,err-container :foreground ,on-err-container :weight bold)))) `(magit-hash ((t (:foreground ,outline-color)))) `(magit-branch-local ((t (:foreground ,tertiary :weight bold)))) `(magit-branch-remote ((t (:foreground ,primary :weight bold)))) - - ;; Company + + ;; === Company === `(company-tooltip ((t (:background ,surface-container :foreground ,on-surface)))) `(company-tooltip-selection ((t (:background ,primary-container :foreground ,on-primary-container)))) `(company-tooltip-common ((t (:foreground ,primary)))) @@ -193,15 +171,15 @@ `(company-scrollbar-bg ((t (:background ,surface-variant)))) `(company-preview ((t (:foreground ,on-surface-variant :slant italic)))) `(company-preview-common ((t (:foreground ,primary :slant italic)))) - - ;; Ido + + ;; === Ido === `(ido-first-match ((t (:foreground ,primary :weight bold)))) `(ido-only-match ((t (:foreground ,tertiary :weight bold)))) `(ido-subdir ((t (:foreground ,secondary)))) `(ido-indicator ((t (:foreground ,err)))) `(ido-virtual ((t (:foreground ,outline-color)))) - - ;; Helm + + ;; === Helm === `(helm-selection ((t (:background ,primary-container :foreground ,on-primary-container)))) `(helm-match ((t (:foreground ,primary :weight bold)))) `(helm-source-header ((t (:background ,surface-container-high :foreground ,primary :weight bold :height 1.1)))) @@ -210,57 +188,57 @@ `(helm-ff-file ((t (:foreground ,on-surface)))) `(helm-ff-executable ((t (:foreground ,tertiary)))) - ;; corfu + ;; === Corfu === `(corfu-default ((t (:background ,surface-container :foreground ,on-surface)))) `(corfu-current ((t (:background ,primary-container :foreground ,on-primary-container)))) - - ;; Which-key + + ;; === Which-key === `(which-key-key-face ((t (:foreground ,primary :weight bold)))) `(which-key-separator-face ((t (:foreground ,outline-variant)))) `(which-key-command-description-face ((t (:foreground ,on-surface)))) `(which-key-group-description-face ((t (:foreground ,secondary)))) `(which-key-special-key-face ((t (:foreground ,tertiary :weight bold)))) - - ;; Line numbers + + ;; === Line numbers === `(line-number ((t (:foreground ,outline-variant :inherit fixed-pitch)))) `(line-number-current-line ((t (:foreground ,primary :weight bold :inherit fixed-pitch)))) - - ;; Parenthesis matching + + ;; === Parenthesis matching === `(sp-show-pair-match-face ((t (:background ,primary-container :foreground ,on-primary-container)))) `(sp-show-pair-mismatch-face ((t (:background ,err-container :foreground ,on-err-container)))) - - ;; Rainbow delimiters + + ;; === Rainbow delimiters - FIXED: all levels use readable colors === `(rainbow-delimiters-depth-1-face ((t (:foreground ,primary)))) `(rainbow-delimiters-depth-2-face ((t (:foreground ,secondary)))) `(rainbow-delimiters-depth-3-face ((t (:foreground ,tertiary)))) - `(rainbow-delimiters-depth-4-face ((t (:foreground ,primary-fixed)))) - `(rainbow-delimiters-depth-5-face ((t (:foreground ,secondary-fixed)))) - `(rainbow-delimiters-depth-6-face ((t (:foreground ,tertiary-fixed)))) - `(rainbow-delimiters-depth-7-face ((t (:foreground ,primary-fixed-dim)))) - `(rainbow-delimiters-depth-8-face ((t (:foreground ,secondary-fixed-dim)))) - `(rainbow-delimiters-depth-9-face ((t (:foreground ,tertiary-fixed-dim)))) + `(rainbow-delimiters-depth-4-face ((t (:foreground ,err)))) + `(rainbow-delimiters-depth-5-face ((t (:foreground ,primary-variant)))) + `(rainbow-delimiters-depth-6-face ((t (:foreground ,secondary-variant)))) + `(rainbow-delimiters-depth-7-face ((t (:foreground ,tertiary-variant)))) ;; FIX: was primary_fixed_dim + `(rainbow-delimiters-depth-8-face ((t (:foreground ,on-surface-variant)))) ;; FIX: was secondary_fixed_dim + `(rainbow-delimiters-depth-9-face ((t (:foreground ,outline-color)))) ;; FIX: was tertiary_fixed_dim `(rainbow-delimiters-mismatched-face ((t (:foreground ,err :weight bold)))) `(rainbow-delimiters-unmatched-face ((t (:foreground ,err :weight bold)))) - - ;; Dired + + ;; === Dired === `(dired-directory ((t (:foreground ,primary :weight bold)))) `(dired-ignored ((t (:foreground ,outline-variant)))) `(dired-flagged ((t (:foreground ,err)))) `(dired-marked ((t (:foreground ,tertiary :weight bold)))) `(dired-symlink ((t (:foreground ,secondary :slant italic)))) `(dired-header ((t (:foreground ,primary :weight bold :height 1.1)))) - - ;; Terminal colors - `(term-color-black ((t (:foreground ,term0 :background ,term0)))) - `(term-color-red ((t (:foreground ,term1 :background ,term1)))) - `(term-color-green ((t (:foreground ,term2 :background ,term2)))) - `(term-color-yellow ((t (:foreground ,term3 :background ,term3)))) - `(term-color-blue ((t (:foreground ,term4 :background ,term4)))) - `(term-color-magenta ((t (:foreground ,term5 :background ,term5)))) - `(term-color-cyan ((t (:foreground ,term6 :background ,term6)))) - `(term-color-white ((t (:foreground ,term7 :background ,term7)))) - - ;; EShell + + ;; === Terminal colors - FIXED: no container colors as foreground === + `(term-color-black ((t (:foreground ,surface-container-lowest :background ,surface-container-lowest)))) + `(term-color-red ((t (:foreground ,err :background ,err)))) + `(term-color-green ((t (:foreground ,tertiary :background ,tertiary)))) + `(term-color-yellow ((t (:foreground ,secondary :background ,secondary)))) + `(term-color-blue ((t (:foreground ,primary :background ,primary)))) + `(term-color-magenta ((t (:foreground ,err-variant :background ,err-variant)))) ;; FIX: was tertiary_container + `(term-color-cyan ((t (:foreground ,primary-variant :background ,primary-variant)))) ;; FIX: was secondary_container + `(term-color-white ((t (:foreground ,on-surface :background ,on-surface)))) + + ;; === EShell === `(eshell-prompt ((t (:foreground ,primary :weight bold)))) `(eshell-ls-directory ((t (:foreground ,primary :weight bold)))) `(eshell-ls-symlink ((t (:foreground ,secondary :slant italic)))) @@ -271,21 +249,21 @@ `(eshell-ls-missing ((t (:foreground ,err)))) `(eshell-ls-product ((t (:foreground ,on-surface-variant)))) `(eshell-ls-readonly ((t (:foreground ,on-surface-variant)))) - `(eshell-ls-special ((t (:foreground ,secondary-fixed)))) + `(eshell-ls-special ((t (:foreground ,secondary)))) `(eshell-ls-unreadable ((t (:foreground ,outline-variant)))) - - ;; Improved markdown mode + + ;; === Markdown - FIXED: same heading fix as org === `(markdown-header-face ((t (:foreground ,primary :weight bold)))) `(markdown-header-face-1 ((t (:foreground ,primary :weight bold :height 1.2)))) - `(markdown-header-face-2 ((t (:foreground ,primary-container :weight bold :height 1.1)))) - `(markdown-header-face-3 ((t (:foreground ,secondary :weight bold)))) - `(markdown-header-face-4 ((t (:foreground ,secondary-container :weight bold)))) - `(markdown-inline-code-face ((t (:foreground ,tertiary-fixed :background ,surface-container-low :inherit fixed-pitch)))) + `(markdown-header-face-2 ((t (:foreground ,secondary :weight bold :height 1.1)))) ;; FIX: was primary_container + `(markdown-header-face-3 ((t (:foreground ,tertiary :weight bold)))) ;; FIX: was secondary + `(markdown-header-face-4 ((t (:foreground ,err :weight bold)))) ;; FIX: was secondary_container + `(markdown-inline-code-face ((t (:foreground ,tertiary :background ,surface-container-low :inherit fixed-pitch)))) `(markdown-code-face ((t (:background ,surface-container-low :extend t :inherit fixed-pitch)))) `(markdown-pre-face ((t (:background ,surface-container-low :inherit fixed-pitch)))) - `(markdown-table-face ((t (:foreground ,secondary-fixed :inherit fixed-pitch)))) - - ;; Web mode + `(markdown-table-face ((t (:foreground ,secondary :inherit fixed-pitch)))) + + ;; === Web mode === `(web-mode-html-tag-face ((t (:foreground ,primary)))) `(web-mode-html-tag-bracket-face ((t (:foreground ,on-surface-variant)))) `(web-mode-html-attr-name-face ((t (:foreground ,secondary)))) @@ -293,60 +271,56 @@ `(web-mode-css-selector-face ((t (:foreground ,primary)))) `(web-mode-css-property-name-face ((t (:foreground ,secondary)))) `(web-mode-css-string-face ((t (:foreground ,tertiary)))) - - ;; Flycheck + + ;; === Flycheck === `(flycheck-error ((t (:underline (:style wave :color ,err))))) `(flycheck-warning ((t (:underline (:style wave :color ,secondary))))) `(flycheck-info ((t (:underline (:style wave :color ,tertiary))))) `(flycheck-fringe-error ((t (:foreground ,err)))) `(flycheck-fringe-warning ((t (:foreground ,secondary)))) `(flycheck-fringe-info ((t (:foreground ,tertiary)))) - - ;; Mini-buffer customization + + ;; === Minibuffer === `(minibuffer-prompt ((t (:foreground ,primary :weight bold)))) - - ;; Improved search highlighting + + ;; === LSP === `(lsp-face-highlight-textual ((t (:background ,primary-container :foreground ,on-primary-container :weight bold)))) `(lsp-face-highlight-read ((t (:background ,secondary-container :foreground ,on-secondary-container :weight bold)))) `(lsp-face-highlight-write ((t (:background ,tertiary-container :foreground ,on-tertiary-container :weight bold)))) - - ;; Info and help modes + + ;; === Info titles - FIXED: same heading fix === `(info-title-1 ((t (:foreground ,primary :weight bold :height 1.3)))) - `(info-title-2 ((t (:foreground ,primary-container :weight bold :height 1.2)))) - `(info-title-3 ((t (:foreground ,secondary :weight bold :height 1.1)))) - `(info-title-4 ((t (:foreground ,secondary-container :weight bold)))) + `(info-title-2 ((t (:foreground ,secondary :weight bold :height 1.2)))) ;; FIX: was primary_container + `(info-title-3 ((t (:foreground ,tertiary :weight bold :height 1.1)))) ;; FIX: was secondary + `(info-title-4 ((t (:foreground ,err :weight bold)))) ;; FIX: was secondary_container `(Info-quoted ((t (:foreground ,tertiary)))) `(info-menu-header ((t (:foreground ,primary :weight bold)))) `(info-menu-star ((t (:foreground ,primary)))) `(info-node ((t (:foreground ,tertiary :weight bold)))) - ;; Tabs + ;; === Tabs === `(tab-bar ((t (:background ,surface-container-high :foreground ,on-surface :box nil)))) `(tab-bar-tab ((t (:background ,surface-container-high :foreground ,on-surface :weight bold :box nil)))) `(tab-bar-tab-inactive ((t (:background ,surface :foreground ,on-surface-variant :box nil)))) - `(tab-line ((t (:background ,surface-container-high :foreground ,on-surface :box nil)))) `(tab-line-tab ((t (:background ,surface :foreground ,on-surface-variant :box nil)))) `(tab-line-tab-current ((t (:background ,surface-container-high :foreground ,on-surface :weight bold :box nil)))) `(tab-line-tab-inactive ((t (:background ,surface :foreground ,on-surface-variant :box nil)))) `(tab-line-highlight ((t (:background ,surface-container-highest :foreground ,on-surface)))) - `(centaur-tabs-default ((t (:background ,surface-container-high :foreground ,on-surface)))) `(centaur-tabs-selected ((t (:background ,surface-container-high :foreground ,on-surface :weight bold)))) `(centaur-tabs-unselected ((t (:background ,surface :foreground ,on-surface-variant)))) `(centaur-tabs-selected-modified ((t (:background ,surface-container-high :foreground ,tertiary :weight bold)))) `(centaur-tabs-unselected-modified ((t (:background ,surface :foreground ,tertiary)))) `(centaur-tabs-active-bar-face ((t (:background ,primary)))) - - ;; Fixed-pitch faces + + ;; === Fixed/variable pitch === `(fixed-pitch ((t (:family "monospace")))) `(fixed-pitch-serif ((t (:family "monospace serif")))) - - ;; Variable-pitch face `(variable-pitch ((t (:family "sans serif")))) )) -;; Add org-mode hooks for hiding leading stars +;; Org-mode settings (with-eval-after-load 'org (setq org-hide-leading-stars t) (setq org-startup-indented t)) @@ -358,4 +332,3 @@ (provide-theme 'noctalia) ;;; noctalia-theme.el ends here - |
