Add long-form option parsing
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

So far we could only add single-letter (POSIX) options: `-e`, `-n` and
so forth. Since we will run out of alphabet at some point, this commit
introduces parsing of multi-letter long-form (gnu) options (plus any
modern application should really support it anyways):
`--echo`, `--noline`.

Additionally, we support supplying long-form options that supply a value
both in the spaced (`--hist-limit 0`) and the equals (`--hist-limit=0`)
forms. Short, long, spaced, equals can be mixed and matched between
freely.

Lastly, we retain the ability to concatenate short options as before
(`-ne` is valid, as is `-P0` for the respective options above).

This should cover all bases and does not complicate the code too much to
keep a coherent overview.

Changed several code samples in the documentation to make
use of short- or long-form options to point out
possibility.
This commit is contained in:
Marty Oehme 2023-08-26 14:37:44 +02:00
parent 6c037a5771
commit d44cbf5b74
Signed by: Marty
GPG key ID: EDBF2ED917B2EF6A
4 changed files with 123 additions and 45 deletions

View file

@ -14,6 +14,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
This replaces previous `-P` history flag toggle. Use number to set amount of recent This replaces previous `-P` history flag toggle. Use number to set amount of recent
entries to display, `-P3`. To completely hide history use `-P0`. entries to display, `-P3`. To completely hide history use `-P0`.
- Add nerdfont emoji set download with `-D nerd` - 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 ### Changed

View file

@ -118,7 +118,7 @@ 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 -P 0 bemoji --hist-limit 0
``` ```
This will stop bemoji from adding recently used emoji before displaying the list. This will stop bemoji from adding recently used emoji before displaying the list.
@ -126,11 +126,12 @@ This will stop bemoji from adding recently used emoji before displaying the list
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 -p bemoji --private
``` ```
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 -p -P0
@ -142,7 +143,7 @@ To limit the number of your recently used emoji that are shown without hiding th
For example, to display only the top 4 recently used emoji: For example, to display only the top 4 recently used emoji:
```bash ```bash
bemoji -P 4 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,
@ -171,7 +172,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 -f path/to/my/list.txt bemoji --file path/to/my/list.txt
``` ```
The list will override the normally presented emoji, The list will override the normally presented emoji,
@ -191,7 +192,7 @@ By default, it only downloads emoji, though you can have it download math symbol
To download additional sets, execute bemoji like the following: To download additional sets, execute bemoji like the following:
```bash ```bash
bemoji -D all bemoji --download 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, nerd font icons, and a long list of math symbols.
@ -201,7 +202,7 @@ Other valid options for this setting are `emoji`, `math`, `nerd`, `none`.
bemoji -D "math emoji nerd" bemoji -D "math emoji nerd"
``` ```
The above command is equivalent to `all` as you can mention multiple sets you want downloaded. 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 complain and not show anything.
@ -244,7 +245,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 -e | cat <(echo -n "https://emojipedia.org/") - | xargs xdg-open bemoji --echo | 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.

121
bemoji
View file

@ -22,27 +22,27 @@ bm_limit_recent="$BEMOJI_LIMIT_RECENT"
# Report usage # Report usage
usage() { usage() {
echo "Usage: $(basename "$0") [-t | -c | -e] [-f <filepath> ] [-p] [-P] [-D <choices>]" 1>&2 echo "Usage: $(basename "$0") [-t | -c | -e] [-f <filepath> ] [-p] [-P] [-D <choices>]" 1>&2
echo echo
echo "A simple emoji picker. Runs on bemenu/wofi/rofi/dmenu by default." 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 "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 Simulate typing the emoji choice with the keyboard." echo " -t, --type Simulate typing the emoji choice with the keyboard."
echo " -c Send emoji choice to the clipboard. (default)" echo " -c, --clip Send emoji choice to the clipboard. (default)"
echo " -e Only echo out the picked emoji." echo " -e, --echo Only echo out the picked emoji."
echo "" echo ""
echo " Other options:" echo " Other options:"
echo " -n Do not print a newline after the picked emoji." echo " -n, --noline Do not print a newline after the picked emoji."
echo " -p Do not save picked emoji to recent history." echo " -p, --private Do not save picked emoji to recent history."
echo " -P <number> Limit number of recent emoji to display." echo " -P, --hist-limit <number> Limit number of recent emoji to display."
echo " -D <choice> Choose from default lists to download." echo " -D, --download <choice> Choose from default lists to download."
echo " Valid choices: all|none|emoji|math|nerd (multiple choices possible)." echo " Valid choices: all|none|emoji|math|nerd (multiple choices possible)."
echo " -f <filepath> Use a custom emoji database. Can be a url which will be retrieved." echo " -f, --file <filepath> Use a custom emoji database. Can be a url which will be retrieved."
echo " -v Display current program version and directory configuration." echo " -v, --version Display current program version and directory configuration."
echo " -h Show this help." echo " -h, --help Show this help."
echo echo
exit "$1" exit "$1"
} }
version() { version() {
@ -50,22 +50,67 @@ version() {
exit exit
} }
# Get Options parse_cli() {
while getopts ":f:D:tcenpP:hv" o; do while getopts cD:ef:hnpP:tv-: arg "$@"; do
case "${o}" in case "$arg" in
f) BEMOJI_CUSTOM_LIST="${OPTARG}" ;; c) bm_cmds+=(_clipper) ;;
t) bm_cmds+=(_typer) ;; D) _opt_set_download_list "${OPTARG}" ;;
c) bm_cmds+=(_clipper) ;; e) bm_cmds+=(cat) ;;
e) bm_cmds+=(cat) ;; f) _opt_set_custom_list "${OPTARG}" ;;
n) bm_echo_newline=false ;; h) usage 0 ;;
D) BEMOJI_DOWNLOAD_LIST="${OPTARG}" ;; n) bm_echo_newline=false ;;
p) bm_private_mode=true ;; p) bm_private_mode=true ;;
P) bm_limit_recent="${OPTARG}" ;; P) _opt_set_hist_limit "${OPTARG}" ;;
h) usage 0 ;; t) bm_cmds+=(_typer) ;;
v) version ;; v) version ;;
*) usage 1 ;; -)
esac LONG_OPTARG="${OPTARG#*=}"
done 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
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
@ -220,6 +265,8 @@ _picker() {
fi 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="$?"

View file

@ -85,3 +85,29 @@ 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
}