commit 3ad2e2acf9f06d00fc810462602d362cec57c5aa
parent 1d738397dc5e41afed177bc9f28efeb153d64832
Author: Iqbal Ansari <iqbalansari02@yahoo.com>
Date: Sun, 18 Sep 2016 00:06:59 +0530
Cleanup display of composed text
Diffstat:
M | emojify.el | | | 93 | +++++++++++++++++++++++++++++++++++++++++++++---------------------------------- |
1 file changed, 53 insertions(+), 40 deletions(-)
diff --git a/emojify.el b/emojify.el
@@ -768,6 +768,19 @@ mark the start and end of region containing the text."
(goto-char point)
(cons (current-column) (line-number-at-pos))))
+(defun emojify--get-composed-text (point)
+ "Get the text used as composition property at POINT.
+
+This does not check if there is composition property at point the callers should
+make sure the point has a composition property otherwise this function will
+fail."
+ (emojify--string-join (mapcar #'char-to-string
+ (decode-composition-components (nth 2
+ (find-composition point
+ nil
+ nil
+ t))))))
+
;; These should be bound dynamically by functions calling
;; `emojify--inside-rectangle-selection-p' and
;; `emojify--inside-non-rectangle-selection-p' to region-beginning and
@@ -922,21 +935,41 @@ region containing the emoji."
beg
end))
-(defsubst emojify--get-composed-text (point)
- (emojify--string-join (mapcar #'char-to-string
- (decode-composition-components (nth 2
- (find-composition point
- nil
- nil
- t))))))
+(defun emojify--display-emoji (emoji text buffer start end)
+ "Display EMOJI for TEXT in BUFFER between START and END."
+ (let ((display-prop (emojify--get-text-display-props emoji start end)))
+ (when display-prop
+ (add-text-properties start
+ end
+ (list 'emojified t
+ 'emojify-display display-prop
+ 'display display-prop
+ 'emojify-buffer buffer
+ 'emojify-text text
+ 'emojify-beginning (copy-marker start)
+ 'emojify-end (copy-marker end)
+ 'yank-handler (list nil text)
+ 'keymap emojify-emoji-keymap
+ 'point-entered #'emojify-point-entered-function
+ 'help-echo #'emojify-help-function)))))
(defun emojify-display-emojis-in-region (beg end)
"Display emojis in region.
BEG and END are the beginning and end of the region respectively.
-TODO: Skip emojifying if region is already emojified."
+
+Displaying happens in two phases, first search based phase displays actual text
+appearing in buffer as emojis. In the next phase composed text is searched for
+emojis and displayed.
+
+A minor problem here is that if the text is composed after this display loop it
+would not be displayed as emoji, although in practice the two packages that use
+the composition property `prettify-symbol-mode' and `org-bullets' use the
+font-lock machinery which runs before emojify's display loop, so hopefully this
+should not be a problem 🤞."
(emojify-with-saved-buffer-state
- ;; Make sure we halt if displaying emojis takes more than a second
+ ;; Make sure we halt if displaying emojis takes more than a second (this
+ ;; might be too large duration)
(with-timeout (1 (emojify-message "Failed to display emojis under 1 second"))
(seq-doseq (regexp (apply #'append
(when emojify--user-emojis-regexp
@@ -984,27 +1017,18 @@ TODO: Skip emojifying if region is already emojified."
(emojify-looking-at-end-of-list-maybe match-end)))
(not (run-hook-with-args-until-success 'emojify-inhibit-functions match match-beginning match-end)))
-
- (let ((display-prop (emojify--get-text-display-props emoji match-beginning match-end)))
- (when display-prop
- (add-text-properties match-beginning
- match-end
- (list 'emojified t
- 'emojify-display display-prop
- 'display display-prop
- 'emojify-buffer buffer
- 'emojify-text match
- 'emojify-beginning (copy-marker match-beginning)
- 'emojify-end (copy-marker match-end)
- 'yank-handler (list nil match)
- 'keymap emojify-emoji-keymap
- 'point-entered #'emojify-point-entered-function
- 'help-echo #'emojify-help-function)))))))
+ (emojify--display-emoji emoji match buffer match-beginning match-end))))
;; Stop a bit to let `with-timeout' kick in
(sit-for 0 t)))
+
;; Loop to emojify composed text
(goto-char beg)
(let ((compose-start (if (get-text-property beg 'composition)
+ ;; Check `beg' first for composition property
+ ;; since `next-single-property-change' will
+ ;; search for region after `beg' for property
+ ;; change thus skipping any composed text at
+ ;; `beg'
beg
(next-single-property-change beg
'composition
@@ -1014,27 +1038,16 @@ TODO: Skip emojifying if region is already emojified."
(let* ((match (emojify--get-composed-text compose-start))
(emoji (emojify-get-emoji match))
(compose-end (next-single-property-change compose-start 'composition)))
+ ;; Display only composed text that is unicode char
(when (and emoji (string= (gethash "style" emoji) "unicode"))
- (let ((display-prop (emojify--get-text-display-props emoji compose-start compose-end)))
- (when display-prop
- (add-text-properties compose-start
- compose-end
- (list 'emojified t
- 'emojify-display display-prop
- 'display display-prop
- 'emojify-buffer (current-buffer)
- 'emojify-text match
- 'emojify-beginning (copy-marker compose-start)
- 'emojify-end (copy-marker compose-end)
- 'yank-handler (list nil match)
- 'keymap emojify-emoji-keymap
- 'point-entered #'emojify-point-entered-function
- 'help-echo #'emojify-help-function)))))
+ (emojify--display-emoji emoji match (current-buffer) compose-start compose-end))
+ ;; Setup the next loop
(setq compose-start (and compose-end (next-single-property-change compose-end
'composition
nil
end)))
(goto-char compose-end))
+ ;; Stop a bit to let `with-timeout' kick in
(sit-for 0 t))))))
(defun emojify-undisplay-emojis-in-region (beg end)