I found a solution that basically uses this question to get the width of one char (based on font-get-glyphs
), and then I use default-font-width
to get the width of a column, and then I add a space using the display
text property (I don't know why but I needed to create a new temporary variable to make sure it's a buffer-local variable, if you have a better code let me know).
;; https://emacs.stackexchange.com/questions/5495/how-can-i-determine-the-width-of-characters-on-the-screen
(defun my-char-width (char_str)
"Return the width in pixels of a character in the current
window's default font. More precisely, this returns the
width of the letter ‘m’. If the font is mono-spaced, this
will also be the width of all other printable characters."
(let ((window (selected-window))
(remapping face-remapping-alist))
(with-temp-buffer
(make-local-variable 'face-remapping-alist)
(setq face-remapping-alist remapping)
(set-window-buffer window (current-buffer))
(insert char_str)
(aref (aref (font-get-glyphs (font-at 1) 1 2) 0) 4))))
(defun insert_in_n_columns (cols_nb str)
"Insert as much element of list_char as possible, until it goes
out of n cols. 'Begin' is useless for the user."
(cl-labels ((aux (rem_px rem_l)
(if (null rem_l) ;; Empty list, fill with big space
(progn
;; Cannot use the local variable...
;; Better way than using a tmp variable?
(insert
(propertize " "
'display
`(space . (:width (,rem_px))))))
(progn
;; Get first element, remaining part,
;; and with of first elt
(let* ((c (car rem_l))
(r (cdr rem_l))
(w (my-char-width c)))
;; If there is enough space for the char, insert it
(if (<= w rem_px)
(progn
(insert c)
(aux (- rem_px w) r))
(progn
(if (not (eq rem_px 0))
;; Else fill with the good space
(progn
(insert
(propertize " "
'display
`(space . (:width (,rem_px)))))
)))))))))
(aux (* cols_nb (default-font-width)) (string-to-list str))))
;; Demo:
;; (insert_in_n_columns 4 "ab⏚")
;; (insert_in_n_columns 4 "ab⚴d")
;; (insert_in_n_columns 4 "abc⏚d")
Demo:
NB: the same idea can be used with images.
compose-chars-after-function
variable may be a worthwhile thing to look at.compose-chars-after-function
.