Compare commits

..

3 commits

Author SHA1 Message Date
31dea58782
! Rename XDG_CACHE_LOCATION to XDG_HISTORY_LOCATION
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Gives closer adherence to actual content for the environment variable.
2022-11-03 15:23:39 +01:00
525a379564
📖 Update README for new state directory
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2022-10-12 17:04:53 +02:00
250fb36146
! Use new XDG Base specification for state
Switched the history from using the XDG_CACHE_HOME directory by default
to use XDG_STATE_HOME by default.

This makes sense since cache can (and should be prepared to) be wiped at
any moment and the program functionality should not be hindered by this.

Since we need to retain history through such wipes the newly introduced
state directory is the perfect match for keeping the history file in.

This does constitute a small breaking change for existing histories
which need to be moved to the new directory if they made use of the old
cache directory.

Fixes #5.
2022-10-12 16:59:53 +02:00
12 changed files with 121 additions and 536 deletions

3
.gitmodules vendored
View file

@ -7,6 +7,3 @@
[submodule "test/test_helper/bats-assert"] [submodule "test/test_helper/bats-assert"]
path = test/test_helper/bats-assert path = test/test_helper/bats-assert
url = https://github.com/bats-core/bats-assert.git url = https://github.com/bats-core/bats-assert.git
[submodule "test/test_helper/mocks"]
path = test/test_helper/mocks
url = https://github.com/jasonkarns/bats-mock.git

View file

