diff options
| -rw-r--r-- | NOTES.org | 59 | ||||
| -rw-r--r-- | early-init.el | 16 | ||||
| -rw-r--r-- | modules/modeline-config.el | 170 | ||||
| -rw-r--r-- | modules/ui-config.el | 9 | ||||
| -rw-r--r-- | modules/user-constants.el | 9 | ||||
| -rw-r--r-- | modules/vc-config.el | 5 |
6 files changed, 239 insertions, 29 deletions
@@ -123,3 +123,62 @@ Note: This file evolves as we learn best practices. - Defined four-question Q&A framework - Established seven core principles for session creation - Documented in =docs/sessions/create-session.org= + +** 2025-11-03: Method 2 Quick Wins Session +- Completed 6 tasks across Methods 1, 2, and 3 +- Focus: Low-risk improvements aligned with V2MOM Methods + +*** Key Technical Learnings + +**** Difftastic vs Ediff - Complementary Tools +- **Difftastic**: Read-only structural diffs for git (language-aware) +- **Ediff**: Interactive side-by-side editing for buffer comparison +- **Discovery**: User had ediff at C-c D but C-; b D used basic diff +- **Solution**: Hybrid approach - ediff for buffers, difftastic for git +- **Lesson**: Don't assume one replaces the other; they serve different purposes + +**** Org-mode Visual Emphasis +- =org-fontify-emphasized-text= controls bold/italic rendering +- =org-hide-emphasis-markers= hides markup characters (* / _) +- =org-appear= shows markers only when cursor is on emphasized text +- **Pattern**: Hide markers globally, reveal contextually with org-appear + +*** User Workflow Preferences + +**** Task Selection Strategy +- User prefers quick wins when energy is lower +- Appreciates effort estimates BEFORE committing to work +- Will defer mission-critical changes (e.g., Company → Corfu) +- Quote: "now I'm hungry for more" after successful quick wins + +**** Communication Patterns +- User sometimes needs clarification iterations ("whoops. I wasn't clear again") +- Always confirm understanding before major changes +- User values knowing keybindings for new features +- Appreciates when tasks are already complete (just need verification) + +**** V2MOM Task Management +- Tasks organized by 6 Methods with progress tracking (e.g., 7/13, 3/5) +- User maintains detailed completion notes in todo.org +- Each task includes context, rationale, and completion details +- Weekly triage scheduled to keep active todos < 20 + +*** Development Patterns + +**** Git Workflow +- Always push to BOTH remotes: origin (cjennings.net) AND github +- Commit messages include Claude Code attribution +- User reviews git status and diffs before committing + +**** Configuration Management +- User runs Emacs 30.2 with use-package +- Prefers editing existing files over creating new ones +- Values code reduction (mood-line: -40 lines, ediff upgrade: -12 lines) + +*** Tasks Completed +1. Switched doom-modeline → mood-line (Method 2) +2. Removed deprecated tree-sitter package (Method 2) +3. Fixed cj/goto-git-gutter-diff-hunks void-function (Method 1) +4. Cleaned up go-ts-mode-map declarations (Method 1) +5. Upgraded buffer diff to ediff + added difftastic for git (Method 3) +6. Added org-appear and enabled emphasis rendering (Method 2) diff --git a/early-init.el b/early-init.el index 79ff7816..6fa3e0b2 100644 --- a/early-init.el +++ b/early-init.el @@ -51,15 +51,19 @@ (setq debug-on-error t) ;; default nil. turn on to debug issues only. (setq debug-on-quit t) ;; debug on C-g (breaking out of hangs/freezes) -(add-hook 'emacs-startup-hook - (lambda () - (setq debug-on-error nil) - (setq debug-on-quit nil))) +;; (add-hook 'emacs-startup-hook +;; (lambda () +;; (setq debug-on-error nil) +;; (setq debug-on-quit nil))) ;; ------------------------------ Bug Workarounds ------------------------------ -;; Prevent org-element from being natively compiled again by adding the line -(setq native-comp-jit-compilation-deny-list '(".*org-element.*")) +;; Disable async native compilation to prevent "Selecting deleted buffer" errors +;; This is a known issue in Emacs 30.x where async compilation buffers get +;; deleted before the compilation process completes. Synchronous compilation +;; is slower initially but avoids these race conditions. +(setq native-comp-deferred-compilation nil) ;; Disable async/deferred compilation +(setq native-comp-async-report-warnings-errors nil) ;; Silence async warnings ;; --------------------------- Warning Notifications --------------------------- diff --git a/modules/modeline-config.el b/modules/modeline-config.el index af0c3524..1c98e965 100644 --- a/modules/modeline-config.el +++ b/modules/modeline-config.el @@ -3,29 +3,169 @@ ;;; Commentary: -;; Minimal modeline configuration using mood-line. - -;; mood-line is a lightweight, minimal modeline inspired by doom-modeline -;; but with much better performance and simpler configuration. +;; Simple, minimal modeline using only built-in Emacs functionality. +;; No external packages = no buffer issues, no native-comp errors. ;; Features: -;; - Buffer status and modification indicators -;; - Major mode display +;; - Buffer status (modified, read-only) +;; - Buffer name +;; - Major mode ;; - Version control status -;; - Flycheck/Flymake status -;; - Cursor position and buffer percentage -;; - Anzu and multiple-cursors counters -;; - No dependencies -;; - Minimal performance overhead +;; - Line and column position +;; - Buffer percentage ;;; Code: -;; -------------------------------- mood-line ---------------------------------- +;; Use buffer status colors from user-constants +(require 'user-constants) + +;; -------------------------- Modeline Configuration -------------------------- + +;; Use Emacs 30's built-in right-alignment +(setq mode-line-right-align-edge 'right-margin) + +;; String truncation length for narrow windows +(defcustom cj/modeline-string-truncate-length 12 + "String length after which truncation happens in narrow windows." + :type 'natnum + :group 'modeline) + +;; -------------------------- Helper Functions --------------------------------- + +(defun cj/modeline-window-narrow-p () + "Return non-nil if window is narrow (less than 100 chars wide)." + (< (window-total-width) 100)) + +(defun cj/modeline-string-truncate-p (str) + "Return non-nil if STR should be truncated." + (and (stringp str) + (not (string-empty-p str)) + (cj/modeline-window-narrow-p) + (> (length str) cj/modeline-string-truncate-length) + (not (one-window-p :no-minibuffer)))) + +(defun cj/modeline-string-cut-middle (str) + "Truncate STR in the middle if appropriate, else return STR. +Example: 'my-very-long-name.el' → 'my-ver...me.el'" + (if (cj/modeline-string-truncate-p str) + (let ((half (floor cj/modeline-string-truncate-length 2))) + (concat (substring str 0 half) "..." (substring str (- half)))) + str)) + +;; -------------------------- Modeline Segments -------------------------------- + +(defvar-local cj/modeline-buffer-name + '(:eval (let* ((state (cond + (buffer-read-only 'read-only) + (overwrite-mode 'overwrite) + (t 'normal))) + (color (alist-get state cj/buffer-status-colors)) + (name (buffer-name)) + (truncated-name (cj/modeline-string-cut-middle name))) + (propertize truncated-name + 'face `(:foreground ,color) + 'mouse-face 'mode-line-highlight + 'help-echo (concat + name "\n" + (or (buffer-file-name) + (format "No file. Directory: %s" default-directory))) + 'local-map (let ((map (make-sparse-keymap))) + (define-key map [mode-line mouse-1] 'previous-buffer) + (define-key map [mode-line mouse-3] 'next-buffer) + map)))) + "Buffer name colored by read-only/read-write status. +Green = writeable, Red = read-only, Gold = overwrite. +Truncates in narrow windows. Click: mouse-1 = prev buffer, mouse-3 = next buffer.") + +(defvar-local cj/modeline-position + '(:eval (format "L:%d C:%d" (line-number-at-pos) (current-column))) + "Line and column position as L:line C:col.") + +(defvar cj/modeline-vc-faces + '((added . vc-locally-added-state) + (edited . vc-edited-state) + (removed . vc-removed-state) + (missing . vc-missing-state) + (conflict . vc-conflict-state) + (locked . vc-locked-state) + (up-to-date . vc-up-to-date-state)) + "VC state to face mapping.") + +(defvar-local cj/modeline-vc-branch + '(:eval (when (mode-line-window-selected-p) ; Only show in active window + (when-let* ((file (or buffer-file-name default-directory)) + (backend (vc-backend file))) + (when-let* ((branch (vc-working-revision file backend))) + ;; For Git, try to get symbolic branch name + (when (eq backend 'Git) + (require 'vc-git) + (when-let* ((symbolic (vc-git--symbolic-ref file))) + (setq branch symbolic))) + ;; Get VC state for face + (let* ((state (vc-state file backend)) + (face (alist-get state cj/modeline-vc-faces 'vc-up-to-date-state)) + (truncated-branch (cj/modeline-string-cut-middle branch))) + (concat + (propertize (char-to-string #xE0A0) 'face 'shadow) ; Git branch symbol + " " + (propertize truncated-branch + 'face face + 'mouse-face 'mode-line-highlight + 'help-echo (format "Branch: %s\nState: %s\nmouse-1: vc-diff\nmouse-3: vc-root-diff" branch state) + 'local-map (let ((map (make-sparse-keymap))) + (define-key map [mode-line mouse-1] 'vc-diff) + (define-key map [mode-line mouse-3] 'vc-root-diff) + map)))))))) + "Git branch with symbol and colored by VC state. +Shows only in active window. Truncates in narrow windows. +Click: mouse-1 = vc-diff, mouse-3 = vc-root-diff.") + +(defvar-local cj/modeline-major-mode + '(:eval (let ((mode-str (format-mode-line mode-name)) ; Convert to string + (mode-sym major-mode)) + (propertize mode-str + 'mouse-face 'mode-line-highlight + 'help-echo (if-let* ((parent (get mode-sym 'derived-mode-parent))) + (format "Major mode: %s\nDerived from: %s\nmouse-1: describe-mode" mode-sym parent) + (format "Major mode: %s\nmouse-1: describe-mode" mode-sym)) + 'local-map (let ((map (make-sparse-keymap))) + (define-key map [mode-line mouse-1] 'describe-mode) + map)))) + "Major mode name only (no minor modes). +Click: mouse-1 = describe-mode.") + +(defvar-local cj/modeline-misc-info + '(:eval (when (mode-line-window-selected-p) + mode-line-misc-info)) + "Misc info (chime notifications, etc). +Shows only in active window.") + +;; -------------------------- Modeline Assembly -------------------------------- -(use-package mood-line - :config - (mood-line-mode)) +(setq-default mode-line-format + '("%e" ; Error message if out of memory + ;; LEFT SIDE + " " + cj/modeline-major-mode + " " + cj/modeline-buffer-name + " " + cj/modeline-position + ;; RIGHT SIDE (using Emacs 30 built-in right-align) + ;; Order: leftmost to rightmost as they appear in the list + mode-line-format-right-align + cj/modeline-vc-branch + " " + cj/modeline-misc-info)) +;; Mark all segments as risky-local-variable (required for :eval forms) +(dolist (construct '(cj/modeline-buffer-name + cj/modeline-position + cj/modeline-vc-branch + cj/modeline-vc-faces + cj/modeline-major-mode + cj/modeline-misc-info)) + (put construct 'risky-local-variable t)) (provide 'modeline-config) ;;; modeline-config.el ends here diff --git a/modules/ui-config.el b/modules/ui-config.el index 91dbaf31..837d2169 100644 --- a/modules/ui-config.el +++ b/modules/ui-config.el @@ -36,11 +36,8 @@ "Opacity level for Emacs frames when `cj/enable-transparency' is non-nil. 100 = fully opaque, 0 = fully transparent.") -(defconst cj/cursor-colors - '((read-only . "#f06a3f") ; red – buffer is read-only - (overwrite . "#c48702") ; gold – overwrite mode - (normal . "#64aa0f")) ; green – insert & read/write - "Alist mapping cursor states to their colors.") +;; Use buffer status colors from user-constants +(require 'user-constants) ;; ----------------------------- System UI Settings ---------------------------- @@ -104,7 +101,7 @@ When `cj/enable-transparency' is nil, reset alpha to fully opaque." (buffer-read-only 'read-only) (overwrite-mode 'overwrite) (t 'normal))) - (color (alist-get state cj/cursor-colors))) + (color (alist-get state cj/buffer-status-colors))) (unless (and (string= color cj/-cursor-last-color) (string= (buffer-name) cj/-cursor-last-buffer)) (set-cursor-color color) diff --git a/modules/user-constants.el b/modules/user-constants.el index bcb34bcc..ba52cec2 100644 --- a/modules/user-constants.el +++ b/modules/user-constants.el @@ -38,6 +38,15 @@ Example: (setq cj/debug-modules '(org-agenda mail)) (defvar user-mail-address "c@cjennings.net" "The user's email address.") +;; ---------------------------- Buffer Status Colors --------------------------- + +(defconst cj/buffer-status-colors + '((read-only . "#f06a3f") ; red – buffer is read-only + (overwrite . "#c48702") ; gold – overwrite mode + (normal . "#64aa0f")) ; green – insert & read/write + "Alist mapping buffer states to their colors. +Used by cursor color, modeline, and other UI elements.") + ;; ------------------------ Directory And File Constants ----------------------- ;; DIRECTORIES diff --git a/modules/vc-config.el b/modules/vc-config.el index b9b61c29..141f6e17 100644 --- a/modules/vc-config.el +++ b/modules/vc-config.el @@ -125,10 +125,11 @@ interactive selection to jump to any changed line in the buffer." ;; -------------------------------- Difftastic --------------------------------- ;; Structural diffs for better git change visualization +;; Requires: difft binary (installed via pacman -S difftastic) (use-package difftastic - :demand t - :after magit + :defer t + :commands (difftastic-magit-diff difftastic-magit-show) :bind (:map magit-blame-read-only-mode-map ("D" . difftastic-magit-show) ("S" . difftastic-magit-show)) |
