initial commit

This commit is contained in:
Marty Oehme 2021-12-01 15:51:37 +01:00
commit b1361617e7
Signed by: Marty
GPG key ID: B7538B8F50A1C800
7 changed files with 468 additions and 0 deletions

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Marty Oehme
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

233
README.md Normal file
View file

@ -0,0 +1,233 @@
# bemoji ❤ - Quickly ⛏ your 🌟
Emoji picker with support for bemenu/wofi/rofi/dmenu and wayland/X11.
Will remember your favorite emojis and give you quick access.
![bemoji picker interface on bemenu](assets/bemenu.png)
## 📁 Installation
Option 1. Clone the repository and put the executable somewhere in your path:
```bash
git clone <INSERT-REPOSITORY>
chmod +x bemoji/bemoji
mv bemoji/bemoji /usr/local/bin/bemoji
rm -r bemoji
```
Option 2. Clone the repository and link the executable to your path:
```bash
git clone <INSERT-REPOSITORY>
chmod +x bemoji/bemoji
ln -s bemoji/bemoji /usr/local/bin/bemoji
```
Dependencies:
* One of `bemenu`, `wofi`, `rofi`, `dmenu`, or supplying your own picker.
* One of `wl-copy`, `xclip`, `xsel` or supplying your own clipboard tool.
* One of `wtype`, `xdotool` or supplying your own typing tool.
* `sed`, `grep`, `cut`, `sort`, `uniq`, `tr`, `curl` if using the download functionality.
To see how to substitute the default choices with your own tools,
see Options below.
![wofi picker interface](assets/wofi.png)
## 💿 Usage
![bemoji help window](assets/help.png)
Simply execute `bemoji` without any options to set up the default emoji database and let you quickly pick an emoji.
It will be copied to your clipboard for you to paste anywhere.
If you execute `bemoji -t` it will directly type your emoji directly into whatever application is in focus.
When the emoji list is open you can always press `Alt+1` to send the selected emoji to clipboard and `Alt+2` to type the selected emoji,
regardless of what the default action is set to.[^always]
[^always]: This functionality currently only works in bemenu and rofi.
You can also map the picker to a key combination, e.g.
In `swaywm`, put the following in `~/.config/sway/config`:
```
bindsym Mod4+Shift+e exec bemoji -t
```
For `i3`, put the same into `~/.config/i3/config`:
```
bindsym Mod4+Shift+e exec bemoji -t
```
For `riverwm`, put the following in `~/.config/river/init`:
```
riverctl map normal $mod+Shift E spawn "bemoji -t"
```
In `sxhkd`, put the following into `~/.config/sxhkd/sxhkdrc`:
```
super + Shift + e
bemoji -t
```
And you can easily type any emoji with the help of `Super+Shift+E`.
![rofi picker interface](assets/rofi.png)
## 🧰 Options
bemoji comes with a couple of options to specify actions, emoji libraries and directories being used.
### Adding your own emoji
Simply put your own emoji list into the bemoji data directory.
By default, the directory will be at your `$XDG_DATA_HOME/bemoji` location -
most likely this is `~/.local/share/bemoji`.
Add any number of `.txt` files containing additional emoji to this directory:
```
🫦 Biting lip
🫶 Heart Hands
```
The lists *need* to have the format `🙂 description of emoji` with a whitespace separating the emoji and its description.
The description can have as many words and whitespaces as you want.
### Ignoring the most recent emoji
By default, bemoji will sort the list it displays by your most frequently and most recently used emoji.
To disable this behavior, execute bemoji like the following:
```bash
bemoji -P
```
This will stop bemoji from re-ordering your emoji lists before displaying them.
You can also stop bemoji from adding any emoji to your history in the first place:
```bash
bemoji -p
```
This will not add any of the emoji you pick to your recent emojis.
Put both together to completely ignore the recent emoji feature of the program:
```bash
bemoji -Pp
```
Like this, you'll be hiding any recent personal emoji and no one will know that you always type 👄🍆💦.
The recent list will also contain emoji that are *not* usually on your lists,
so kept in single-use lists for example.
If you don't wish those to show up, make use of these options.
### Setting custom directories
By default bemoji stores your recent history in `$XDG_CACHE_HOME/bemoji-history.txt`,
so most often in `~/.cache/bemoji-history.txt`
You can overwrite the directories bemoji uses for its emoji lists and history files with the following two environment variables:
```
BEMOJI_DB_LOCATION=/path/to/my/emoji/directory
BEMOJI_CACHE_LOCATION=/path/to/my/cache/directory
```
There are no equivalent commandline arguments to overwrite these two settings.
### Display one custom emoji list
A custom emoji list can be supplied as commandline argument `-f` or `BEMOJI_CUSTOM_LIST` environment variable.
```bash
bemoji -f path/to/my/list.txt
```
The list will override the normally presented emoji,
so that only the custom list and recent emoji will be displayed.
To display *only* the emoji list passed in, pass an extra `-P` flag to bemoji.
The path can also be a weblink which bemoji will download and use:
```
bemoji -f "https://raw.githubusercontent.com/jchook/emoji-menu/master/data/emojis.txt"
```
### Change the default emoji set
bemoji downloads emoji for you to use on first invocation.
By default, it only downloads emoji, though you can have it download math symbols as well.
To change this setting, execute bemoji like the following:
```bash
bemoji -D all
```
This will download *all* default sets bemoji knows - which is currently the default emoji list and a long list of math symbols.
Other valid options for this setting are `emoji`, `math`, `none`.
If set to `none` and no files are in the emoji directory,
bemoji will simply complain and not show anything.
### Using a custom tool for picking, clipping, typing
If you want to replace one of the default supported tools with your own you can do this through environment variables:
```bash
BEMOJI_PICKER_CMD="path/to/your/picker-tool"
BEMOJI_CLIP_CMD="path/to/your/clipboard/tool"
BEMOJI_TYPE_CMD="path/to/your/xdotool"
```
This is pretty experimental and you'll have to see how well it works for you.
The setting can not be changed through the commandline alone.
### Execute a custom command with my emoji
You can execute bemoji with the `-e` flag with which you tell it not to do anything but echo out the chosen emoji.
This can be very useful for creating your own little script with it:
```bash
bemoji -e | cat <(echo -n "https://emojipedia.org/") - | xargs xdg-open
```
This snippet will open a wiki page for the picked emoji in your browser.
Of course, there are many more possibilities.
This is just an example to show how the echo mode works.
### A list of all environment variables
What follows is a list of all environment variables bemoji understands,
with their default settings
```bash
BEMOJI_DB_LOCATION=$XDG_DATA_HOME/bemoji # where the emoji lists reside
BEMOJI_CACHE_LOCATION=$XDG_CACHE_HOME # where the cache file resides
BEMOJI_CUSTOM_LIST="" # the custom emoji list to display
BEMOJI_DOWNLOAD_LIST="" # the default emoji lists to download to database
BEMOJI_DEFAULT_COMMAND=<clip-tool> # which command to invoke by default
BEMOJI_PICKER_CMD=bemenu # which picker tool to use
BEMOJI_CLIP_CMD=wl-copy # which clipboard tool to use
BEMOJI_TYPE_CMD=wtype # which typing tool to use (ydotool will NOT work)
BEMOJI_PRIVATE_MODE=false # whether to save new entries
BEMOJI_IGNORE_RECENT=false # whether to display recent entries
```
## Issues
Thanks for checking this program out! ❤
If there are any problems, don't hesitate to open an issue.
If you have an idea or improvement, don't hesitate to open a merge request!

