diff options
| author | cashmere <cashmere@autistici.org> | 2026-09-12 14:40:11 +0200 |
|---|---|---|
| committer | cashmere <cashmere@autistici.org> | 2026-09-12 14:40:11 +0200 |
| commit | 9bfc7c38dd8988b4d9923dc0a421c027adcbf514 (patch) | |
| tree | f27830952d60e6790e59c3e7c63c6be3550a93fe | |
| parent | 77d69634bf4029e522d8a09e3a417f21dbd65f4d (diff) | |
| download | emacs-9bfc7c38dd8988b4d9923dc0a421c027adcbf514.tar.gz | |
relic: 2026-09-12T14:40:15+02:00
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | config.el | 59 | ||||
| -rw-r--r-- | config.org | 60 | ||||
| -rw-r--r-- | lisp/fossil-ui.el | 17 | ||||
| -rw-r--r-- | test/fossil-ui-test.el | 21 |
5 files changed, 118 insertions, 42 deletions
@@ -82,6 +82,9 @@ dirvish/thumbnails # Downloaded eca binary + archive (large, per-host) /eca/ +# Private Fossil UI staging snapshots and recovery state +/fossil-stage/ + # persp-mode session autosave state /workspaces/ @@ -31,6 +31,9 @@ Set per-host in the gitignored `local.el'.") "Per-host background-only opacity, or nil for the Emacs default.") (defvar cashmere/font-family "Maple Mono NF" "Per-host default monospace font family.") + (defvar cashmere/font-features + '("cv01" "cv32" "cv34" "cv36" "cv63" "cv64" "cv66") + "OpenType features enabled for the default monospace font.") (defvar cashmere/font-height 180 "Per-host default font height in tenths of a point.") (defvar cashmere/theme nil @@ -757,7 +760,7 @@ Temporarily disables notifications during the fetch." ;; Let the full markup toggle reveal link destinations as well. (markdown-hide-urls nil) (markdown-header-scaling t) - (markdown-header-scaling-values '(1.6 1.3 1.15 1.08 1.0 1.0)) + (markdown-header-scaling-values '(1.65 1.40 1.22 1.10 1.00 0.92)) (markdown-fontify-code-blocks-natively t) (markdown-asymmetric-header t) (markdown-indent-on-enter 'indent-and-new-item) @@ -772,10 +775,10 @@ Temporarily disables notifications during the fetch." "Apply the quiet, theme-adaptive typography used by Org buffers." (let ((foreground (face-attribute 'default :foreground nil t)) (muted (face-attribute 'shadow :foreground nil t))) - (dolist (spec '((markdown-header-face-1 1.60 medium) - (markdown-header-face-2 1.30 semibold) - (markdown-header-face-3 1.15 semibold) - (markdown-header-face-4 1.08 semibold) + (dolist (spec '((markdown-header-face-1 1.65 bold) + (markdown-header-face-2 1.40 bold) + (markdown-header-face-3 1.22 semibold) + (markdown-header-face-4 1.10 medium) (markdown-header-face-5 1.00 medium))) (set-face-attribute (car spec) nil :family "SF Pro Display" @@ -783,7 +786,7 @@ Temporarily disables notifications during the fetch." :weight (caddr spec) :foreground foreground)) (set-face-attribute 'markdown-header-face-6 nil - :family "SF Pro Display" :height 1.0 + :family "SF Pro Display" :height 0.92 :weight 'regular :foreground muted) (set-face-attribute 'markdown-header-delimiter-face nil :height 0.9 :weight 'normal :foreground muted) @@ -937,21 +940,23 @@ Temporarily disables notifications during the fetch." (let ((foreground (face-attribute 'default :foreground nil t)) (muted (face-attribute 'shadow :foreground nil t))) (set-face-attribute 'org-document-title nil - :family "SF Pro Display" :height 1.6 - :weight 'medium :foreground foreground) - (dolist (spec '((org-level-1 1.30 semibold) - (org-level-2 1.15 semibold) - (org-level-3 1.08 semibold) - (org-level-4 1.00 medium) + :family "SF Pro Display" :height 1.80 + :weight 'bold :foreground foreground) + (dolist (spec '((org-level-1 1.55 bold) + (org-level-2 1.35 semibold) + (org-level-3 1.20 semibold) + (org-level-4 1.10 medium) (org-level-5 1.00 medium))) (set-face-attribute (car spec) nil :family "SF Pro Display" :height (cadr spec) :weight (caddr spec) :foreground foreground)) - (dolist (face '(org-level-6 org-level-7 org-level-8)) - (set-face-attribute face nil - :family "SF Pro Display" :height 1.0 + (dolist (spec '((org-level-6 0.95) + (org-level-7 0.90) + (org-level-8 0.85))) + (set-face-attribute (car spec) nil + :family "SF Pro Display" :height (cadr spec) :weight 'regular :foreground muted)))) ;; Reapply the neutral heading palette after Tinty's or Fontaine's theme @@ -2936,6 +2941,15 @@ BODY is the xonsh script. PARAMS may include :dir and :cmdline." (blink-cursor-mode 0) (setq-default cursor-type 'box) +(defun my/fontconfig-name (&optional height) + "Return the configured monospace Fontconfig name at HEIGHT." + (concat cashmere/font-family + (when height + (format "-%g" (/ height 10.0))) + (when cashmere/font-features + (concat ":fontfeatures=" + (mapconcat #'identity cashmere/font-features ","))))) + (use-package fontaine :ensure t :demand t @@ -2993,7 +3007,16 @@ BODY is the xonsh script. PARAMS may include :dir and :cmdline." :underline nil :overline nil))) + (defun my/apply-font-features (&optional _preset) + "Apply `cashmere/font-features' without changing the current font size." + (dolist (frame (frame-list)) + (when (display-graphic-p frame) + (set-frame-font + (my/fontconfig-name (face-attribute 'default :height frame)) + t (list frame) t)))) + (add-hook 'fontaine-set-preset-hook #'my/apply-line-number-faces) + (add-hook 'fontaine-set-preset-hook #'my/apply-font-features) (add-hook 'enable-theme-functions #'my/apply-line-number-faces) ;; Fontaine 3 implements presets as a global theme, so applying the preset @@ -3003,14 +3026,14 @@ BODY is the xonsh script. PARAMS may include :dir and :cmdline." (fontaine-set-preset (or (fontaine-restore-latest-preset) 'regular)) (fontaine-mode 1) - (my/apply-line-number-faces)) + (my/apply-line-number-faces) + (my/apply-font-features)) ;; Give a daemon's first GUI frame the final base font before its first ;; redisplay. This avoids fallback-font geometry and a visible layout jump; ;; Fontaine's global theme then supplies the remaining face attributes. (add-to-list 'default-frame-alist - `(font . ,(format "%s-%g" cashmere/font-family - (/ cashmere/font-height 10.0)))) + `(font . ,(my/fontconfig-name cashmere/font-height))) @@ -40,6 +40,7 @@ (setq cashmere/frame-alpha 100 cashmere/frame-alpha-background nil cashmere/font-family "SFMono Nerd Font" + cashmere/font-features nil cashmere/font-height 180 cashmere/theme 'tinty) #+end_example @@ -55,6 +56,9 @@ Set per-host in the gitignored `local.el'.") "Per-host background-only opacity, or nil for the Emacs default.") (defvar cashmere/font-family "Maple Mono NF" "Per-host default monospace font family.") + (defvar cashmere/font-features + '("cv01" "cv32" "cv34" "cv36" "cv63" "cv64" "cv66") + "OpenType features enabled for the default monospace font.") (defvar cashmere/font-height 180 "Per-host default font height in tenths of a point.") (defvar cashmere/theme nil @@ -873,7 +877,7 @@ Not necessary but an eyecandy to look at! ;; Let the full markup toggle reveal link destinations as well. (markdown-hide-urls nil) (markdown-header-scaling t) - (markdown-header-scaling-values '(1.6 1.3 1.15 1.08 1.0 1.0)) + (markdown-header-scaling-values '(1.65 1.40 1.22 1.10 1.00 0.92)) (markdown-fontify-code-blocks-natively t) (markdown-asymmetric-header t) (markdown-indent-on-enter 'indent-and-new-item) @@ -888,10 +892,10 @@ Not necessary but an eyecandy to look at! "Apply the quiet, theme-adaptive typography used by Org buffers." (let ((foreground (face-attribute 'default :foreground nil t)) (muted (face-attribute 'shadow :foreground nil t))) - (dolist (spec '((markdown-header-face-1 1.60 medium) - (markdown-header-face-2 1.30 semibold) - (markdown-header-face-3 1.15 semibold) - (markdown-header-face-4 1.08 semibold) + (dolist (spec '((markdown-header-face-1 1.65 bold) + (markdown-header-face-2 1.40 bold) + (markdown-header-face-3 1.22 semibold) + (markdown-header-face-4 1.10 medium) (markdown-header-face-5 1.00 medium))) (set-face-attribute (car spec) nil :family "SF Pro Display" @@ -899,7 +903,7 @@ Not necessary but an eyecandy to look at! :weight (caddr spec) :foreground foreground)) (set-face-attribute 'markdown-header-face-6 nil - :family "SF Pro Display" :height 1.0 + :family "SF Pro Display" :height 0.92 :weight 'regular :foreground muted) (set-face-attribute 'markdown-header-delimiter-face nil :height 0.9 :weight 'normal :foreground muted) @@ -1079,21 +1083,23 @@ let's give agent-shell another try (let ((foreground (face-attribute 'default :foreground nil t)) (muted (face-attribute 'shadow :foreground nil t))) (set-face-attribute 'org-document-title nil - :family "SF Pro Display" :height 1.6 - :weight 'medium :foreground foreground) - (dolist (spec '((org-level-1 1.30 semibold) - (org-level-2 1.15 semibold) - (org-level-3 1.08 semibold) - (org-level-4 1.00 medium) + :family "SF Pro Display" :height 1.80 + :weight 'bold :foreground foreground) + (dolist (spec '((org-level-1 1.55 bold) + (org-level-2 1.35 semibold) + (org-level-3 1.20 semibold) + (org-level-4 1.10 medium) (org-level-5 1.00 medium))) (set-face-attribute (car spec) nil :family "SF Pro Display" :height (cadr spec) :weight (caddr spec) :foreground foreground)) - (dolist (face '(org-level-6 org-level-7 org-level-8)) - (set-face-attribute face nil - :family "SF Pro Display" :height 1.0 + (dolist (spec '((org-level-6 0.95) + (org-level-7 0.90) + (org-level-8 0.85))) + (set-face-attribute (car spec) nil + :family "SF Pro Display" :height (cadr spec) :weight 'regular :foreground muted)))) ;; Reapply the neutral heading palette after Tinty's or Fontaine's theme @@ -3556,6 +3562,15 @@ Native =undo-redo= (via =evil-undo-system='undo-redo=); just raise the undo limi (blink-cursor-mode 0) (setq-default cursor-type 'box) +(defun my/fontconfig-name (&optional height) + "Return the configured monospace Fontconfig name at HEIGHT." + (concat cashmere/font-family + (when height + (format "-%g" (/ height 10.0))) + (when cashmere/font-features + (concat ":fontfeatures=" + (mapconcat #'identity cashmere/font-features ","))))) + (use-package fontaine :ensure t :demand t @@ -3613,7 +3628,16 @@ Native =undo-redo= (via =evil-undo-system='undo-redo=); just raise the undo limi :underline nil :overline nil))) + (defun my/apply-font-features (&optional _preset) + "Apply `cashmere/font-features' without changing the current font size." + (dolist (frame (frame-list)) + (when (display-graphic-p frame) + (set-frame-font + (my/fontconfig-name (face-attribute 'default :height frame)) + t (list frame) t)))) + (add-hook 'fontaine-set-preset-hook #'my/apply-line-number-faces) + (add-hook 'fontaine-set-preset-hook #'my/apply-font-features) (add-hook 'enable-theme-functions #'my/apply-line-number-faces) ;; Fontaine 3 implements presets as a global theme, so applying the preset @@ -3623,14 +3647,14 @@ Native =undo-redo= (via =evil-undo-system='undo-redo=); just raise the undo limi (fontaine-set-preset (or (fontaine-restore-latest-preset) 'regular)) (fontaine-mode 1) - (my/apply-line-number-faces)) + (my/apply-line-number-faces) + (my/apply-font-features)) ;; Give a daemon's first GUI frame the final base font before its first ;; redisplay. This avoids fallback-font geometry and a visible layout jump; ;; Fontaine's global theme then supplies the remaining face attributes. (add-to-list 'default-frame-alist - `(font . ,(format "%s-%g" cashmere/font-family - (/ cashmere/font-height 10.0)))) + `(font . ,(my/fontconfig-name cashmere/font-height))) #+end_src #+results: diff --git a/lisp/fossil-ui.el b/lisp/fossil-ui.el index eeeabc5..33911cf 100644 --- a/lisp/fossil-ui.el +++ b/lisp/fossil-ui.el @@ -2462,14 +2462,19 @@ when every content issue is covered by the checkout's effective glob settings." (fossil-ui--remove-entry root index path) (let* ((file (expand-file-name path root)) (change (cl-find path changes :key (lambda (candidate) (plist-get candidate :path)) :test #'equal)) - (deleted (equal (plist-get change :status) "DELETED"))) + (status (plist-get change :status)) + (missing (and (equal status "MISSING") (not (file-exists-p file)))) + (deleted (or (equal status "DELETED") missing))) (fossil-ui--clean-buffer file) (if deleted - (condition-case nil - (let ((base (fossil-ui--base root path))) - (fossil-ui--put-entry root index (list :path path :base base :staged "" :deleted t))) - (error - (fossil-ui--put-entry root index (list :path path :binary t :deleted t)))) + (let ((entry + (condition-case nil + (let ((base (fossil-ui--base root path))) + (list :path path :base base :staged "" :deleted t)) + (error (list :path path :binary t :deleted t))))) + (when missing + (fossil-ui--require-success root "rm" "--soft" "--" path)) + (fossil-ui--put-entry root index entry)) (let ((content (fossil-ui--file-content root path t))) (if (plist-get content :binary) (let ((snapshot (fossil-ui--save-binary-snapshot root path (plist-get content :bytes))) diff --git a/test/fossil-ui-test.el b/test/fossil-ui-test.el index 80fd5c0..9032408 100644 --- a/test/fossil-ui-test.el +++ b/test/fossil-ui-test.el @@ -218,6 +218,27 @@ :key (lambda (change) (plist-get change :path)) :test #'equal))))) +(ert-deftest fossil-ui-missing-file-can-be-staged-unstaged-and-committed-as-deletion () + (fossil-ui-test--with-checkout + (delete-file (expand-file-name "tracked.txt" root)) + (let ((buffer (save-window-excursion (fossil-ui-status root)))) + (unwind-protect + (with-current-buffer buffer + (fossil-ui--goto-path "tracked.txt") + (should (equal (fossil-ui--status-at-point) "MISSING")) + (fossil-ui-stage) + (should (plist-get (car (plist-get (fossil-ui--index root) :entries)) :deleted)) + (should (equal (plist-get (car (fossil-ui--changes root)) :status) "DELETED")) + (fossil-ui--goto-path "tracked.txt" t) + (fossil-ui-unstage) + (should-not (plist-get (fossil-ui--index root) :entries)) + (should (equal (plist-get (car (fossil-ui--changes root)) :status) "DELETED")) + (fossil-ui--goto-path "tracked.txt") + (fossil-ui-stage) + (fossil-ui--commit-staged root "remove tracked file") + (should-not (member "tracked.txt" (split-string (fossil-ui-test--call root "ls" "-r" "current") "\n" t)))) + (when (buffer-live-p buffer) (kill-buffer buffer)))))) + (ert-deftest fossil-ui-staged-and-unstaged-inline-sections-are-independent () (fossil-ui-test--with-checkout (fossil-ui-test--write (expand-file-name "tracked.txt" root) "staged version\n") |
