From 8bc1c3ffb29ca730609574177a40813b1a8db6d8 Mon Sep 17 00:00:00 2001 From: Roman Scherer Date: Fri, 22 Aug 2025 12:54:08 +0200 Subject: [PATCH 1/3] Add icons to header line This adds icons to the header line using the svg-lib library when running on a graphical display. Otherwise no icons are shown. The svg-lib supports a couple of icon repositories: https://github.com/rougier/svg-lib?tab=readme-ov-file#icon-repositories For now I have chosen to pick icons from the Boostrap repository. Some open questions: - Any preference for which icon repository to choose? - Pick icons only from one repository (to have consistent styling) or from many? - The Boxicons repository does not seem to work, or my IP is blocked. --- eca-chat.el | 39 ++++++++++++++++++++++++++++++++++----- eca.el | 2 +- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/eca-chat.el b/eca-chat.el index ceb9e98..f5090bc 100644 --- a/eca-chat.el +++ b/eca-chat.el @@ -14,6 +14,7 @@ (require 'f) (require 'markdown-mode) (require 'compat) +(require 'svg-lib) (require 'eca-util) (require 'eca-api) @@ -593,6 +594,31 @@ the prompt/context line." (eq (line-number-at-pos (point)) (line-number-at-pos (eca-chat--prompt-field-start-point)))) +(defun eca-chat--header-line-icon (icon) + "Create an SVG icon for use in the header line. +ICON is the name of the Bootstrap icon to display. +Returns an SVG image suitable for insertion in the header line, +styled to match the current theme's header-line face." + (svg-lib-icon icon nil + :background (face-background 'header-line nil t) + :collection "bootstrap" + :foreground (face-foreground 'eca-chat-option-key-face nil t) + :stroke 0)) + +(defun eca-chat--header-line-label (name icon) + "Create a formatted label string for the header line. +NAME is the text label to display. +ICON is the Bootstrap icon name to display before the name. +Returns a string containing the icon (if in graphical display) followed +by the name and a colon separator, suitable for header line display." + (with-temp-buffer + (when (display-graphic-p) + (when-let ((svg-icon (eca-chat--header-line-icon icon))) + (insert-image svg-icon))) + (insert name) + (insert ": ") + (buffer-substring (point-min) (point-max)))) + (defun eca-chat--header-line-string (session) "Update chat header line for SESSION." (let ((model-keymap (make-sparse-keymap)) @@ -601,25 +627,28 @@ the prompt/context line." (define-key model-keymap (kbd " ") #'eca-chat-select-model) (define-key behavior-keymap (kbd " ") #'eca-chat-select-behavior) (define-key mcp-keymap (kbd " ") #'eca-mcp-details) - (list (propertize "model:" + (list (propertize (eca-chat--header-line-label "Model" "cpu") 'font-lock-face 'eca-chat-option-key-face 'pointer 'hand 'keymap model-keymap) + + " " (propertize (eca-chat--model session) 'font-lock-face 'eca-chat-option-value-face 'pointer 'hand 'keymap model-keymap) - " " - (propertize "behavior:" + " " + (propertize (eca-chat--header-line-label "Behavior" "robot") 'font-lock-face 'eca-chat-option-key-face 'pointer 'hand 'keymap behavior-keymap) + " " (propertize (eca-chat--behavior session) 'font-lock-face 'eca-chat-option-value-face 'pointer 'hand 'keymap behavior-keymap) - " " - (propertize "mcps:" + " " + (propertize (eca-chat--header-line-label "MCPs" "server") 'font-lock-face 'eca-chat-option-key-face 'pointer 'hand 'keymap mcp-keymap) diff --git a/eca.el b/eca.el index 1c7c5c9..989c3db 100644 --- a/eca.el +++ b/eca.el @@ -3,7 +3,7 @@ ;; Author: Eric Dallo ;; Maintainer: Eric Dallo ;; Version: 0.0.1 -;; Package-Requires: ((emacs "28.1") (dash "2.18.0") (f "0.20.0") (markdown-mode "2.3") (compat "30.1")) +;; Package-Requires: ((emacs "28.1") (dash "2.18.0") (f "0.20.0") (markdown-mode "2.3") (compat "30.1") (svg-lib "0.3")) ;; Keywords: tools ;; Homepage: https://github.com/editor-code-assistant/eca-emacs ;; From e8fbd5b573f59a7779e1116c0e6ea5d4582026f2 Mon Sep 17 00:00:00 2001 From: Roman Scherer Date: Fri, 22 Aug 2025 15:51:26 +0200 Subject: [PATCH 2/3] Use default theme background as fallback --- eca-chat.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eca-chat.el b/eca-chat.el index f5090bc..513a46b 100644 --- a/eca-chat.el +++ b/eca-chat.el @@ -600,7 +600,8 @@ ICON is the name of the Bootstrap icon to display. Returns an SVG image suitable for insertion in the header line, styled to match the current theme's header-line face." (svg-lib-icon icon nil - :background (face-background 'header-line nil t) + :background (or (face-background 'header-line nil t) + (face-background 'default nil t)) :collection "bootstrap" :foreground (face-foreground 'eca-chat-option-key-face nil t) :stroke 0)) From dc5cda07e7009bc67a9d2497525a33454bae9829 Mon Sep 17 00:00:00 2001 From: Roman Scherer Date: Fri, 22 Aug 2025 15:57:06 +0200 Subject: [PATCH 3/3] Fallback to mode-line theme --- eca-chat.el | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/eca-chat.el b/eca-chat.el index 513a46b..bd60bb1 100644 --- a/eca-chat.el +++ b/eca-chat.el @@ -600,8 +600,7 @@ ICON is the name of the Bootstrap icon to display. Returns an SVG image suitable for insertion in the header line, styled to match the current theme's header-line face." (svg-lib-icon icon nil - :background (or (face-background 'header-line nil t) - (face-background 'default nil t)) + :background (face-background 'header-line nil 'mode-line) :collection "bootstrap" :foreground (face-foreground 'eca-chat-option-key-face nil t) :stroke 0))