Skip to content

Feature: Colon to Emoji Functionality#601

Open
LJSigersmith wants to merge 12 commits intoscribe-org:mainfrom
LJSigersmith:feat/emoji-colon
Open

Feature: Colon to Emoji Functionality#601
LJSigersmith wants to merge 12 commits intoscribe-org:mainfrom
LJSigersmith:feat/emoji-colon

Conversation

@LJSigersmith
Copy link
Copy Markdown

Contributor checklist


Description

Implements emoji colon mode: an emoji suggestion mode triggered by typing : (space + colon) in the keyboard. This allows users to search for emojis by keyword prefix directly from the suggestion bar without interrupting their typing flow.

Typing a space followed by : activates emoji colon mode (emojiColonModeOn flag in GeneralKeyboardIME). While active:

  • The word suggestion bar is replaced by a dedicated emoji row — 6 slots on phones, 9 on tablets — defined in input_method_view.xml.
  • A set of common emojis (😀 ❤️ 👍 😂 🎉 ✨ 🔥 👋 😊) is shown immediately on the bare : before any letters are typed.
  • As the user types, the prefix is matched against the emoji_keywords table using the new findEmojisForPrefix() function, which finds all keywords starting with the typed prefix and collects their associated emojis.
  • If no keywords match, empty slots are displayed rather than falling back to word buttons.
  • Tapping an emoji deletes back to the : that triggered the mode and commits the emoji.
  • Typing a space or deleting the : exits emoji colon mode and restores normal suggestions.
  • Mid-word colons (e.g. in URLs or times) do not trigger the mode — only a colon immediately following a space does.

Files changed

File Change
GeneralKeyboardIME.kt Added emojiColonModeOn state, findEmojisForPrefix(), and colon mode restoration after closing command menus.
KeyHandler.kt Detects the : trigger, toggles colon mode on/off on space or colon deletion, suppresses word suggestion flicker during colon mode, and restores emoji suggestions after mode changes.
SuggestionHandler.kt Strips the leading colon before prefix lookup, shows common emojis on bare :, and shows blank slots on no match.
KeyboardUIManager.kt Renders the 6-slot phone row and 9-slot tablet row during colon mode, hides word buttons and separators, and restores them on exit.
EmojiUtils.kt Added COMMON_EMOJIS constant and colon-mode branch in insertEmoji that deletes back to the triggering : before committing the selected emoji.
input_method_view.xml Added the dedicated phone and tablet colon emoji button rows.

Backend dependencies

Emoji colon mode requires emoji_keywords data to be available in the language pack. Getting this working locally required some work in the Scribe-Data and Scribe-Server repos.

Repo Fix
Scribe-Data PR #684 — fixes the data_to_sqlite.py insertion loop that overflows the emoji_keywords table columns, so the data actually reaches the SQLite output.
Scribe-Server emoji_keywords must be added to DATA_TYPES in update_data.sh, and the underscore must be preserved through generateMariaTableName (currently strips it to emojikeywords). Dependencies for PyICU must also be added.

Emoji colon mode on tablet:
image

Emoji colon mode on phone:
image

Related issue

@github-actions
Copy link
Copy Markdown

Thank you for the pull request! 💙🩵

The Scribe-Android team will do our best to address your contribution as soon as we can. The following are some important points:

  • Those interested in developing their skills and expanding their role in the community should read the mentorship and growth section of the contribution guide
  • If you're not already a member of our public Matrix community, please consider joining!
    • We'd suggest that you use the Element client as well as Element X for a mobile app
    • Join the General and Android rooms once you're in
  • Also consider attending our bi-weekly Saturday developer syncs!
    • Details are shared in the General room on Matrix each Wednesday before the sync
    • It would be great to meet you 😊

Note

Scribe uses Conventional Comments in reviews to make sure that communication is as clear as possible.

@github-actions
Copy link
Copy Markdown

Maintainer Checklist

The following is a checklist for maintainers to make sure this process goes as well as possible. Feel free to address the points below yourself in further commits if you realize that actions are needed :)

  • Tests for changes have been written and the unit test, linting and formatting workflows within the PR checks do not indicate new errors in the files changed

    • Tests may need to be reran as they're at times not deterministic
  • The CHANGELOG has been updated with a description of the changes for the upcoming release and the corresponding issue (if necessary)

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First PR Commit Check

  • The commit messages for the remote branch should be checked to make sure the contributor's email is set up correctly so that they receive credit for their contribution
    • The contributor's name and icon in remote commits should be the same as what appears in the PR
    • If there's a mismatch, the contributor needs to make sure that the email they use for GitHub matches what they have for git config user.email in their local Scribe-Android repo (can be set with git config --global user.email "GITHUB_EMAIL")

@DeleMike
Copy link
Copy Markdown
Collaborator

Hey @LJSigersmith , thanks for the PR! I am currently reviewing and I will drop my initial thoughts.

Copy link
Copy Markdown
Collaborator

@DeleMike DeleMike left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @LJSigersmith, this will raise the keyboard to a new level.🎉✨

