Subject: possible fix for string-glyph-split halts on certain emoji strings.

From: Paul Maragakis <[email-masked]>
Date: Tue, 23 Nov 2021 23:58:17 -0500

The following code fixes this bug, though there might be better ways to fix it for someone who understands the domain.
I don't know much about glyph/grapheme representations, so although this code passes my limited tests, it may break other things.

(defun pm-string-glyph-split (string)
  "Split STRING into a list of strings representing separate glyphs.
This takes into account combining characters and grapheme clusters."
  (let ((result nil)
        (start 0)
	(laststart -1) ;; the last start of a character with the composition property
        comp)
    (while (< start (length string))
      (setq comp (find-composition-internal start nil string nil))
      (if (and comp (/= laststart (car comp)))  ;; check that we don't return to same start
          (progn
            (push (substring string (car comp) (cadr comp)) result)
	    (setq laststart start)  ;; keep the start of the last successful search.
            (setq start (cadr comp)))
        (push (substring string start (1+ start)) result)
        (setq start (1+ start))))
    (nreverse result)))

Compare to the original:

(defun string-glyph-split (string)
  "Split STRING into a list of strings representing separate glyphs.
This takes into account combining characters and grapheme clusters."
  (let ((result nil)
        (start 0)
        comp)
    (while (< start (length string))
      (if (setq comp (find-composition-internal start nil string nil))
          (progn
            (push (substring string (car comp) (cadr comp)) result)
            (setq start (cadr comp)))
        (push (substring string start (1+ start)) result)
        (setq start (1+ start))))
    (nreverse result)))