Browse Source

Add alternative ways to insert emoji

First, the classical typing, our companion since v1.0
Secondly, the new "Copy to clipbard, paste and then restore the
clipoard" to work around Firefox's problems. However, as `Ctrl+v` does
not work with a console (and thus Vim), I changed it to use
`Shift+Insert`. Unfortunately, this copies from both clipboard and
primary depending on the application. To work around this (yay,
recursive workarounds), we just spam both with our emoji and restore
them later. What could go wrong?

Also, we now allow choosing a method using cli args or different
keybindings (`Alt+p` for copypasting, `Alt+t` for typing).
tags/3.0.0
Fabian Winter 4 months ago
parent
commit
4a33d2ba68
3 changed files with 122 additions and 46 deletions
  1. 4
    0
      CHANGELOG.md
  2. 8
    4
      README.md
  3. 110
    42
      rofimoji.py

+ 4
- 0
CHANGELOG.md View File

@@ -1,3 +1,7 @@
# [3.0.0]
## Added
- You can choose a new input method: `rofimoji` can copy your emojis, paste them into the application and restore the previous contents.

# [2.1.0]
## Changed
- This release is based on the emoji v12, including all these: https://unicode.org/emoji/charts/emoji-versions.html#2019

+ 8
- 4
README.md View File

@@ -8,21 +8,25 @@ Inserts the selected emoji directly, or copies it to the clipboard.
2. Search for the emoji you want
3. (optional) Select multiple emoji with `shift+enter`
4. Hit `enter` to insert the emoji directly \
Hit `alt+c` to copy it to the clipboard
Hit `alt+c` to copy it to the clipboard \
`alt+t` or `alt+p` can be used to select a specific input method
5. Maybe select a skin color
6. 🎠

## How does it look?
![Screenshot of rofimoji](screenshot.png?raw=true)

## Insertion method
For some applications, `xdotool` cannot type emojis (f.e. Firefox). To work around this, `rofimoji` can copy the emojis to your clipboard and insert them from there with `shift+insert`. Afterwards, it will restore the previous contents.
Unfortunately, it depends on the receiving application whether `shift+insert` uses the clipboard or the primary selection. Therefore, `rofimoji` uses both and also restores both 😐.

By default, `rofimoji` uses `xdotool type`. To choose to spam your clipboards, you can either use the keybinding `alt+p` or start it as `rofimoji --use-clipboard`. If you want to use typing, you can hit `alt+t`, even though it was started with `--use-clipboard`.

## Installation

