Fix deletion of composed text

* lisp/composite.el (lgstring-glyph-boundary): New function.
* lisp/simple.el (delete-forward-char): Call
'lgstring-glyph-boundary' to find where to end the deletion inside
an automatic composition.  (Bug#56237)
This commit is contained in:
Eli Zaretskii 2022-06-27 15:32:53 +03:00
parent f9f41c586a
commit 0190dff96a
2 changed files with 35 additions and 6 deletions

View file

@ -474,6 +474,25 @@ after a sequence of character events."
(aset gstring (1- len) nil))
gstring)
(defun lgstring-glyph-boundary (gstring startpos endpos)
"Return buffer position at or after ENDPOS where grapheme from GSTRING ends.
STARTPOS is the position where the grapheme cluster starts; it is returned
by `find-composition'."
(let ((nglyphs (lgstring-glyph-len gstring))
(idx 0)
glyph found)
(while (and (not found) (< idx nglyphs))
(setq glyph (lgstring-glyph gstring idx))
(cond
((or (null glyph)
(= (+ startpos (lglyph-from glyph)) endpos))
(setq found endpos))
((>= (+ startpos (lglyph-to glyph)) endpos)
(setq found (+ startpos (lglyph-to glyph) 1)))
(t
(setq idx (1+ idx)))))
(or found endpos)))
(defun compose-glyph-string (gstring from to)
(let ((glyph (lgstring-glyph gstring from))
from-pos to-pos)

View file

@ -1507,12 +1507,22 @@ the actual saved text might be different from what was killed."
(while (> n 0)
;; 'find-composition' will return (FROM TO ....) or nil.
(setq cmp (find-composition pos))
(if cmp
;; TO can be at POS, in which case we want to make
;; sure we advance at least by 1 character.
(let ((cmp-end (cadr cmp)))
(setq pos (max (1+ pos) cmp-end)))
(setq pos (1+ pos)))
(setq pos
(if cmp
(let ((from (car cmp))
(to (cadr cmp)))
(cond
((= (length cmp) 2) ; static composition
to)
;; TO can be at POS, in which case we want
;; to make sure we advance at least by 1
;; character.
((<= to pos)
(1+ pos))
(t
(lgstring-glyph-boundary (nth 2 cmp)
from (1+ pos)))))
(1+ pos)))
(setq n (1- n)))
(delete-char (- pos start) killflag)))