BIN
assets/bemenu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
assets/help.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
assets/rofi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
assets/wofi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

214
bemoji Executable file
View file

@ -0,0 +1,214 @@
#!/usr/bin/env sh
# Wanted features:
#
# - [ ] limit maximum number of recent emoji
# Emoji default database location
bm_db_location=${BEMOJI_DB_LOCATION:-"${XDG_DATA_HOME:-$HOME/.local/share}/bemoji"}
# Setting custom emoji list file location:
# BEMOJI_CUSTOM_LIST=/my/location/emojis.txt
# Setting custom recent emoji cache:
# BEMOJI_CACHE_LOCATION=/path/to/my/recents/directory
bm_cache_dir="${BEMOJI_CACHE_LOCATION:-${XDG_CACHE_HOME:-$HOME/.cache}}"
bm_history_file="${bm_cache_dir}/bemoji-history.txt"
# Command to run after user chooses an emoji
bm_default_cmd=${BEMOJI_DEFAULT_CMD:-'_clipResult'}
# Do not save choices
bm_private_mode=${BEMOJI_PRIVATE_MODE:-false}
# Do not sort results
bm_ignore_recent=${BEMOJI_IGNORE_RECENT:-false}
# Report usage
usage() {
echo "Usage: $(basename "$0") [-t | -c | -e] [-f <filepath> ] [-p] [-P] [-D all|none|emoji]" 1>&2
echo
echo "A simple emoji picker. Runs on bemenu/wofi/rofi/dmenu by default."
echo "Invoked without arguments sends the picked emoji to the clipboard."
echo
echo " -f <filepath> Use a custom emoji database. Can be a url which will be retrieved."
echo " -t Simulate typing the emoji choice with the keyboard."
echo " -c Send emoji choice to the clipboard. (default)"
echo " -p Do not save picked emoji to recent history."
echo " -P Do not order emoji by recently used."
echo " -e Only echo out the picked emoji."
echo " -D <choice> Choose specific default lists to download if none found locally."
echo
exit "$1"
}
# Get Options
while getopts ":f:D:tcepPh" o; do
case "${o}" in
f) BEMOJI_CUSTOM_LIST="${OPTARG}" ;;
t) bm_default_cmd=_typeResult ;;
c) bm_default_cmd=_clipResult ;;
e) bm_default_cmd=_echo ;;
D) BEMOJI_DOWNLOAD_LIST="${OPTARG}" ;;
p) bm_private_mode=true ;;
P) bm_ignore_recent=true ;;
h) usage 0 ;;
*) usage 1 ;;
esac
done
prepare_db() {
# Create list directory
if [ ! -d "$bm_db_location" ]; then
mkdir -p "$bm_db_location"
fi
if [ -n "$(find "$bm_db_location" -maxdepth 0 -type d -empty 2>/dev/null)" ]; then
# Populate default lists
if echo "$BEMOJI_DOWNLOAD_LIST" | grep -q -e 'none'; then
printf "No emoji list found, but set to not download any default lists."
exit 1
elif echo "$BEMOJI_DOWNLOAD_LIST" | grep -q -e 'all'; then
dl_default_emoji
dl_math_symbols
return
fi
if [ -z "$BEMOJI_DOWNLOAD_LIST" ] || echo "$BEMOJI_DOWNLOAD_LIST" | grep -q -e 'emoji'; then
dl_default_emoji
fi
if echo "$BEMOJI_DOWNLOAD_LIST" | grep -q -e 'math'; then
dl_math_symbols
fi
fi
}
dl_default_emoji() {
curl -sSL "https://unicode.org/Public/emoji/14.0/emoji-test.txt" |
sed -ne 's/^.*; fully-qualified.*# \(\S*\) \S* \(.*$\)/\1 \2/gp' >"$bm_db_location/emojis.txt"
printf "Downloaded default emoji set."
}
dl_math_symbols() {
curl -sSL "https://unicode.org/Public/math/latest/MathClassEx-15.txt" |
grep -ve '^#' | cut -d';' -f3,7 --output-delimiter=' ' >"$bm_db_location/math.txt"
printf "Downloaded math symbols set."
}
gather_emojis() {
if [ -n "$BEMOJI_CUSTOM_LIST" ] && [ -f "$BEMOJI_CUSTOM_LIST" ]; then
result=$(cat "$BEMOJI_CUSTOM_LIST")
elif [ -n "$BEMOJI_CUSTOM_LIST" ] && curl -fsSI "$BEMOJI_CUSTOM_LIST" >/dev/null 2>&1; then
result=$(curl -sSL "$BEMOJI_CUSTOM_LIST")
else
result=$(cat "$bm_db_location"/*.txt)
fi
if [ "$bm_ignore_recent" = true ]; then
printf "%s" "$result"
else
printf "%s\n%s" "$(get_most_recent)" "$result" | cat -n - | sort -uk2 | sort -n | cut -f2-
fi
}
get_most_recent() {
recent_file="$bm_history_file"
if [ ! -f "$recent_file" ]; then
touch "$recent_file"
fi
# TODO improve this messy line
cat "$recent_file" |
sed -e '/^$/d' |
sort |
uniq -c |
sort -rn |
sed -e 's/^\s*//' |
cut -d' ' -f2-
}
add_to_recent() {
if [ -z "$1" ]; then return; fi
if [ ! -d "$bm_cache_dir" ]; then
mkdir -p "$bm_cache_dir"
fi
echo "$1" >>"$bm_history_file"
}
# Set default clipboard util
_clipper() {
if [ -n "$BEMOJI_CLIP_CMD" ]; then
"${BEMOJI_CLIP_CMD[@]}"
elif [ -n "$WAYLAND_DISPLAY" ] && command -v wl-copy >/dev/null 2>&1; then
wl-copy
elif [ -n "$DISPLAY" ] && command -v xclip >/dev/null 2>&1; then
xclip -selection clipboard
elif [ -n "$DISPLAY" ] && command -v xsel >/dev/null 2>&1; then
xsel -b
else
printf "No suitable clipboard tool found."
exit 1
fi
}
# Set default typing uti
_typer() {
totype=$(cat -)
if [ -n "$BEMOJI_TYPE_CMD" ]; then
"${BEMOJI_TYPE_CMD[@]}"
elif [ -n "$WAYLAND_DISPLAY" ] && command -v wtype >/dev/null 2>&1; then
wtype -s 30 "$totype"
elif [ -n "$DISPLAY" ] && command -v xdotool >/dev/null 2>&1; then
xdotool type "$totype" --delay 30
else
printf "No suitable typing tool found."
exit 1
fi
}
# Set default picker util
_picker() {
if [ -n "$BEMOJI_PICKER_CMD" ]; then
"${BEMOJI_PICKER_CMD[@]}"
elif command -v bemenu >/dev/null 2>&1; then
bemenu -p 🔍 -i -l 20
elif command -v wofi >/dev/null 2>&1; then
wofi -p 🔍 -i --show dmenu
elif command -v rofi >/dev/null 2>&1; then
rofi -p 🔍 -dmenu --kb-custom-1 "Alt+1" --kb-custom-2 "Alt+2"
elif command -v dmenu >/dev/null 2>&1; then
dmenu -p 🔍 -i -l 20
else
printf "No suitable picker tool found."
exit 1
fi
}
# Type result using xdotool
_typeResult() {
cat - | _typer
}
_clipResult() {
cat - | _clipper
}
[ -n "$BEMOJI_CUSTOM_LIST" ] || prepare_db
result=$(gather_emojis | _picker)
exit_value="$?"
[ "$bm_private_mode" = true ] || add_to_recent "$result"
result=$(echo "$result" | grep -oP '^[^\s]+' | tr -d '\n')
case "$exit_value" in
1)
exit
;;
0)
if [ "$bm_default_cmd" = "_echo" ]; then
echo "$result"
exit
fi
echo "$result" | "$bm_default_cmd"
;;
10)
echo "$result" | _clipResult
;;
11)
echo "$result" | _typeResult
;;
esac
exit