### Arch
A kind soul has packaged it as [rofimoji](https://www.archlinux.org/packages/community/any/rofimoji/). To, install, use `sudo pacman -Syu rofimoji`.

#### AUR for Manjaro and others
If `rofimoji` is not yet synced to your distro's repo, you can also install [rofimoji-git](https://aur.archlinux.org/packages/rofimoji-git/) from the AUR.

### From sources
Download `rofimoji.py` and move it somewhere on your path, for example `/usr/local/bin`.


+ 110
- 42
rofimoji.py View File

@@ -1,9 +1,9 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import argparse
from subprocess import Popen, PIPE

emojis = """😀 grinning face
emoji_list = """😀 grinning face
😃 grinning face with big eyes
😄 grinning face with smiling eyes
😁 beaming face with smiling eyes
@@ -1746,6 +1746,13 @@ fitzpatrick_modifiers = {
}


def insert_emojis(emojis: str, active_window: str, use_clipboard: bool = False):
if use_clipboard:
copy_paste_emojis(emojis, active_window)
else:
type_emojis(emojis, active_window)


def select_skin_tone(selected_emoji: chr):
modified_emojis = '\n'.join(map(
lambda modifier: selected_emoji + modifier + " " + fitzpatrick_modifiers[modifier],
@@ -1774,30 +1781,72 @@ def select_skin_tone(selected_emoji: chr):

return stdout_skin.split()[0].decode('utf-8')

xdotool = Popen(args=['xdotool', 'getactivewindow'], stdout=PIPE)
active_window = xdotool.communicate()[0].decode("utf-8")[:-1]

rofi = Popen(
args=[
'rofi',
'-dmenu',
'-i',
'-multi-select',
'-p',
' 😀 ',
'-kb-custom-1',
'Alt+c'
],
stdin=PIPE,
stdout=PIPE
)
(stdout, stderr) = rofi.communicate(input=emojis.encode('utf-8'))
def type_emojis(emojis: str, active_window: str):
Popen(
args=[
'xdotool',
'type',
'--clearmodifiers',
'--window',
active_window,
emojis
]
)


def copy_paste_emojis(emojis: str, active_window: str):
xsel = Popen(args=['xsel', '-o', '-b'], stdout=PIPE)
old_clipboard_content = xsel.communicate()[0].decode("utf-8")
xsel = Popen(args=['xsel', '-o', '-p'], stdout=PIPE)
old_primary_content = xsel.communicate()[0].decode("utf-8")

xsel = Popen(args=['xsel', '-i', '-b'], stdin=PIPE)
xsel.communicate(input=emojis.encode('utf-8'))
xsel = Popen(args=['xsel', '-i', '-p'], stdin=PIPE)
xsel.communicate(input=emojis.encode('utf-8'))

Popen(args=['xdotool', 'key', '--clearmodifiers', '--window', active_window,
'Shift+Insert']).wait()

xsel = Popen(args=['xsel', '-i', '-b'], stdin=PIPE)
xsel.communicate(input=old_clipboard_content.encode('utf-8'))
xsel = Popen(args=['xsel', '-i', '-p'], stdin=PIPE)
xsel.communicate(input=old_primary_content.encode('utf-8'))


def copy_emojis_to_clipboard(emojis: str):
xsel = Popen(
args=[
'xsel',
'-i',
'-b'
],
stdin=PIPE
)
xsel.communicate(input=emojis.encode('utf-8'))


def parse_arguments() -> argparse.Namespace:
parser = argparse.ArgumentParser(description='Select, insert or copy Unicode emoji')
parser.add_argument(
'--use-clipboard',
'-c',
dest='use_clipboard',
action='store_true',
help='Do not type the emoji directly, but copy it to the clipboard, insert it from there and then restore the clipboard\'s original value'
)
return parser.parse_args()


def get_active_window() -> str:
xdotool = Popen(args=['xdotool', 'getactivewindow'], stdout=PIPE)
return xdotool.communicate()[0].decode("utf-8")[:-1]

if rofi.returncode == 1:
exit()
else:

def compile_chosen_emojis(chosen_emojis) -> str:
emojis = ""
for line in stdout.splitlines():
for line in chosen_emojis:
emoji = line.split()[0].decode('utf-8')

if emoji in skin_tone_selectable_emojis:
@@ -1805,25 +1854,44 @@ else:

emojis += emoji

if rofi.returncode == 0:
# HACK: using clipboard and Control+v to insert emojis in Firefox and Telegram
xsel = Popen(args=['xsel', '-ob'], stdout=PIPE)
clipboard = xsel.communicate()[0].decode("utf-8")
return emojis


xsel = Popen(args=['xsel', '-ib'], stdin=PIPE)
xsel.communicate(input=emojis.encode('utf-8'))
if __name__ == "__main__":
args = parse_arguments()

active_window = get_active_window()

rofi = Popen(
args=[
'rofi',
'-dmenu',
'-i',
'-multi-select',
'-p',
' 😀 ',
'-kb-custom-1',
'Alt+c',
'-kb-custom-2',
'Alt+t',
'-kb-custom-3',
'Alt+p'
],
stdin=PIPE,
stdout=PIPE
)
(stdout, stderr) = rofi.communicate(input=emoji_list.encode('utf-8'))

Popen(args=['xdotool', 'key', '--clearmodifiers', '--window', active_window, 'Control+v']).wait()
if rofi.returncode == 1:
exit()
else:
emojis = compile_chosen_emojis(stdout.splitlines(), args.skincolor[0])

xsel = Popen(args=['xsel', '-ib'], stdin=PIPE)
xsel.communicate(input=clipboard.encode('utf-8'))
elif rofi.returncode == 10:
xsel = Popen(
args=[
'xsel',
'-i',
'-b'
],
stdin=PIPE
)
xsel.communicate(input=emojis.encode('utf-8'))
if rofi.returncode == 0:
insert_emojis(emojis, active_window, args.use_clipboard)
elif rofi.returncode == 10:
copy_emojis_to_clipboard(emojis)
elif rofi.returncode == 11:
type_emojis(emojis, active_window)
elif rofi.returncode == 12:
copy_paste_emojis(emojis, active_window)

Loading…
Cancel
Save