@ -1,80 +1,5 @@
steps: pipeline:
test: test:
image: bats/bats image: bats/bats
commands: commands:
- /opt/bats/bin/bats test - /opt/bats/bin/bats test
release-prep:
# prepare changelog and version information for release candidate
when:
event: tag
ref: refs/tags/v*
image: alpine
commands:
- sed -ne 's/bm_version=\(.*\)/\1/p' bemoji > NEWEST_VERSION.txt
- awk '/^## \[\d/{p++} p==2{print; exit} p>=1' CHANGELOG.md | head -n -1 | tail -n+3 > NEWEST_CHANGES.txt
versioncompare:
# ensure we correctly bumped versions
when:
event: tag
ref: refs/tags/v*
image: alpine
secrets: [ github_release_token, github_repo ]
commands:
- apk add jq curl
- "lastversion=$(curl -X GET -H \"Accept: application/vnd.github.v3+json\" -H \"Authorization: Bearer $GITHUB_RELEASE_TOKEN\" https://api.github.com/repos/$GITHUB_REPO/releases/latest | jq -r '.name')"
- "programversion=$(cat NEWEST_VERSION.txt)"
- changelogversion=$(sed -ne 's/^## \[\([0-9].*\)\].*$/\1/p' CHANGELOG.md | head -n1)
- echo "Last version - $lastversion"
- echo "New version - $programversion"
- echo "Changelog version - $changelogversion"
- "if [ \"$changelogversion\" != \"$programversion\" ]; then { echo \"VERSION MISMATCH: Changelog - $changelogversion, Program - $programversion\" && exit 1; }; fi"
- "if [ \"$lastversion\" = \"$programversion\" ]; then { echo \"RELEASE DUPLICATE: Last release already had version - $programversion\" && exit 1; }; fi"
build:
when:
event: tag
ref: refs/tags/v*
image: savant/md2man
commands:
- apk update && apk add zip
- BM_VERSION=$(cat NEWEST_VERSION.txt)
- mkdir -p build/doc dist
- cp bemoji build
- md2man -in README.md -out bemoji.1 && gzip bemoji.1
- cp LICENSE README.md bemoji.1.gz build/doc
- cd build || exit 1
- tar -czvf bemoji-$BM_VERSION.tar.gz *
- zip -r bemoji-$BM_VERSION.zip *
- mv bemoji-$BM_VERSION.tar.gz bemoji-$BM_VERSION.zip ../dist
release-gitea:
when:
event: tag
ref: refs/tags/v*
image: plugins/gitea-release
settings:
api_key:
from_secret: gitea_release_token
base_url: https://git.martyoeh.me
files: dist/*
title: NEWEST_VERSION.txt
note: NEWEST_CHANGES.txt
release-github:
when:
event: tag
ref: refs/tags/v*
image: alpine
secrets: [ github_release_token, github_repo ]
commands:
- apk add file jq curl
- BM_VERSION=$(cat NEWEST_VERSION.txt)
- BM_CHANGED=$(sed -e 's|#||g' -e 's|^.*$|\0 <br />|' NEWEST_CHANGES.txt) # display newlines workaround
- echo "{\"tag_name\":\"v${BM_VERSION}\",\"target_commitish\":\"main\",\"name\":\"v${BM_VERSION}\",\"body\":\"$BM_CHANGED\",\"draft\":false,\"prerelease\":false,\"generate_release_notes\":false}" > data.json
- "response=$(curl -X POST -H \"Accept:\\ application/vnd.github+json\" -H \"Authorization:\\ Bearer $GITHUB_RELEASE_TOKEN\" https://api.github.com/repos/$GITHUB_REPO/releases -d \"@data.json\")"
- "uploadurl=$(echo $response | jq -r '.upload_url' | cut -d'{' -f1)"
- "[ $uploadurl = null ] && { echo $response; exit 1; }"
- "curl -X POST -H \"Accept:\\ application/vnd.github.v3+json\" -H \"Authorization:\\ Bearer $GITHUB_RELEASE_TOKEN\" -H \"Content-Type:\\ $(file -b --mime-type dist/bemoji-$BM_VERSION.zip)\" -H \"Content-Length:\\ $(wc -c <dist/bemoji-$BM_VERSION.zip | xargs)\" -T dist/bemoji-$BM_VERSION.zip \"$uploadurl?name=bemoji-$BM_VERSION.zip\""
- "curl -X POST -H \"Accept:\\ application/vnd.github.v3+json\" -H \"Authorization:\\ Bearer $GITHUB_RELEASE_TOKEN\" -H \"Content-Type:\\ $(file -b --mime-type dist/bemoji-$BM_VERSION.tar.gz)\" -H \"Content-Length:\\ $(wc -c <dist/bemoji-$BM_VERSION.tar.gz | xargs)\" -T dist/bemoji-$BM_VERSION.tar.gz \"$uploadurl?name=bemoji-$BM_VERSION.tar.gz\""

View file

@ -7,51 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
<!-- ### Added -->
<!-- ### Changed -->
<!-- ### Deprecated -->
<!-- ### Removed -->
<!-- ### Fixed -->
<!-- ### Security -->
## [0.4.0] - 2024-02-22
### Added
- Add default support for `fuzzel` wayland-native picker tool
- Add default support for `ilia` gtk-based picker tool, used by default in Regolith Linux
- Pass through return code 1 from selection tool
- (!) Number of displayed recent emoji can be set with `-P` option:
This replaces previous `-P` history flag toggle. Use number to set amount of recent
entries to display, `-P3`. To completely hide history use `-P0`.
- Add nerdfont emoji set download with `-D nerd`
- Add parsing for long-form options (`--private` instead of `-p` and so on):
Options requiring a value can be given both in space-separated (`--hist-limit 2`)
and equals-separated (`--hist-limit=2`) versions. POSIX option concatenation still
works (`-ne` to echo without newline).
### Changed
- (!) History uses `XDG_STATE_HOME` directory by default:
This constitutes a break in behavior if you relied a lot on your pick history in the default
location. To retain your old history file, simply move it from the old cache directory
(`~/.cache/bemoji-history.txt` by default) to the new one (`~/.local/state/bemoji-history.txt`
by default).
- (!) `XDG_CACHE_LOCATION` renamed to `XDG_HISTORY_LOCATION` to better signify its purpose
### Fixed
- Always download from newest emoji list url
- Pass selection to custom typing tools through stdin
- Pass info messages to stderr to avoid passing to picker tools
## [0.3.0] - 2022-11-10
### Added ### Added
- Add new option `-n` which suppresses printing the final newline character in output - Add new option `-n` which suppresses printing the final newline character in output
@ -59,13 +14,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- Multiple command options can be combined - Multiple command options can be combined
- Allow downloading emoji sets at any time after initial run with `-D <choice>` - (!) History uses `XDG_STATE_HOME` directory by default:
This constitutes a break in behavior if you relied a lot on your pick history in the default
location. To retain your old history file, simply move it from the old cache directory
(`~/.cache/bemoji-history.txt` by default) to the new one (`~/.local/state/bemoji-history.txt`
by default).
- (!) `XDG_CACHE_LOCATION` renamed to `XDG_HISTORY_LOCATION` to better signify its purpose
<!-- ### Deprecated -->
<!-- ### Removed -->
### Fixed ### Fixed
- Custom default command is only executed when no command option given - Custom default command is only executed when no command option given
- Results are matched case insensitively when using rofi picker to match other pickers - Results are matched case insensitively when using rofi picker to match other pickers
<!-- ### Security -->
## [0.2.0] - 2022-06-29 ## [0.2.0] - 2022-06-29
### Added ### Added

View file

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2021 - 2024 Marty Oehme Copyright (c) 2022 Marty Oehme
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -12,7 +12,7 @@ Will remember your favorite emojis and give you quick access.
### Dependencies ### Dependencies
* One of `bemenu`, `wofi`, `rofi`, `dmenu`, `ilia`, `fuzzel` or supplying your own picker. * 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 `wl-copy`, `xclip`, `xsel` or supplying your own clipboard tool.
* One of `wtype`, `xdotool` or supplying your own typing tool. * One of `wtype`, `xdotool` or supplying your own typing tool.
* `sed`, `grep`, `cut`, `sort`, `uniq`, `tr`, `curl` if using the download functionality. * `sed`, `grep`, `cut`, `sort`, `uniq`, `tr`, `curl` if using the download functionality.
@ -43,10 +43,10 @@ ln -s bemoji/bemoji /usr/local/bin/bemoji
### Arch Linux ### Arch Linux
On Arch Linux, bemoji has been packaged for the [AUR](https://aur.archlinux.org/packages?K=bemoji) so it can be installed manually from here or easily with your preferred AUR helper, e.g.: On Arch Linux, bemoji has been packaged for the [AUR](https://aur.archlinux.org/packages/bemoji-git) so it can be installed manually from here or easily with your preferred AUR helper, e.g.:
```bash ```bash
paru -S bemoji # or bemoji-git paru -S bemoji-git
``` ```
## 💿 Usage ## 💿 Usage
@ -78,7 +78,7 @@ bindsym Mod4+Shift+e exec bemoji -t
For `riverwm`, put the following in `~/.config/river/init`: For `riverwm`, put the following in `~/.config/river/init`:
``` ```
riverctl map normal Mod4+Shift E spawn "bemoji -t" riverctl map normal $mod+Shift E spawn "bemoji -t"
``` ```
In `sxhkd`, put the following into `~/.config/sxhkd/sxhkdrc`: In `sxhkd`, put the following into `~/.config/sxhkd/sxhkdrc`:
@ -118,46 +118,35 @@ By default, bemoji will sort the list it displays by your most frequently and mo
To disable this behavior, execute bemoji like the following: To disable this behavior, execute bemoji like the following:
```bash ```bash
bemoji --hist-limit 0 bemoji -P
``` ```
This will stop bemoji from adding recently used emoji before displaying the list. 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: You can also stop bemoji from adding any emoji to your history in the first place:
```bash ```bash
bemoji --private bemoji -p
``` ```
This will not add any of the emoji you pick to your recent emojis. 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 Put both together to completely ignore the recent emoji feature of the program:
(these are the equivalent short versions of the options above):
```bash ```bash
bemoji -p -P0 bemoji -Pp
``` ```
Like this, you'll be hiding any recent personal emoji and no one will know that you always type 👄🍆💦. Like this, you'll be hiding any recent personal emoji and no one will know that you always type 👄🍆💦.
To limit the number of your recently used emoji that are shown without hiding them completely simply increase the number to however many you wish to display.
For example, to display only the top 4 recently used emoji:
```bash
bemoji --hist-limit 4
```
The recent list will also contain emoji that are *not* usually on your lists, The recent list will also contain emoji that are *not* usually on your lists,
so kept in single-use lists for example. so kept in single-use lists for example.
If you don't wish those to show up, make use of these options. If you don't wish those to show up, make use of these options.
### Setting custom directories and editing history ### Setting custom directories
By default bemoji stores your recent history in `$XDG_STATE_HOME/bemoji-history.txt`, By default bemoji stores your recent history in `$XDG_STATE_HOME/bemoji-history.txt`,
so most often in `~/.local/state/bemoji-history.txt` so most often in `~/.local/state/bemoji-history.txt`
You can edit this file in any text editor to change your recent history,
removing, adding or changing the emoji appearing there.
You can overwrite the directories bemoji uses for its emoji lists and history files with the following two environment variables: You can overwrite the directories bemoji uses for its emoji lists and history files with the following two environment variables:
``` ```
@ -172,7 +161,7 @@ There are no equivalent commandline arguments to overwrite these two settings.
A custom emoji list can be supplied as commandline argument `-f` or `BEMOJI_CUSTOM_LIST` environment variable. A custom emoji list can be supplied as commandline argument `-f` or `BEMOJI_CUSTOM_LIST` environment variable.
```bash ```bash
bemoji --file path/to/my/list.txt bemoji -f path/to/my/list.txt
``` ```
The list will override the normally presented emoji, The list will override the normally presented emoji,
@ -185,27 +174,21 @@ 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" bemoji -f "https://raw.githubusercontent.com/jchook/emoji-menu/master/data/emojis.txt"
``` ```
### Download additional emoji sets ### Change the default emoji set
bemoji automatically downloads an emoji list for you to use on first invocation. bemoji downloads emoji for you to use on first invocation.
By default, it only downloads emoji, though you can have it download math symbols and nerdfont icons as well. By default, it only downloads emoji, though you can have it download math symbols as well.
To download additional sets, execute bemoji like the following: To change this setting, execute bemoji like the following:
```bash ```bash
bemoji --download all bemoji -D all
``` ```
This will download *all* default sets bemoji knows - which is currently the default emoji list, nerd font icons, and a long list of math symbols. 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`, `nerd`, `none`. Other valid options for this setting are `emoji`, `math`, `none`.
```bash
bemoji -D "math emoji nerd"
```
The above command is equivalent to the previous `all` as you can mention multiple sets you want downloaded.
If set to `none` and no files are in the emoji directory, If set to `none` and no files are in the emoji directory,
bemoji will complain and not show anything. bemoji will simply complain and not show anything.
### Do not skip to new line after output ### Do not skip to new line after output
@ -233,15 +216,7 @@ BEMOJI_CLIP_CMD="path/to/your/clipboard/tool"
BEMOJI_TYPE_CMD="path/to/your/xdotool" BEMOJI_TYPE_CMD="path/to/your/xdotool"
``` ```
The candidate list (in the case of picker tool) or the picked selection are passed to the tools through stdin. This is pretty experimental and you'll have to see how well it works for you.
For example, to manually invoke fuzzel with no extra options as the picker for bemoji you would use:
```bash
BEMOJI_PICKER_CMD="fuzzel -d" bemoji
```
This is somewhat experimental still and you'll have to see how well it works for you.
The setting can not be changed through the commandline alone. The setting can not be changed through the commandline alone.
### Execute a custom command with my emoji ### Execute a custom command with my emoji
@ -251,7 +226,7 @@ You can execute bemoji with the `-e` flag with which you tell it not to do anyth
This can be very useful for creating your own little script with it: This can be very useful for creating your own little script with it:
```bash ```bash
bemoji --echo | cat <(echo -n "https://emojipedia.org/") - | xargs xdg-open 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. This snippet will open a wiki page for the picked emoji in your browser.
@ -265,16 +240,16 @@ What follows is a list of all environment variables bemoji understands,
with their default settings with their default settings
```bash ```bash
BEMOJI_DB_LOCATION="$XDG_DATA_HOME/bemoji" # where the emoji lists reside BEMOJI_DB_LOCATION=$XDG_DATA_HOME/bemoji # where the emoji lists reside
BEMOJI_HISTORY_LOCATION="$XDG_STATE_HOME" # where the state file resides BEMOJI_HISTORY_LOCATION=$XDG_STATE_HOME # where the state file resides
BEMOJI_CUSTOM_LIST="" # the custom emoji list to display BEMOJI_CUSTOM_LIST="" # the custom emoji list to display
BEMOJI_DOWNLOAD_LIST="" # the default emoji lists to download to database BEMOJI_DOWNLOAD_LIST="" # the default emoji lists to download to database
BEMOJI_DEFAULT_COMMAND="" # which command to invoke by default BEMOJI_DEFAULT_COMMAND=<clip-tool> # which command to invoke by default
BEMOJI_PICKER_CMD="bemenu" # which picker tool to use BEMOJI_PICKER_CMD=bemenu # which picker tool to use
BEMOJI_CLIP_CMD="wl-copy" # which clipboard 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_TYPE_CMD=wtype # which typing tool to use (ydotool will NOT work)
BEMOJI_PRIVATE_MODE=false # whether to save new entries BEMOJI_PRIVATE_MODE=false # whether to save new entries
BEMOJI_LIMIT_RECENT="" # whether to display recent entries BEMOJI_IGNORE_RECENT=false # whether to display recent entries
BEMOJI_ECHO_NEWLINE=true # whether to end the output with a newline character BEMOJI_ECHO_NEWLINE=true # whether to end the output with a newline character
``` ```
@ -290,12 +265,7 @@ If you have an idea or improvement, don't hesitate to open a merge request!
This project makes use of [bash-bats](https://github.com/bats-core/bats-core) (community fork) to test some of its functionality. This project makes use of [bash-bats](https://github.com/bats-core/bats-core) (community fork) to test some of its functionality.
To run the tests locally: To run the tests locally, simply execute `./test/bats/bin/bats test`.
```
git submodule init
git submodule update
./test/bats/bin/bats test
```
I would suggest running the test suite in docker instead, just to minimize the possibility of something going awry and borking up your local file system. I would suggest running the test suite in docker instead, just to minimize the possibility of something going awry and borking up your local file system.
To run the tests in a docker suite, execute `docker run --rm -it -v "$PWD:/code" bats/bats:latest /code/test` after initializing the git submodules as listed above. To run the tests in a docker suite, execute `docker run --rm -it -v "$PWD:/code" bats/bats:latest /code/test`

Binary file not shown.

Before

Width:  |  Height:  |  Size: 241 KiB

After

Width:  |  Height:  |  Size: 41 KiB

204
bemoji
View file

@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
bm_version=0.4.0 bm_version=0.2.0
# Emoji default database location # Emoji default database location
bm_db_location=${BEMOJI_DB_LOCATION:-"${XDG_DATA_HOME:-$HOME/.local/share}/bemoji"} bm_db_location=${BEMOJI_DB_LOCATION:-"${XDG_DATA_HOME:-$HOME/.local/share}/bemoji"}
# Setting custom emoji list file location: # Setting custom emoji list file location:
@ -18,16 +18,7 @@ bm_echo_newline=${BEMOJI_ECHO_NEWLINE:-true}
# Do not save choices # Do not save choices
bm_private_mode=${BEMOJI_PRIVATE_MODE:-false} bm_private_mode=${BEMOJI_PRIVATE_MODE:-false}
# Do not sort results # Do not sort results
bm_limit_recent="$BEMOJI_LIMIT_RECENT" bm_ignore_recent=${BEMOJI_IGNORE_RECENT:-false}
declare -A default_pickers=(
["bemenu"]="bemenu -p 🔍 -i -l 20"
["wofi"]="wofi -p 🔍 -i --show dmenu"
["rofi"]="rofi -p 🔍 -i -dmenu --kb-custom-1 "Alt+1" --kb-custom-2 "Alt+2""
["dmenu"]="dmenu -p 🔍 -i -l 20"
["ilia"]="ilia -n -p textlist -l 'Emoji' -i desktop-magnifier"
["fuzzel"]="fuzzel -d -p 🔍"
)
# Report usage # Report usage
usage() { usage() {
@ -37,19 +28,19 @@ usage() {
echo "Invoked without arguments sends the picked emoji to the clipboard." echo "Invoked without arguments sends the picked emoji to the clipboard."
echo echo
echo " Command options (can be combined):" echo " Command options (can be combined):"
echo " -t, --type Simulate typing the emoji choice with the keyboard." echo " -t Simulate typing the emoji choice with the keyboard."
echo " -c, --clip Send emoji choice to the clipboard. (default)" echo " -c Send emoji choice to the clipboard. (default)"
echo " -e, --echo Only echo out the picked emoji." echo " -e Only echo out the picked emoji."
echo "" echo ""
echo " Other options:" echo " Other options:"
echo " -n, --noline Do not print a newline after the picked emoji." echo " -n Do not print a newline after the picked emoji."
echo " -p, --private Do not save picked emoji to recent history." echo " -p Do not save picked emoji to recent history."
echo " -P, --hist-limit <number> Limit number of recent emoji to display." echo " -P Do not order emoji by recently used."
echo " -D, --download <choice> Choose from default lists to download." echo " -D <choice> Choose specific default lists to download if none found locally."
echo " Valid choices: all|none|emoji|math|nerd (multiple choices possible)." echo " Valid choices: all|none|emoji|math."
echo " -f, --file <filepath> Use a custom emoji database. Can be a url which will be retrieved." echo " -f <filepath> Use a custom emoji database. Can be a url which will be retrieved."
echo " -v, --version Display current program version and directory configuration." echo " -v Display current program version and directory configuration."
echo " -h, --help Show this help." echo " -h Show this help."
echo echo
exit "$1" exit "$1"
} }
@ -59,72 +50,22 @@ version() {
exit exit
} }
msg() { # Get Options
# Outputs a message to stderr, to be used for info, warning and error messages. while getopts ":f:D:tcenpPhv" o; do
printf "%s\n" "$1" >&2 case "${o}" in
} f) BEMOJI_CUSTOM_LIST="${OPTARG}" ;;
parse_cli() {
while getopts cD:ef:hnpP:tv-: arg "$@"; do
case "$arg" in
c) bm_cmds+=(_clipper) ;;
D) _opt_set_download_list "${OPTARG}" ;;
e) bm_cmds+=(cat) ;;
f) _opt_set_custom_list "${OPTARG}" ;;
h) usage 0 ;;
n) bm_echo_newline=false ;;
p) bm_private_mode=true ;;
P) _opt_set_hist_limit "${OPTARG}" ;;
t) bm_cmds+=(_typer) ;; t) bm_cmds+=(_typer) ;;
c) bm_cmds+=(_clipper) ;;
e) bm_cmds+=(cat) ;;
n) bm_echo_newline=false ;;
D) BEMOJI_DOWNLOAD_LIST="${OPTARG}" ;;
p) bm_private_mode=true ;;
P) bm_ignore_recent=true ;;
h) usage 0 ;;
v) version ;; v) version ;;
-) *) usage 1 ;;
LONG_OPTARG="${OPTARG#*=}"
case "$OPTARG" in
clip) bm_cmds+=(_clipper) ;;
download=?*) _opt_set_download_list "${LONG_OPTARG}" ;;
download*)
_opt_set_download_list "${*:$OPTIND:1}"
OPTIND=$((OPTIND + 1))
;;
echo) bm_cmds+=(cat) ;;
file=?*) _opt_set_custom_list "${LONG_OPTARG}" ;;
file*)
_opt_set_custom_list "${*:$OPTIND:1}"
OPTIND=$((OPTIND + 1))
;;
help) usage 0 ;;
noline) bm_echo_newline=false ;;
private) bm_private_mode=true ;;
hist-limit=?*) _opt_set_hist_limit "${LONG_OPTARG}" ;;
hist-limit*)
_opt_set_hist_limit "${*:$OPTIND:1}"
OPTIND=$((OPTIND + 1))
;;
type) bm_cmds+=(_typer) ;;
version) version ;;
'') break ;;
*)
echo "Unknown option: ${OPTARG}" 1>&2
usage 1
;;
esac
;;
\?) exit 2 ;;
esac esac
done done
shift $((OPTIND - 1))
OPTIND=1
}
_opt_set_custom_list() {
BEMOJI_CUSTOM_LIST="$1"
}
_opt_set_download_list() {
BEMOJI_DOWNLOAD_LIST="$1"
}
_opt_set_hist_limit() {
bm_limit_recent="$1"
}
prepare_db() { prepare_db() {
# Create list directory # Create list directory
@ -132,50 +73,34 @@ prepare_db() {
mkdir -p "$bm_db_location" mkdir -p "$bm_db_location"
fi fi
if [ -n "$BEMOJI_DOWNLOAD_LIST" ]; then if [ -n "$(find "$bm_db_location" -maxdepth 0 -type d -empty 2>/dev/null)" ]; then
# Populate default lists # Populate default lists
if echo "$BEMOJI_DOWNLOAD_LIST" | grep -q -e 'none'; then if echo "$BEMOJI_DOWNLOAD_LIST" | grep -q -e 'none'; then
msg "Not downloading a default emoji list." printf "No emoji list found, but set to not download any default lists."
return exit 1
elif echo "$BEMOJI_DOWNLOAD_LIST" | grep -q -e 'all'; then elif echo "$BEMOJI_DOWNLOAD_LIST" | grep -q -e 'all'; then
dl_default_emoji dl_default_emoji
dl_math_symbols dl_math_symbols
dl_nerd_symbols
return return
else fi
if echo "$BEMOJI_DOWNLOAD_LIST" | grep -q -e 'emoji'; then if [ -z "$BEMOJI_DOWNLOAD_LIST" ] || echo "$BEMOJI_DOWNLOAD_LIST" | grep -q -e 'emoji'; then
dl_default_emoji dl_default_emoji
fi fi
if echo "$BEMOJI_DOWNLOAD_LIST" | grep -q -e 'math'; then if echo "$BEMOJI_DOWNLOAD_LIST" | grep -q -e 'math'; then
dl_math_symbols dl_math_symbols
fi fi
if echo "$BEMOJI_DOWNLOAD_LIST" | grep -q -e 'nerd'; then
dl_nerd_symbols
fi
fi
fi
if [ -n "$(find "$bm_db_location" -maxdepth 0 -type d -empty 2>/dev/null)" ]; then
dl_default_emoji
fi fi
} }
dl_default_emoji() { dl_default_emoji() {
local emojis curl -sSL "https://unicode.org/Public/emoji/14.0/emoji-test.txt" |
emojis=$(curl -sSL "https://unicode.org/Public/emoji/latest/emoji-test.txt") sed -ne 's/^.*; fully-qualified.*# \(\S*\) \S* \(.*$\)/\1 \2/gp' >"$bm_db_location/emojis.txt"
printf "%s" "$emojis" | sed -ne 's/^.*; fully-qualified.*# \(\S*\) \S* \(.*$\)/\1 \2/gp' >"$bm_db_location/emojis.txt" printf "Downloaded default emoji set."
msg "Downloaded default emoji set."
} }
dl_math_symbols() { dl_math_symbols() {
curl -sSL "https://unicode.org/Public/math/latest/MathClassEx-15.txt" | curl -sSL "https://unicode.org/Public/math/latest/MathClassEx-15.txt" |
grep -ve '^#' | cut -d';' -f3,7 | sed -e 's/;/ /' >"$bm_db_location/math.txt" grep -ve '^#' | cut -d';' -f3,7 --output-delimiter=' ' >"$bm_db_location/math.txt"
msg "Downloaded math symbols set." printf "Downloaded math symbols set."
}
dl_nerd_symbols() {
local nerd all
nerd=$(curl -sSL "https://raw.githubusercontent.com/ryanoasis/nerd-fonts/master/css/nerd-fonts-generated.css")
all+=$(printf "%s" "$nerd" | sed -ne '/\.nf-/p' -e '/\s*[^_]content:/p' | sed -e 'N;s/^\.nf-\(.*\):before.* content: \"\\\(.*\)\";/\\U\2 \1/')
echo -e "$all" > "$bm_db_location/nerdfont.txt"
msg "Downloaded nerdfont symbols set."
} }
gather_emojis() { gather_emojis() {
@ -187,33 +112,25 @@ gather_emojis() {
result=$(cat "$bm_db_location"/*.txt) result=$(cat "$bm_db_location"/*.txt)
fi fi
if [ -n "$bm_limit_recent" ] && [ "$bm_limit_recent" -eq 0 ]; then if [ "$bm_ignore_recent" = true ]; then
printf "%s" "$result" printf "%s" "$result"
return else
printf "%s\n%s" "$(get_most_recent)" "$result" | cat -n - | sort -uk2 | sort -n | cut -f2-
fi fi
printf "%s\n%s" "$(get_most_recent "$bm_limit_recent")" "$result" | cat -n - | sort -uk2 | sort -n | cut -f2-
} }
get_most_recent() { get_most_recent() {
limit=${1}
recent_file="$bm_history_file" recent_file="$bm_history_file"
if [ ! -f "$recent_file" ]; then if [ ! -f "$recent_file" ]; then
touch "$recent_file" touch "$recent_file"
fi fi
# TODO improve this messy line # TODO improve this messy line
local result sed -e '/^$/d' "$recent_file" |
result=$(sed -e '/^$/d' "$recent_file" |
sort | sort |
uniq -c | uniq -c |
sort -k1rn | sort -rn |
sed -e 's/^\s*//' | sed -e 's/^\s*//' |
cut -d' ' -f2-) cut -d' ' -f2-
if [ -z "$limit" ]; then
echo "$result"
else
echo "$result" | head -n "$limit"
fi
} }
add_to_recent() { add_to_recent() {
@ -236,26 +153,23 @@ _clipper() {
elif [ -n "$DISPLAY" ] && command -v xsel >/dev/null 2>&1; then elif [ -n "$DISPLAY" ] && command -v xsel >/dev/null 2>&1; then
xsel -b xsel -b
else else
msg "No suitable clipboard tool found." printf "No suitable clipboard tool found."
exit 1 exit 1
fi fi
} }
# Set default typing util # Set default typing uti
_typer() { _typer() {
totype=$(cat -)
if [ -n "$BEMOJI_TYPE_CMD" ]; then if [ -n "$BEMOJI_TYPE_CMD" ]; then
# shellcheck disable=SC2068 # shellcheck disable=SC2068
${BEMOJI_TYPE_CMD[@]} ${BEMOJI_TYPE_CMD[@]}
return elif [ -n "$WAYLAND_DISPLAY" ] && command -v wtype >/dev/null 2>&1; then
fi
totype=$(cat -)
if [ -n "$WAYLAND_DISPLAY" ] && command -v wtype >/dev/null 2>&1; then
wtype -s 30 "$totype" wtype -s 30 "$totype"
elif [ -n "$DISPLAY" ] && command -v xdotool >/dev/null 2>&1; then elif [ -n "$DISPLAY" ] && command -v xdotool >/dev/null 2>&1; then
xdotool type --delay 30 "$totype" xdotool type --delay 30 "$totype"
else else
msg "No suitable typing tool found." printf "No suitable typing tool found."
exit 1 exit 1
fi fi
} }
@ -265,22 +179,20 @@ _picker() {
if [ -n "$BEMOJI_PICKER_CMD" ]; then if [ -n "$BEMOJI_PICKER_CMD" ]; then
# shellcheck disable=SC2068 # shellcheck disable=SC2068
${BEMOJI_PICKER_CMD[@]} ${BEMOJI_PICKER_CMD[@]}
return elif command -v bemenu >/dev/null 2>&1; then
fi bemenu -p 🔍 -i -l 20
elif command -v wofi >/dev/null 2>&1; then
for tool in "${!default_pickers[@]}"; do wofi -p 🔍 -i --show dmenu
if command -v "$tool" >/dev/null 2>&1; then elif command -v rofi >/dev/null 2>&1; then
${default_pickers[$tool]} rofi -p 🔍 -i -dmenu --kb-custom-1 "Alt+1" --kb-custom-2 "Alt+2"
return elif command -v dmenu >/dev/null 2>&1; then
fi dmenu -p 🔍 -i -l 20
done else
printf "No suitable picker tool found."
msg "No suitable picker tool found."
exit 1 exit 1
fi
} }
parse_cli "$@"
[ -n "$BEMOJI_CUSTOM_LIST" ] || prepare_db [ -n "$BEMOJI_CUSTOM_LIST" ] || prepare_db
result=$(gather_emojis | _picker) result=$(gather_emojis | _picker)
exit_value="$?" exit_value="$?"
@ -289,7 +201,7 @@ result=$(echo "$result" | grep -o '^\S\+' | tr -d '\n')
case "$exit_value" in case "$exit_value" in
1) 1)
exit 1 exit
;; ;;
0) 0)
if [ ${#bm_cmds[@]} -eq 0 ]; then if [ ${#bm_cmds[@]} -eq 0 ]; then

View file

@ -54,11 +54,6 @@ setup() {
typing result" typing result"
} }
@test "Passes selection to custom typer tool through stdin" {
BEMOJI_TYPE_CMD="cat -" run bemoji -t 3>&-
assert_output "❤️"
}
@test "Runs custom default command" { @test "Runs custom default command" {
BEMOJI_DEFAULT_CMD="echo my custom command" run bemoji 3>&- BEMOJI_DEFAULT_CMD="echo my custom command" run bemoji 3>&-
assert_output "my custom command" assert_output "my custom command"
@ -69,11 +64,6 @@ typing result"
assert_output "my clipping" assert_output "my clipping"
} }
@test "Returns status code 1 on picker status code 1" {
BEMOJI_PICKER_CMD="return 1" run bemoji -e 3>&-
assert_failure 1
}
@test "Prints output with newline by default" { @test "Prints output with newline by default" {
bats_require_minimum_version 1.5.0 bats_require_minimum_version 1.5.0
BEMOJI_PICKER_CMD="echo heart" run --keep-empty-lines -- bemoji -e BEMOJI_PICKER_CMD="echo heart" run --keep-empty-lines -- bemoji -e
@ -85,29 +75,3 @@ typing result"
BEMOJI_PICKER_CMD="echo heart" run --keep-empty-lines -- bemoji -ne BEMOJI_PICKER_CMD="echo heart" run --keep-empty-lines -- bemoji -ne
assert_output --regexp '^heart$' assert_output --regexp '^heart$'
} }
@test "Understands long-form options" {
run bemoji --help
assert_success
assert_output --partial "A simple emoji picker."
}
@test "Understands long-form equals values" {
BEMOJI_CLIP_CMD="echo heart" run bemoji --hist-limit=0
assert_success
}
@test "Understands long-form spaced values" {
BEMOJI_CLIP_CMD="echo heart" run bemoji --hist-limit 0
assert_success
}
@test "Understands short-form spaced values" {
BEMOJI_CLIP_CMD="echo heart" run bemoji -P 0
assert_success
}
@test "Can concatenate short-form options and values" {
BEMOJI_CLIP_CMD="echo heart" run bemoji -neP0
assert_success
}

View file

@ -1,48 +0,0 @@
#!/usr/bin/env bash
setup_file() {
# make bemoji executable from anywhere relative to current testfile
TEST_DIR="$( cd "$( dirname "$BATS_TEST_FILENAME" )" >/dev/null 2>&1 && pwd )"
PATH="$TEST_DIR/..:$PATH"
}
setup() {
load 'test_helper/bats-support/load'
load 'test_helper/bats-assert/load'
load 'test_helper/mocks/stub'
# mock out interactive picker for static emoji return
export BEMOJI_PICKER_CMD="echo heart"
# set up small default set of test emoji for each test
export BEMOJI_DB_LOCATION="$BATS_TEST_TMPDIR/database"
export BEMOJI_HISTORY_LOCATION="$BATS_TEST_TMPDIR/history"
mkdir -p "$BEMOJI_DB_LOCATION" "$BEMOJI_HISTORY_LOCATION"
}
@test "Runs emoji download on -D emoji option" {
stub curl \
"echo -e '1F605 ; fully-qualified # emoji E0.6 grinning face with sweat\nnot picked up\n1F605 ; fully-qualified # emoji2 E0.6 picked up'"
run bemoji -D emojis 3>&-
outcome=$(cat "$BEMOJI_DB_LOCATION/emojis.txt")
assert_equal "$outcome" "emoji grinning face with sweat
emoji2 picked up"
unstub curl
}
@test "Runs maths download on -D maths option" {
stub curl \
"echo '03A3;A;Σ;Sigma;ISOGRK3;;GREEK CAPITAL LETTER SIGMA'"
run bemoji -D math 3>&-
outcome=$(cat "$BEMOJI_DB_LOCATION/math.txt")
assert_equal "$outcome" "Σ GREEK CAPITAL LETTER SIGMA"
unstub curl
}
@test "Runs nerdfont download on -D nerd option" {
stub curl \
"printf 'meangingless\nafiller lines\n.nf-md-pipe_wrench:before { \n content: \"\\\f1354\";\n }'"
run bemoji -D nerd 3>&-
outcome=$(cat "$BEMOJI_DB_LOCATION/nerdfont.txt")
assert_equal "$outcome" "󱍔 md-pipe_wrench"
unstub curl
}

View file

@ -1,43 +0,0 @@
#!/usr/bin/env bash
setup_file() {
# make bemoji executable from anywhere relative to current testfile
TEST_DIR="$( cd "$( dirname "$BATS_TEST_FILENAME" )" >/dev/null 2>&1 && pwd )"
PATH="$TEST_DIR/..:$PATH"
}
setup() {
load 'test_helper/bats-support/load'
load 'test_helper/bats-assert/load'
# set up small default set of test emoji for each test
export BEMOJI_DB_LOCATION="$BATS_TEST_TMPDIR/database"
export BEMOJI_HISTORY_LOCATION="$BATS_TEST_TMPDIR/history"
mkdir -p "$BEMOJI_DB_LOCATION" "$BEMOJI_HISTORY_LOCATION"
cat "$BATS_TEST_DIRNAME/resources/test_emoji.txt" > "$BEMOJI_DB_LOCATION/emoji.txt"
# these tests require stdout to be separated from stderr
# such run flags were only introduced in recent bats version
bats_require_minimum_version 1.5.0
}
@test "Prints clipper error to stderr" {
BEMOJI_PICKER_CMD="echo hi" run --separate-stderr bemoji 3>&-
assert_output ""
output="$stderr"
assert_output "No suitable clipboard tool found."
}
@test "Prints picker error to stderr" {
run --separate-stderr bemoji 3>&-
assert_output ""
output="$stderr"
assert_output "No suitable picker tool found."
}
@test "Prints typer error to stderr" {
BEMOJI_PICKER_CMD="echo hi" run --separate-stderr bemoji -t 3>&-
assert_output ""
output="$stderr"
assert_output "No suitable typing tool found."
}

View file

@ -1,57 +0,0 @@
#!/usr/bin/env bash
setup_file() {
# make bemoji executable from anywhere relative to current testfile
TEST_DIR="$( cd "$( dirname "$BATS_TEST_FILENAME" )" >/dev/null 2>&1 && pwd )"
PATH="$TEST_DIR/..:$PATH"
}
setup() {
load 'test_helper/bats-support/load'
load 'test_helper/bats-assert/load'
# mock out interactive picker for static emoji return
export BEMOJI_PICKER_CMD="echo ❤️"
# set up small default set of test emoji for each test
export BEMOJI_DB_LOCATION="$BATS_TEST_TMPDIR/database"
export BEMOJI_HISTORY_LOCATION="$BATS_TEST_TMPDIR/history"
mkdir -p "$BEMOJI_DB_LOCATION" "$BEMOJI_HISTORY_LOCATION"
cat "$BATS_TEST_DIRNAME/resources/test_emoji.txt" > "$BEMOJI_DB_LOCATION/emoji.txt"
}
@test "sorts by frecency" {
echo -e "there\nhello\nhello" > "$BEMOJI_HISTORY_LOCATION/bemoji-history.txt"
echo -e "database" > "$BEMOJI_DB_LOCATION/emoji.txt"
BEMOJI_CLIP_CMD="cat -" BEMOJI_PICKER_CMD="cat -" run bemoji 3>&-
assert_output "hellotheredatabase"
}
@test "history limiting uses sorted results" {
echo -e "zany\nmy\nisee\nonomatopeia" > "$BEMOJI_HISTORY_LOCATION/bemoji-history.txt"
echo -e "database" > "$BEMOJI_DB_LOCATION/emoji.txt"
BEMOJI_CLIP_CMD="cat -" BEMOJI_PICKER_CMD="cat -" run bemoji -P 1 3>&-
assert_output "iseedatabase"
}
@test "history limiting takes frecency into account" {
echo -e "there\nfriend\nhello\nhello" > "$BEMOJI_HISTORY_LOCATION/bemoji-history.txt"
echo -e "database" > "$BEMOJI_DB_LOCATION/emoji.txt"
BEMOJI_CLIP_CMD="cat -" BEMOJI_PICKER_CMD="cat -" run bemoji -P 1 3>&-
assert_output "hellodatabase"
}
@test "-P 0 disables history" {
echo -e "there\nfriend\nhello\nhello" > "$BEMOJI_HISTORY_LOCATION/bemoji-history.txt"
echo -e "database" > "$BEMOJI_DB_LOCATION/emoji.txt"
BEMOJI_CLIP_CMD="cat -" BEMOJI_PICKER_CMD="cat -" run bemoji -P 0 3>&-
assert_output "database"
}
@test "BEMOJI_LIMIT_RECENT=0 disables history" {
echo -e "there\nfriend\nhello\nhello" > "$BEMOJI_HISTORY_LOCATION/bemoji-history.txt"
echo -e "database" > "$BEMOJI_DB_LOCATION/emoji.txt"
BEMOJI_LIMIT_RECENT=0 BEMOJI_CLIP_CMD="cat -" BEMOJI_PICKER_CMD="cat -" run bemoji 3>&-
assert_output "database"
}

@ -1 +0,0 @@
Subproject commit 7e0fbf6bc705bd1b09daa2d5ff88962ddbe832f6