I noticed a few things:

  1. The screenshot you posted, the app currently does not behave in the same manner. I tried to do ":Heart" but all the emoji suggestion bars were empty. I'm guessing you reverted

  2. I did not need to type "space + colon", once I typed in "colon(:)", the emoji bar showed up. I am not sure if this is an issue.

  3. Can you explain how this file will help in the process of fetching all emojis and using them effectively in the app, please?

  4. You write this "If no keywords match, empty slots are displayed rather than falling back to word buttons.", I believe we can show the user a default set of emojis.

  5. I also believe this PR will be partially blocked as we do not have this data coming from Scribe-Server. What do you think @andrewtavis ?

Please also review @angrezichatterbox, thanks.

@LJSigersmith
Copy link
Copy Markdown
Author

Thanks for the feedback @DeleMike,

  1. I think this could be because the emoji_keywords table is not currently in the downloaded language packs so the query fails when looking up suggestions. I've attached the sqlite file I have on my emulator at /data/data/be.scri.keyboards.debug/databases/ENLanguageData.sqlite if that would help verify that this is the cause of not seeing emojis. When I replace this with the language pack currently provided by Scribe-Server, I observe the behavior you're describing.

  2. If this happened when you only typed : in the start of a text field, this is expected. Space + colon is only required between words to prevent triggering it in the middle of a word.

  3. The changes in EmojiUtils.kt add a list of common emojis and ensure the text, up to and including the colon, that triggered the emoji suggestions are deleted when an emoji suggestion is selected and inserted. The common emojis are used when the user first types the colon to suggest common emojis before any actual letters are typed. This provides common emojis quickly and also indicates emoji suggestions are on.

  4. I can certainly change this behavior to show common emojis in the case of no matches.

  5. I did have to implement a couple patches on my clones of Scribe-Server and Scribe-Data to produce the emoji_keywords table in the downloaded language packs. Happy to detail this process if that helps move this forward.

@DeleMike
Copy link
Copy Markdown
Collaborator

Thanks for the response @LJSigersmith.

Yeah, detailing the process of how you used Scribe-Data and Scribe-Server to achieve it is important. We want to see how it connects into the app.

I understand that Scribe-Server does not support emoji_keywords for now, and that is not a problem. I just did not see how your current PR reads the database to give suggestions.

I'm thinking, especially with the EmojiUtils.kt file, I just see that you declare val COMMON_EMOJIS = listOf("😀", "❤️", "👍", "😂", "🎉", "✨", "🔥", "👋", "😊") which is fine for testing but we would love to see how it reads via the SQLite file.

cc: @andrewtavis @angrezichatterbox

@LJSigersmith
Copy link
Copy Markdown
Author

Hi @DeleMike,

The COMMON_EMOJIS list is only shown before the user starts typing after :. It felt like a helpful way to indicate that emoji suggestions are active without querying the emoji_keywords table when there's no keyword to search for yet.

Once the user starts typing after the :, the flow is:

KeyHandler.handleKeyPressSuggestionHandler.processEmojiSuggestionsGeneralKeyboardIME.findEmojisForPrefix with emojiKeywords: HashMap

emojiKeywords is populated at language load time by EmojiDataManager.getEmojiKeywords, which reads directly from the SQLite file:

db.use {
    if (!it.tableExists("emoji_keywords")) return emojiMap

    it.rawQuery("SELECT MAX(LENGTH(word)) FROM emoji_keywords", null).use { cursor ->
        if (cursor.moveToFirst()) {
            maxKeywordLength = cursor.getInt(0)
        }
    }
    it.rawQuery("SELECT * FROM emoji_keywords", null).use { cursor ->
        processEmojiCursor(cursor, emojiMap)
    }
}

So the SQLite read happens at load, and findEmojisForPrefix then does a prefix match against that map as the user types.

@LJSigersmith
Copy link
Copy Markdown
Author

LJSigersmith commented Apr 23, 2026

Here is what I changed to get this working end-to-end:


Scribe-Data

There is a bug in src/scribe_data/data_to_sqlite.py that prevents emoji_keywords from being written to SQLite. The insertion loop overflows the number of columns in the table. I have a fix for this in Scribe-Data PR #684. PyICU is also a required dependency.

brew install icu4c
export PATH="$(brew --prefix icu4c)/bin:$PATH"
export PKG_CONFIG_PATH="$(brew --prefix icu4c)/lib/pkgconfig"
pip install PyICU
scribe-data get -l English -dt nouns verbs emoji_keywords
scribe-data convert -lang English -dt emoji_keywords nouns verbs -ot sqlite

produced the emoji_keywords table in the SQLite file.


Scribe-Server

A couple changes were needed to update_data.sh:
emoji_keywords was not in DATA_TYPES.

DATA_TYPES=("nouns" "verbs" "emoji_keywords")

PyICU dependencies were needed.

sudo apt-get install -y libicu-dev pkg-config g++ python3-dev
pip install PyICU 

At some point, the underscore is also stripped from emoji_keywords and the Android app expects the underscore. I haven't dug into this, I just renamed the table manually in the sqlite file.

And then moved the file from Scribe-Data to Scribe-Server

mv Scribe-Data/scribe_data_sqlite_export/ENLanguageData.sqlite Scribe-Server/packs/sqlite/ENLanguageData.sqlite

Scribe-Android

I ran the app on the emulator and downloaded the language pack from the local server by changing BASE_URL in RetrofitClient.kt and allowing cleartext HTTP in AndroidManifest.xml. With emoji_keywords now present in the downloaded SQLite file, emoji colon mode works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add colon (:) to emoji functionality to the Android keyboard app

2 participants