[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
scratch/emoji 93a835c: Start implementation of an emoji input system bas
From: |
Lars Ingebrigtsen |
Subject: |
scratch/emoji 93a835c: Start implementation of an emoji input system based on transient |
Date: |
Mon, 25 Oct 2021 23:34:51 -0400 (EDT) |
branch: scratch/emoji
commit 93a835c652c98bf0086258c1c18c7ca47747c797
Author: Lars Ingebrigtsen <larsi@gnus.org>
Commit: Lars Ingebrigtsen <larsi@gnus.org>
Start implementation of an emoji input system based on transient
---
admin/unidata/labels.txt | 196 +++++++++++++++++++++++++++++++++++++++++++++++
lisp/play/emoji.el | 191 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 387 insertions(+)
diff --git a/admin/unidata/labels.txt b/admin/unidata/labels.txt
new file mode 100644
index 0000000..5b35bf5
--- /dev/null
+++ b/admin/unidata/labels.txt
@@ -0,0 +1,196 @@
+# labels.txt
+# Copyright ยฉ 1991-2016 Unicode, Inc.
+# CLDR data files are interpreted according to the LDML specification
(http://unicode.org/reports/tr35/)
+# For terms of use, see http://www.unicode.org/copyright.html
+#
+# This file provides information for mapping character labels to sets of
characters.
+# The characters should normally be sorted using CLDR collation data, but that
order may be further customized.
+# For example, lists of brackets may be ordered to show pairs together.
+# The data is not in XML; instead it uses a variant of the UCD semicolon
format for compactness and maintainability:
+# Format:
+# Field 0: a hex Unicode character, or a hex Unicode character range, or a
UnicodeSet.
+# Field 1: a label that applies to that character.
+# Field 2: a second-level label (optional) that applies to that character.
+# Any field that would contain a literal โ;โ has that replaced by \u003B.
+# Note that characters may get multiple labels.
+
+[โบ๐-๐๐-๐๐๐๐-๐๐๐ค] ; Smileys & People ; face-positive
+[๐คฃ๐คฉ๐ฅฐ] ; Smileys & People ; face-positive
+[๐๐-๐๐-๐๐ฃ๐ฅ๐ช๐ซ๐ฎ๐ฏ] ; Smileys & People ; face-neutral
+[๐ฒ๐ด๐ถ๐๐๐ค๐ค๐ค๐คค๐คจ] ; Smileys & People ; face-neutral
+[โน๐๐-๐ข๐ค๐ฆ-๐ฉ๐ฌ๐ญ๐ฐ๐ฑ] ; Smileys & People ; face-negative
+[๐ณ๐ต๐๐คช๐คฌ๐คฏ๐ฅต๐ฅถ] ; Smileys & People ; face-negative
+[๐ท๐ค๐ค๐คข๐คง๐คฎ] ; Smileys & People ; face-sick
+[๐๐ค๐ค ๐คฅ๐คซ๐คญ๐ฅณ๐ฅด๐ฅบ๐ง] ; Smileys & People ; face-role
+[โ ๐น-๐ป๐ฝ-๐๐ฉ๐๐ค๐คก] ; Smileys & People ; face-fantasy
+[๐ธ-๐] ; Smileys & People ; cat-face
+[๐-๐] ; Smileys & People ; monkey-face
+[๐ป-๐ฟ] ; Smileys & People ; skin-tone
+[๐ฆ-๐ฉ๐ด-๐ถ๐ง-๐ง] ; Smileys & People ; person
+[๐ฎ๐ฐ-๐ณ๐ท๐ธ๐๐ต๐คฐ๐คฑ๐คด๐คต] ; Smileys & People ; person-role
+[๐ง๐ง{๐จโโ๏ธ}{๐จโโ๏ธ}{๐จโโ๏ธ}{๐จโ๐พ}{๐จโ๐ณ}] ; Smileys & People ;
person-role
+[{๐จโ๐}{๐จโ๐ค}{๐จโ๐จ}{๐จโ๐ซ}{๐จโ๐ญ}{๐จโ๐ป}] ; Smileys & People ;
person-role
+[{๐จโ๐ผ}{๐จโ๐ง}{๐จโ๐ฌ}{๐จโ๐}{๐จโ๐}{๐จโ๐ฆฐ}] ; Smileys & People ;
person-role
+[{๐จโ๐ฆฑ}{๐จโ๐ฆฒ}{๐จโ๐ฆณ}{๐ฉโโ๏ธ}{๐ฉโโ๏ธ}{๐ฉโโ๏ธ}] ; Smileys & People ;
person-role
+[{๐ฉโ๐พ}{๐ฉโ๐ณ}{๐ฉโ๐}{๐ฉโ๐ค}{๐ฉโ๐จ}{๐ฉโ๐ซ}] ; Smileys & People ;
person-role
+[{๐ฉโ๐ญ}{๐ฉโ๐ป}{๐ฉโ๐ผ}{๐ฉโ๐ง}{๐ฉโ๐ฌ}{๐ฉโ๐}] ; Smileys & People ;
person-role
+[{๐ฉโ๐}{๐ฉโ๐ฆฐ}{๐ฉโ๐ฆฑ}{๐ฉโ๐ฆฒ}{๐ฉโ๐ฆณ}{๐ฎโโ๏ธ}] ; Smileys & People ;
person-role
+[{๐ฎโโ๏ธ}{๐ฑโโ๏ธ}{๐ฑโโ๏ธ}{๐ณโโ๏ธ}{๐ณโโ๏ธ}{๐ทโโ๏ธ}] ; Smileys & People ;
person-role
+[{๐ทโโ๏ธ}{๐โโ๏ธ}{๐โโ๏ธ}{๐ต๏ธโโ๏ธ}{๐ต๏ธโโ๏ธ}] ; Smileys & People ;
person-role
+[๐
๐ผ๐คถ๐ฆธ๐ฆน๐ง-๐ง{๐ฆธโโ๏ธ}{๐ฆธโโ๏ธ}] ; Smileys & People ; person-fantasy
+[{๐ฆนโโ๏ธ}{๐ฆนโโ๏ธ}{๐งโโ๏ธ}{๐งโโ๏ธ}{๐งโโ๏ธ}{๐งโโ๏ธ}] ; Smileys & People ;
person-fantasy
+[{๐งโโ๏ธ}{๐งโโ๏ธ}{๐งโโ๏ธ}{๐งโโ๏ธ}{๐งโโ๏ธ}{๐งโโ๏ธ}] ; Smileys & People ;
person-fantasy
+[{๐งโโ๏ธ}{๐งโโ๏ธ}{๐งโโ๏ธ}{๐งโโ๏ธ}] ; Smileys & People ; person-fantasy
+[๐๐
-๐๐๐๐๐คฆ๐คท{๐โโ๏ธ}{๐โโ๏ธ}] ; Smileys & People ; person-gesture
+[{๐
โโ๏ธ}{๐
โโ๏ธ}{๐โโ๏ธ}{๐โโ๏ธ}{๐โโ๏ธ}{๐โโ๏ธ}] ; Smileys & People ;
person-gesture
+[{๐โโ๏ธ}{๐โโ๏ธ}{๐โโ๏ธ}{๐โโ๏ธ}{๐โโ๏ธ}{๐โโ๏ธ}] ; Smileys & People ;
person-gesture
+[{๐คฆโโ๏ธ}{๐คฆโโ๏ธ}{๐คทโโ๏ธ}{๐คทโโ๏ธ}] ; Smileys & People ; person-gesture
+[๐๐ค๐ฅ๐ฏ๐๐๐๐ด๐บ๐ฃ๐ถ] ; Smileys & People ; person-activity
+[๐๐๐ง-๐ง{๐โโ๏ธ}{๐โโ๏ธ}{๐ฏโโ๏ธ}{๐ฏโโ๏ธ}] ; Smileys & People ;
person-activity
+[{๐โโ๏ธ}{๐โโ๏ธ}{๐โโ๏ธ}{๐โโ๏ธ}{๐ถโโ๏ธ}{๐ถโโ๏ธ}] ; Smileys & People ;
person-activity
+[{๐งโโ๏ธ}{๐งโโ๏ธ}{๐งโโ๏ธ}{๐งโโ๏ธ}{๐งโโ๏ธ}{๐งโโ๏ธ}] ; Smileys & People ;
person-activity
+[โทโน๐๐๐๐-๐๐ฃ๐ด๐ต๐คธ-๐คบ] ; Smileys & People ; person-sport
+[๐คผ-๐คพ{โน๏ธโโ๏ธ}{โน๏ธโโ๏ธ}{๐โโ๏ธ}{๐โโ๏ธ}{๐โโ๏ธ}] ; Smileys & People ;
person-sport
+[{๐โโ๏ธ}{๐๏ธโโ๏ธ}{๐๏ธโโ๏ธ}{๐๏ธโโ๏ธ}{๐๏ธโโ๏ธ}{๐ฃโโ๏ธ}] ; Smileys & People ;
person-sport
+[{๐ฃโโ๏ธ}{๐ดโโ๏ธ}{๐ดโโ๏ธ}{๐ตโโ๏ธ}{๐ตโโ๏ธ}{๐คธโโ๏ธ}] ; Smileys & People ;
person-sport
+[{๐คธโโ๏ธ}{๐คนโโ๏ธ}{๐คนโโ๏ธ}{๐คผโโ๏ธ}{๐คผโโ๏ธ}{๐คฝโโ๏ธ}] ; Smileys & People ;
person-sport
+[{๐คฝโโ๏ธ}{๐คพโโ๏ธ}{๐คพโโ๏ธ}] ; Smileys & People ; person-sport
+[๐ช-๐ญ๐๐{๐จโโค๏ธโ๐จ}{๐จโโค๏ธโ๐โ๐จ}{๐จโ๐ฆ}{๐จโ๐ฆโ๐ฆ}] ; Smileys & People ;
family
+[{๐จโ๐ง}{๐จโ๐งโ๐ฆ}{๐จโ๐งโ๐ง}{๐จโ๐จโ๐ฆ}{๐จโ๐จโ๐ฆโ๐ฆ}{๐จโ๐จโ๐ง}] ; Smileys & People ;
family
+[{๐จโ๐จโ๐งโ๐ฆ}{๐จโ๐จโ๐งโ๐ง}{๐จโ๐ฉโ๐ฆ}{๐จโ๐ฉโ๐ฆโ๐ฆ}{๐จโ๐ฉโ๐ง}{๐จโ๐ฉโ๐งโ๐ฆ}] ; Smileys & People
; family
+[{๐จโ๐ฉโ๐งโ๐ง}{๐ฉโโค๏ธโ๐จ}{๐ฉโโค๏ธโ๐ฉ}{๐ฉโโค๏ธโ๐โ๐จ}{๐ฉโโค๏ธโ๐โ๐ฉ}{๐ฉโ๐ฆ}] ; Smileys & People
; family
+[{๐ฉโ๐ฆโ๐ฆ}{๐ฉโ๐ง}{๐ฉโ๐งโ๐ฆ}{๐ฉโ๐งโ๐ง}{๐ฉโ๐ฉโ๐ฆ}{๐ฉโ๐ฉโ๐ฆโ๐ฆ}] ; Smileys & People ;
family
+[{๐ฉโ๐ฉโ๐ง}{๐ฉโ๐ฉโ๐งโ๐ฆ}{๐ฉโ๐ฉโ๐งโ๐ง}] ; Smileys & People ; family
+[โโ-โ๐-๐๐ฃ๐
๐ช๐๐๐] ; Smileys & People ; body
+[๐๐๐ค-๐ค๐คฒ๐คณ๐ฆฐ-๐ฆท๐ง {๐๏ธโ๐จ๏ธ}] ; Smileys & People ; body
+[โฃโค๐๐๐-๐๐ข-๐ฆ๐จ๐ซ-๐ญ] ; Smileys & People ; emotion
+[๐ณ๐ค๐จ๐ฏ๐งก] ; Smileys & People ; emotion
+[โ๐๐๐ฉ๐-๐ข๐๐๐๐ฟ๐ถ] ; Smileys & People ; clothing
+[๐๐ฅผ-๐ฅฟ๐งข-๐งฆ] ; Smileys & People ; clothing
+[๐-๐๐-๐๐-๐๐จ-๐ซ๐ญ-๐ฑ๐ด-๐ท] ; Animals & Nature ; animal-mammal
+[๐น-๐ฟ๐ฆ๐ฆ๐ฆ๐ฆ๐ฆ๐ฆ๐ฆ๐ฆ-๐ฆ] ; Animals & Nature ; animal-mammal
+[๐ฆ๐ฆ๐ฆ๐ฆ๐ฆก] ; Animals & Nature ; animal-mammal
+[๐๐๐ฃ-๐ง๐๐ฆ๐ฆ
๐ฆ๐ฆ๐ฆ๐ฆ] ; Animals & Nature ; animal-bird
+[๐ฆข] ; Animals & Nature ;
animal-bird
+[๐ธ] ; Animals & Nature ;
animal-amphibian
+[๐๐๐๐ข๐ฒ๐ฆ๐ฆ๐ฆ] ; Animals & Nature ; animal-reptile
+[๐๐๐๐-๐ก๐ฌ๐ณ๐ฆ๐ฆ๐ฆ๐ฆ] ; Animals & Nature ; animal-marine
+[๐ฆ] ; Animals & Nature ;
animal-marine
+[๐๐-๐๐ท๐ธ๐ฆ๐ฆ๐ฆ๐ฆ๐ฆ ] ; Animals & Nature ; animal-bug
+[๐ท-๐ผ๐ต๐๐ฎ๐ฅ] ; Animals & Nature ; plant-flower
+[โ๐ฑ-๐ต๐พ-๐] ; Animals & Nature ; plant-other
+[๐
๐-๐๐ฅ๐ฅฅ๐ฅญ] ; Food & Drink ; food-fruit
+[๐ฐ๐ถ๐ฝ๐๐๐ฅ๐ฅ๐ฅ๐ฅ๐ฅ๐ฅฆ] ; Food & Drink ; food-vegetable
+[๐ฅฌ] ; Food & Drink ; food-vegetable
+[๐ญ-๐ฏ๐-๐๐๐๐ฒ๐ณ๐ฟ๐ฅ๐ฅ] ; Food & Drink ; food-prepared
+[๐ฅ-๐ฅ๐ฅ๐ฅฃ๐ฅจ-๐ฅซ๐ฅฏ๐ง๐ง] ; Food & Drink ; food-prepared
+[๐-๐๐ -๐ฅ๐ฑ๐ฅ-๐ฅก๐ฅฎ] ; Food & Drink ; food-asian
+[๐ฆ-๐ฐ๐๐ฅง๐ง] ; Food & Drink ; food-sweet
+[โ๐ต-๐ผ๐พ๐ฅ๐ฅ๐ฅ๐ฅค] ; Food & Drink ; drink
+[๐ด๐ฝ๐บ๐ช๐ฅ๐ฅข] ; Food & Drink ; dishware
+[๐-๐๐บ๐พ๐งญ] ; Travel & Places ; place-map
+[โฐ๐๐-๐๐-๐๐ป] ; Travel & Places ; place-geographic
+[๐๐๐๐๐-๐ฆ๐จ-๐ญ๐ฏ๐ฐ๐] ; Travel & Places ; place-building
+[๐ผ๐ฝ๐งฑ] ; Travel & Places ; place-building
+[โฉโช๐-๐] ; Travel & Places ; place-religious
+[โจโฒโบ๐๐-๐๐๐๐ -๐ข๐ช] ; Travel & Places ; place-other
+[๐๐] ; Travel & Places ; place-other
+[โฝ๐-๐๐ฅ-๐จ๐ฒ๐๐ข-๐ค๐ด๐ต] ; Travel & Places ; transport-ground
+[๐น] ; Travel & Places ; transport-ground
+[โโดโต๐ข๐ค๐ฅ๐ณ๐ถ] ; Travel & Places ; transport-water
+[โ๐บ๐๐๐-๐ก๐ฉ๐ซ๐ฌ๐ฐ๐ธ] ; Travel & Places ; transport-air
+[๐๐งณ] ; Travel & Places ; hotel
+[โโโฐ-โณ๐-๐ง๐ฐ] ; Travel & Places ; time
+[โ-โโโกโโ
โโฑโโญ๐] ; Travel & Places ; sky & weather
+[๐๐๐๐-๐ก๐ค-๐ฌ๐ง๐ฅ] ; Travel & Places ; sky & weather
+[โจ๐๐๐๐๐-๐๐-๐๐๐] ; Activities ; event
+[๐ซ๐งง๐งจ] ; Activities ; event
+[๐๐
๐๐ฅ-๐ฅ] ; Activities ; award-medal
+[โฝโพโณโธ๐ฃ๐ณ๐ฝ-๐๐๐๐-๐] ; Activities ; sport
+[๐ธ๐ท๐ฅ
๐ฅ-๐ฅ] ; Activities ; sport
+[โโ โฃโฅโฆ๐๐๐ฎ-๐ฒ๐ด๐ฎ] ; Activities ; game
+[๐น๐งฉ๐งธ๐งฟ] ; Activities ; game
+[๐จ๐ญ๐ผ๐งต๐งถ] ; Activities ; arts & crafts
+[๐ข๐ฃ๐ฏ๐-๐๐๐] ; Objects ; sound
+[๐-๐๐ค๐ง๐ต๐ถ๐ผ๐ป] ; Objects ; music
+[๐ท-๐ป๐ฅ] ; Objects ; musical-instrument
+[โ๐-๐ ๐ฑ๐ฒ] ; Objects ; phone
+[โจ๐ป๐ฝ-๐๐๐๐ฅ๐จ๐ฑ๐ฒ๐งฎ] ; Objects ; computer
+[๐๐ฅ๐ฌ๐ฎ๐ก๐ท-๐บ๐ผ๐ฝ๐๐] ; Objects ; light & video
+[๐ฆ๐ฏ] ; Objects ; light & video
+[๐ท๐๐๐-๐๐๐ฐ๐๐] ; Objects ; book-paper
+[๐ฐ-๐น๐งพ] ; Objects ; money
+[โ๐ค-๐ฎ๐ณ] ; Objects ; mail
+[โโ๐๐-๐] ; Objects ; writing
+[โ๐ผ๐๐๐
-๐๐๐-๐๐-๐] ; Objects ; office
+[๐-๐๐] ; Objects ; lock
+[โโโโโโ๐น๐๐ง-๐ฉ๐ซ] ; Objects ; tool
+[๐๐ก๐ ๐ก๐งฐ๐งฒ] ; Objects ; tool
+[โ๐ก๐ฌ๐ญ๐งช-๐งฌ] ; Objects ; science
+[๐๐] ; Objects ; medical
+[๐ช๐ฝ๐ฟ๐๐๐๐๐งฏ๐งด๐งท๐งน-๐งฝ] ; Objects ; household
+[โฐโฑ๐ฟ๐ฌ] ; Objects ; other-object
+[โฟ๐ง๐ฎ๐ฐ๐น-๐ผ๐พ๐-๐
] ; Symbols ; transport-sign
+[โขโฃโ โ๐ต๐๐ซ๐ญ๐ฏ๐ฑ๐ณ] ; Symbols ; warning
+[๐ท๐ธ] ; Symbols ; warning
+[โ-โโฉโชโกโคดโคตโฌ
-โฌ๐๐] ; Symbols ; arrow
+[๐-๐] ; Symbols ; arrow
+[โฆโชโฎโฏโธโโโก๐ฏ๐๐] ; Symbols ; religion
+[๐] ; Symbols ; religion
+[โ-โโ] ; Symbols ; zodiac
+[โโฉ-โฏโธ-โบโถโ๐ฆ๐ณ๐ด๐ถ] ; Symbols ; av-symbol
+[๐-๐๐
๐๐ผ๐ฝ] ; Symbols ; av-symbol
+[ยฉยฎโผโโขโโโโปโพโ] ; Symbols ; other-symbol
+[โโ
โโโณโดโโโโ-โ] ; Symbols ; other-symbol
+[โโ-โโฐโฟโญใฐใฝ๐๐ฐ๐ฑ] ; Symbols ; other-symbol
+[๐{#๏ธโฃ}{*๏ธโฃ}{0๏ธโฃ}{1๏ธโฃ}{2๏ธโฃ}] ; Symbols ; keycap
+[{3๏ธโฃ}{4๏ธโฃ}{5๏ธโฃ}{6๏ธโฃ}{7๏ธโฃ}{8๏ธโฃ}] ; Symbols ; keycap
+[{9๏ธโฃ}] ; Symbols ; keycap
+[โนโใใ๐
ฐ๐
ฑ๐
พ๐
ฟ๐๐-๐] ; Symbols ; alphanum
+[๐๐๐๐ฏ๐ฒ-๐บ๐๐๐ฏ๐ -๐ค] ; Symbols ; alphanum
+[โชโซโป-โพโชโซโฌโฌ๐ ๐๐ฒ-๐ป] ; Symbols ; geometric
+[๐๐๐ณ๐ด๐ฉ{๐ณ๏ธโ๐}{๐ดโโ ๏ธ}] ; Flags ; flag
+[{๐ฆ๐จ}{๐ฆ๐ฉ}{๐ฆ๐ช}{๐ฆ๐ซ}{๐ฆ๐ฌ}{๐ฆ๐ฎ}] ; Flags ; country-flag
+[{๐ฆ๐ฑ}{๐ฆ๐ฒ}{๐ฆ๐ด}{๐ฆ๐ถ}{๐ฆ๐ท}{๐ฆ๐ธ}] ; Flags ; country-flag
+[{๐ฆ๐น}{๐ฆ๐บ}{๐ฆ๐ผ}{๐ฆ๐ฝ}{๐ฆ๐ฟ}{๐ง๐ฆ}] ; Flags ; country-flag
+[{๐ง๐ง}{๐ง๐ฉ}{๐ง๐ช}{๐ง๐ซ}{๐ง๐ฌ}{๐ง๐ญ}] ; Flags ; country-flag
+[{๐ง๐ฎ}{๐ง๐ฏ}{๐ง๐ฑ}{๐ง๐ฒ}{๐ง๐ณ}{๐ง๐ด}] ; Flags ; country-flag
+[{๐ง๐ถ}{๐ง๐ท}{๐ง๐ธ}{๐ง๐น}{๐ง๐ป}{๐ง๐ผ}] ; Flags ; country-flag
+[{๐ง๐พ}{๐ง๐ฟ}{๐จ๐ฆ}{๐จ๐จ}{๐จ๐ฉ}{๐จ๐ซ}] ; Flags ; country-flag
+[{๐จ๐ฌ}{๐จ๐ญ}{๐จ๐ฎ}{๐จ๐ฐ}{๐จ๐ฑ}{๐จ๐ฒ}] ; Flags ; country-flag
+[{๐จ๐ณ}{๐จ๐ด}{๐จ๐ต}{๐จ๐ท}{๐จ๐บ}{๐จ๐ป}] ; Flags ; country-flag
+[{๐จ๐ผ}{๐จ๐ฝ}{๐จ๐พ}{๐จ๐ฟ}{๐ฉ๐ช}{๐ฉ๐ฌ}] ; Flags ; country-flag
+[{๐ฉ๐ฏ}{๐ฉ๐ฐ}{๐ฉ๐ฒ}{๐ฉ๐ด}{๐ฉ๐ฟ}{๐ช๐ฆ}] ; Flags ; country-flag
+[{๐ช๐จ}{๐ช๐ช}{๐ช๐ฌ}{๐ช๐ญ}{๐ช๐ท}{๐ช๐ธ}] ; Flags ; country-flag
+[{๐ช๐น}{๐ช๐บ}{๐ซ๐ฎ}{๐ซ๐ฏ}{๐ซ๐ฐ}{๐ซ๐ฒ}] ; Flags ; country-flag
+[{๐ซ๐ด}{๐ซ๐ท}{๐ฌ๐ฆ}{๐ฌ๐ง}{๐ฌ๐ฉ}{๐ฌ๐ช}] ; Flags ; country-flag
+[{๐ฌ๐ซ}{๐ฌ๐ฌ}{๐ฌ๐ญ}{๐ฌ๐ฎ}{๐ฌ๐ฑ}{๐ฌ๐ฒ}] ; Flags ; country-flag
+[{๐ฌ๐ณ}{๐ฌ๐ต}{๐ฌ๐ถ}{๐ฌ๐ท}{๐ฌ๐ธ}{๐ฌ๐น}] ; Flags ; country-flag
+[{๐ฌ๐บ}{๐ฌ๐ผ}{๐ฌ๐พ}{๐ญ๐ฐ}{๐ญ๐ฒ}{๐ญ๐ณ}] ; Flags ; country-flag
+[{๐ญ๐ท}{๐ญ๐น}{๐ญ๐บ}{๐ฎ๐จ}{๐ฎ๐ฉ}{๐ฎ๐ช}] ; Flags ; country-flag
+[{๐ฎ๐ฑ}{๐ฎ๐ฒ}{๐ฎ๐ณ}{๐ฎ๐ด}{๐ฎ๐ถ}{๐ฎ๐ท}] ; Flags ; country-flag
+[{๐ฎ๐ธ}{๐ฎ๐น}{๐ฏ๐ช}{๐ฏ๐ฒ}{๐ฏ๐ด}{๐ฏ๐ต}] ; Flags ; country-flag
+[{๐ฐ๐ช}{๐ฐ๐ฌ}{๐ฐ๐ญ}{๐ฐ๐ฎ}{๐ฐ๐ฒ}{๐ฐ๐ณ}] ; Flags ; country-flag
+[{๐ฐ๐ต}{๐ฐ๐ท}{๐ฐ๐ผ}{๐ฐ๐พ}{๐ฐ๐ฟ}{๐ฑ๐ฆ}] ; Flags ; country-flag
+[{๐ฑ๐ง}{๐ฑ๐จ}{๐ฑ๐ฎ}{๐ฑ๐ฐ}{๐ฑ๐ท}{๐ฑ๐ธ}] ; Flags ; country-flag
+[{๐ฑ๐น}{๐ฑ๐บ}{๐ฑ๐ป}{๐ฑ๐พ}{๐ฒ๐ฆ}{๐ฒ๐จ}] ; Flags ; country-flag
+[{๐ฒ๐ฉ}{๐ฒ๐ช}{๐ฒ๐ซ}{๐ฒ๐ฌ}{๐ฒ๐ญ}{๐ฒ๐ฐ}] ; Flags ; country-flag
+[{๐ฒ๐ฑ}{๐ฒ๐ฒ}{๐ฒ๐ณ}{๐ฒ๐ด}{๐ฒ๐ต}{๐ฒ๐ถ}] ; Flags ; country-flag
+[{๐ฒ๐ท}{๐ฒ๐ธ}{๐ฒ๐น}{๐ฒ๐บ}{๐ฒ๐ป}{๐ฒ๐ผ}] ; Flags ; country-flag
+[{๐ฒ๐ฝ}{๐ฒ๐พ}{๐ฒ๐ฟ}{๐ณ๐ฆ}{๐ณ๐จ}{๐ณ๐ช}] ; Flags ; country-flag
+[{๐ณ๐ซ}{๐ณ๐ฌ}{๐ณ๐ฎ}{๐ณ๐ฑ}{๐ณ๐ด}{๐ณ๐ต}] ; Flags ; country-flag
+[{๐ณ๐ท}{๐ณ๐บ}{๐ณ๐ฟ}{๐ด๐ฒ}{๐ต๐ฆ}{๐ต๐ช}] ; Flags ; country-flag
+[{๐ต๐ซ}{๐ต๐ฌ}{๐ต๐ญ}{๐ต๐ฐ}{๐ต๐ฑ}{๐ต๐ฒ}] ; Flags ; country-flag
+[{๐ต๐ณ}{๐ต๐ท}{๐ต๐ธ}{๐ต๐น}{๐ต๐ผ}{๐ต๐พ}] ; Flags ; country-flag
+[{๐ถ๐ฆ}{๐ท๐ช}{๐ท๐ด}{๐ท๐ธ}{๐ท๐บ}{๐ท๐ผ}] ; Flags ; country-flag
+[{๐ธ๐ฆ}{๐ธ๐ง}{๐ธ๐จ}{๐ธ๐ฉ}{๐ธ๐ช}{๐ธ๐ฌ}] ; Flags ; country-flag
+[{๐ธ๐ญ}{๐ธ๐ฎ}{๐ธ๐ฏ}{๐ธ๐ฐ}{๐ธ๐ฑ}{๐ธ๐ฒ}] ; Flags ; country-flag
+[{๐ธ๐ณ}{๐ธ๐ด}{๐ธ๐ท}{๐ธ๐ธ}{๐ธ๐น}{๐ธ๐ป}] ; Flags ; country-flag
+[{๐ธ๐ฝ}{๐ธ๐พ}{๐ธ๐ฟ}{๐น๐ฆ}{๐น๐จ}{๐น๐ฉ}] ; Flags ; country-flag
+[{๐น๐ซ}{๐น๐ฌ}{๐น๐ญ}{๐น๐ฏ}{๐น๐ฐ}{๐น๐ฑ}] ; Flags ; country-flag
+[{๐น๐ฒ}{๐น๐ณ}{๐น๐ด}{๐น๐ท}{๐น๐น}{๐น๐ป}] ; Flags ; country-flag
+[{๐น๐ผ}{๐น๐ฟ}{๐บ๐ฆ}{๐บ๐ฌ}{๐บ๐ฒ}{๐บ๐ณ}] ; Flags ; country-flag
+[{๐บ๐ธ}{๐บ๐พ}{๐บ๐ฟ}{๐ป๐ฆ}{๐ป๐จ}{๐ป๐ช}] ; Flags ; country-flag
+[{๐ป๐ฌ}{๐ป๐ฎ}{๐ป๐ณ}{๐ป๐บ}{๐ผ๐ซ}{๐ผ๐ธ}] ; Flags ; country-flag
+[{๐ฝ๐ฐ}{๐พ๐ช}{๐พ๐น}{๐ฟ๐ฆ}{๐ฟ๐ฒ}{๐ฟ๐ผ}] ; Flags ; country-flag
+[{๐ด๓ ง๓ ข๓ ฅ๓ ฎ๓ ง๓ ฟ}{๐ด๓ ง๓ ข๓ ณ๓ ฃ๓ ด๓ ฟ}{๐ด๓ ง๓ ข๓ ท๓ ฌ๓ ณ๓ ฟ}] ; Flags ; subdivision-flag
diff --git a/lisp/play/emoji.el b/lisp/play/emoji.el
new file mode 100644
index 0000000..fdde7fc
--- /dev/null
+++ b/lisp/play/emoji.el
@@ -0,0 +1,191 @@
+;;; emoji.el --- Inserting emojis -*- lexical-binding:t -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; Author: Lars Ingebrigtsen <larsi@gnus.org>
+;; Keywords: fun
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(eval-when-compile (require 'cl-lib))
+
+(defvar emoji--labels nil)
+
+(defun emoji--parse-labels ()
+ (setq emoji--labels nil)
+ (with-temp-buffer
+ (insert-file-contents (expand-file-name "../admin/unidata/labels.txt"
+ data-directory))
+ ;; The format is "[...] ; Main ; sub".
+ (while (re-search-forward "^\\[\\([^]]+\\)\\][ \t]*;[ \t]*\\(.*?\\)[
\t]*;[ \t]*\\(.*\\)$" nil t)
+ (let ((ranges (match-string 1))
+ (main (match-string 2))
+ (sub (match-string 3)))
+ (emoji--add-characters
+ (cl-loop with range-start
+ and set
+ for char across ranges
+ ;; a-z
+ if (eql char ?-)
+ do (setq range-start (1+ prev))
+ else if (and set (eql char ?}))
+ collect (prog1
+ (apply #'string (cdr (nreverse set)))
+ (setq set nil))
+ ;; {set}
+ else if (or (eql char ?{) set)
+ do (push char set)
+ else
+ append (if range-start
+ (prog1
+ (mapcar #'string
+ (number-sequence range-start char))
+ (setq range-start nil))
+ (list (string char)))
+ do (setq prev char))
+ main sub)))))
+
+(defun emoji--add-characters (chars main sub)
+ (let ((subs (if (member sub '( "cat-face" "monkey-face" "skin-tone"
+ "country-flag" "subdivision-flag"
+ "award-medal" "musical-instrument"
+ "book-paper" "other-object"
+ "transport-sign" "av-symbol"
+ "other-symbol"))
+ (list sub)
+ (split-string sub "-")))
+ parent elem)
+ ;; This category is way too big; split it up.
+ (when (equal main "Smileys & People")
+ (setq main
+ (if (member (car subs) '("face" "cat-face" "monkey-face"))
+ "Smileys"
+ (capitalize (car subs))))
+ (when (and (equal (car subs) "person")
+ (= (length subs) 1))
+ (setq subs (list "person" "single")))
+ (when (equal (car subs) "person")
+ (pop subs))
+ (when (and (= (length subs) 1)
+ (not (string-search "-" (car subs))))
+ (setq subs nil)))
+ ;; Useless category.
+ (unless (member main '("Skin-Tone"))
+ (unless (setq parent (assoc main emoji--labels))
+ (setq emoji--labels (append emoji--labels
+ (list (setq parent (list main))))))
+ (setq elem parent)
+ (while subs
+ (unless (setq elem (assoc (car subs) parent))
+ (nconc parent (list (setq elem (list (car subs))))))
+ (pop subs)
+ (setq parent elem))
+ (nconc elem chars))))
+
+(defun emoji--define-transient (&optional alist)
+ (unless alist
+ (setq alist (cons "Emoji" emoji--labels)))
+ (let* ((mname (pop alist))
+ (name (intern (format "emoji-command-%s" mname)))
+ (layout
+ (if (consp (cadr alist))
+ ;; Define sub-maps.
+ (cl-loop for entry in (emoji--compute-prefix alist)
+ collect (list
+ (car entry)
+ (emoji--compute-name (cdr entry))
+ (emoji--define-transient
+ (cons (concat mname " " (cadr entry))
+ (cddr entry)))))
+ ;; Insert an emoji.
+ (cl-loop for char in alist
+ for i from ?a
+ collect (let ((this-char char))
+ (list (string i)
+ char
+ (lambda ()
+ (interactive)
+ (insert this-char)))))))
+ (half (/ (length layout) 2))
+ args)
+ (unless (zerop (mod (length layout) 2))
+ (setq half (1+ half)))
+ (if (nthcdr half layout)
+ (setq args (vector mname
+ (apply #'vector
+ (seq-take layout half))
+ (apply #'vector
+ (nthcdr half layout))))
+ (setq args (vector mname (apply #'vector layout))))
+ ;; There's probably a better way to do this...
+ (setf (symbol-function name)
+ (lambda ()
+ (interactive)
+ (transient-setup name)))
+ (pcase-let ((`(,class ,slots ,suffixes ,docstr ,_body)
+ (transient--expand-define-args (list args))))
+ (put name 'interactive-only t)
+ (put name 'function-documentation docstr)
+ (put name 'transient--prefix
+ (apply (or class 'transient-prefix) :command name
+ slots))
+ (put name 'transient--layout
+ (cl-mapcan (lambda (s) (transient--parse-child name s))
+ suffixes)))
+ name))
+
+(defun emoji--compute-prefix (alist)
+ "Compute characters to use for entries in ALIST.
+We prefer the earliest unique letter."
+ (cl-loop with taken = (make-hash-table)
+ for entry in alist
+ for name = (car entry)
+ collect (cons (cl-loop for char across name
+ while (gethash char taken)
+ finally (progn
+ (setf (gethash char taken) t)
+ (cl-return (string char))))
+ entry)))
+
+(defun emoji--compute-name (entry)
+ "Add example emojis to the name."
+ (let ((name (concat (car entry) " "))
+ (children (emoji--flatten entry)))
+ (cl-loop for i from 0 upto 20
+ while (< (length name) 10)
+ do (cl-loop for child in children
+ for char = (elt child i)
+ while (< (length name) 10)
+ when char
+ do (setq name (concat name char))))
+ (if (= (length name) 20)
+ (concat name "โฆ")
+ name)))
+
+(defun emoji--flatten (alist)
+ (pop alist)
+ (if (consp (cadr alist))
+ (cl-loop for child in alist
+ append (emoji--flatten child))
+ (list alist)))
+
+(provide 'emoji)
+
+;;; emoji.el ends here