0

I have just managed to create an overlay being a small image (the Emacs logo) which purpose is to be shown instead of a special single character in the buffer text:

Emacs logo in buffer text

I would like to place this image so that it enqueues itself perfectly into the line of small text letters, but haven't found (yet) a way to appropriately change the image position in spite of some hours of intense Internet search.

Here the only making to me sense elisp code I was able to find online and used to accomplish what you see in the above image.

;; default max-image-size defined in  src/image.c  -> 10 pixels
(setq max-image-size 128) ;; very large icon size
(defvar imgEmacsLogo16x16 
    (create-image "emacs_logo-round_icon_16x16.png" 
      nil     nil   :scale 1.0   :transform-smoothing t )
"    TYPE   DATA-P -> nil nil  Emacs logo 16x16 img "
);defvar imgEmacsLogo16x16

(defvar re-imgEmacsLogo16x16 "ä")
(setq beforStrChar "")
(setq afterStrChar "")
(setq case-fold-search nil) ;; case sensitive search
;;(setq case-fold-search t) ;; search ignoring case

(defun nextOverlay-forEmacsLogoImg16x16 (&optional limit)
  (when (re-search-forward  re-imgEmacsLogo16x16  limit    t )
    ;;   ^-- start at point  regex_string --^     BOUND  NO-ERROR  COUNT=1
    (setq  beg  (match-beginning  0) ;; 0 -> which regex capt. group? 
           end  (match-end        0)
           str  (match-string     0)
    );set the above values first then create an overlay
    (setq        ov (make-overlay  beg end))
    (overlay-put ov 'display       imgEmacsLogo16x16)
    (overlay-put ov 'face          'default)
    (overlay-put ov 'evaporate     1   )
    (overlay-put ov 'before-string beforStrChar )
    (overlay-put ov 'after-string  afterStrChar )
    (overlay-put ov 'slice         '(17 19 16 16))
    (message "nextOverlay for \"%s\" beg %s  end %s "  str beg end)))

(font-lock-add-keywords 
    nil ;; MODE nil -> curr. buffer ( lisp-mode emacs-lisp-mode python-mode ... )  
    ;; list with keywords:
    '((nextOverlay-forEmacsLogoImg16x16 (0  'font-lock-keyword-face t)))
    t)

The property slice seems to have no impact on the image position.

How can I change the relative position of the shown overlay image within the buffer text?

P.S. I am not really happy with the used code. It appears to me that it unnecessary creates one overlay after another at the same place but I am not sure if it is actually the case. In addition to it the code makes it necessary to move the cursor to the begin of the text and to do some editing there in order to get all the overlays displayed. I am wondering how it comes that I am failing to find a simple and well explained code example to see how it can be done ... Hmmm ...

Here the small logo image Emacs 16x16 Logo if you like to try the code above yourself:


UPDATE: as long as I don't know how to write code to define the anchor and the descent of an image the work around is to adjust the image to the size of the characters. This gives following result:

The size and position adjusted logo image: adjusted Logo and the result:

adjusted Logo in text

As you can see from the positioning of the logo image within the text flow here on stackexchange and in Emacs that the behavior is different. Emacs seems to place the bottom edge of the image far below the bottom line of the text.

6
  • To the extent the question relates to changing the overlay's buffer position point, rather than adjusting the image upwards / downwards without moving its point, the function move-overlay may be helpful. Another option is to use delete-overlay and place a new one elsewhere. Sometimes, it is helpful to use remove-overlays... If the aforementioned functions are not helpful to this particular use-case, then perhaps additional details in the question may be helpful ... E.g., I want to move image at buffer position X to ... Y, and then ... Z ...
    – lawlist
    Apr 18, 2023 at 0:59
  • Image alignment (ascent) may also be helpful, if applicable (e.g., center : gnu.org/software/emacs/manual/html_node/elisp/… To see/inspect what is at a current buffer position, it may be helpful to place the cursor at said position and type C-u C-x =
    – lawlist
    Apr 18, 2023 at 1:14
  • I have already discovered the part of docu with ascent, but have no idea how to write the code to specify it. There is no example there and it seems to be a property of the display property I don't know how to write the code to properly set it.
    – Claudio
    Apr 18, 2023 at 1:34
  • 1
    After :transform-smoothing t, it may be helpful to try adding something like :ascent 'center or substitute 'center with a number between 0 and 100.
    – lawlist
    Apr 18, 2023 at 2:12
  • OK ... it works. So the ascent is a property of the image and not a property of the 'display property of the overlay. Am I again in charge of writing an answer to get this question marked as answered? By the way: the image does not scale together with the text. With or without :scale and also not for nil, t and 1.0 values of :scale. Probably it must be scaled from a hook which triggers on font resize ,,.
    – Claudio
    Apr 18, 2023 at 2:44

1 Answer 1

0

For the sake of completeness and for the purpose of being able to mark this question as answered below all the comments to the question being the actual answer (status 2023-04-18 13:01 CEST):


To the extent the question relates to changing the overlay's buffer position point, rather than adjusting the image upwards / downwards without moving its point, the function move-overlay may be helpful. Another option is to use delete-overlay and place a new one elsewhere. Sometimes, it is helpful to use remove-overlays... If the aforementioned functions are not helpful to this particular use-case, then perhaps additional details in the question may be helpful ... E.g., I want to move image at buffer position X to ... Y, and then ... Z ... –  lawlist 9 hours ago

Image alignment (ascent) may also be helpful, if applicable (e.g., center : gnu.org/software/emacs/manual/html_node/elisp/… To see/inspect what is at a current buffer position, it may be helpful to place the cursor at said position and type C-u C-x = –  lawlist 9 hours ago

I have already discovered the part of docu with ascent, but have no idea how to write the code to specify it. There is no example there and it seems to be a property of the display property I don't know how to write the code to properly set it. –  Claudio 9 hours ago

After :transform-smoothing t, it may be helpful to try adding something like :ascent 'center or substitute 'center with a number between 0 and 100. –  lawlist 8 hours ago

OK ... it works. So the ascent is a property of the image and not a property of the 'display property of the overlay. Am I again in charge of writing an answer to get this question marked as answered? By the way: the image does not scale together with the text. With or without :scale and also not for nil, t and 1.0 values of :scale. Probably it must be scaled from a hook which triggers on font resize ,,. –  Claudio 8 hours ago

I would gather that scaling occurs only once when the function create-image is called; e.g., when the defvar snippet is evaluated. In terms of an answer, please feel free to write up your own answer at your convenience. Using font-lock to apply overlays, without an indication of how/when the overlays will be moved, deleted, and/or reapplied, complicates the question/answer for future forum participants .... –  lawlist 8 hours ago

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.