summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--config.el59
-rw-r--r--config.org60
-rw-r--r--lisp/fossil-ui.el17
-rw-r--r--test/fossil-ui-test.el21
5 files changed, 118 insertions, 42 deletions
diff --git a/.gitignore b/.gitignore
index e115add..682eec2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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/
diff --git a/config.el b/config.el
index 4bc729a..e01bffe 100644
--- a/config.el
+++ b/config.el
@@ -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)))
diff --git a/config.org b/config.org
index 466fdf1..117f500 100644
--- a/config.org
+++ b/config.org
@@ -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")