#!/bin/sh
echo_err() {
notify-send -u critical "$0 error" "$1"
}
err() {
echo_err "$1"
exit 1
}
check_dep() {
command -v "$1" > /dev/null || err "$1 is required: $2"
}
# We don't check if dmenu is installed because someone
# may want to replace it via DMENU vars
check_dep trans https://github.com/soimort/translate-shell
check_dep notify-send
load_config() {
config_dir="${XDG_CONFIG_HOME:-$HOME/.config}/dmenu-translate"
[ -d "$config_dir" ] || mkdir -p "$config_dir"
config_file="$config_dir/config.sh"
[ -f "$config_file" ] || touch "$config_file"
old_config_file="$config_dir/config.conf"
[ -f "$old_config_file" ] && notify-send "dmenu-translate warning" "Found old configuration file at $old_config_file
, which is no longer supported. Please move your settings to a new file at $config_file
and delete the old one."
. "$config_file"
# Check others
if [ -n "$WAYLAND_DISPLAY" ]; then
: "${CLIP_COPY:=wl-copy -n}"
: "${CLIP_PASTE_CLIP:=wl-paste}"
: "${CLIP_PASTE_PRIM:=wl-paste -p}"
: "${DMENU:=wmenu}"
: "${TERMINAL=foot}"
else
: "${CLIP_COPY:=xclip -i -r -selection clipboard}"
: "${CLIP_PASTE_CLIP:=xclip -o -selection clipboard}"
: "${CLIP_PASTE_PRIM:=xclip -o -selection primary}"
: "${DMENU:=dmenu}"
: "${TERMINAL=xterm}"
fi
# Default values
: "${TRANS_LANGS:=:ru :en}"
: "${DMENU_TEXT:=${DMENU} -i -p 'Translate: Text'}"
: "${DMENU_LANG:=${DMENU} -i -p 'Translate: Into'}"
: "${DMENU_NEXT:=${DMENU} -i -p 'Translate: Next?'}"
}
formatmenu() {
echo "$1" | tr '\n' ' ' | sed 's/\s\{3,\}//g; s/^\(.\{30\}\).\+/\1.../; s/$/\n/'
}
get_selection() {
[ -n "$1" ] && eval "$CLIP_PASTE_CLIP" || eval "$CLIP_PASTE_PRIM"
}
clip_menu() {
{ formatmenu "$1"; formatmenu "$2"; } |
sed 's/^\s*$//; 1s/^./Primary: &/; 2s/^./Clipboard: &/' |
sed '/^$/d'
}
lang_menu() {
echo "$TRANS_LANGS" | sed 's/\s\+/\n/g' | sed '/:/!s/^/:/'
echo '[Define]'
}
choose_next() {
t="$1"
shift
if [ -n "$ALWAYS_COPY" ]; then
echo 'Copy'
else
eval "$DMENU_NEXT" "$@" <<-EOF
Copy: $(formatmenu "$t")
Copy temp file name
View
EOF
fi
}
save_file() (
tmp="$(mktemp --tmpdir 'dmenu-translate.XXXXXX')"
echo "$1" > "$tmp"
echo "$tmp"
)
open_term() {
${TERMINAL} -e ${PAGER:-'less'} "$(save_file "$1")"
}
get_text() {
echo "$2" | while IFS= read -r clip; do
[ "$1" = "$clip" ] && {
type="$(echo "$clip" | sed 's/^\(\w\+\):.*/\1/')"
case "$type" in
Primary) echo "$primary" ;;
Clipboard) echo "$clipboard" ;;
esac
exit 10
}
done
# If not found, just echo text
[ $? -ne 10 ] && echo "$1"
}
# Config
load_config
# Get selections
clipboard="$(get_selection clip)"
primary="$(get_selection)"
clip_menu="$(clip_menu "$primary" "$clipboard")"
# Enter text
text="$(printf '%s' "$clip_menu" | eval "$DMENU_TEXT" "$@")" || exit 0
text="$(get_text "$text" "$clip_menu")"
# Choose target language
target="$(lang_menu | eval "$DMENU_LANG" "$@")" || exit 0
# If Define chosen, define term and exit
[ "$target" = '[Define]' ] && {
dict="$(trans -dictionary "$text")"
open_term "$(trans -dictionary "$text")"
exit 0
}
# Translate text
translation="$(trans -b "$target" "$text")"
[ -z "$translation" ] && err 'Failed to translate'
case "$(choose_next "$translation" "$@")" in
'View') open_term "$translation"; exit 0 ;;
'Copy temp file name') output="$(save_file "$translation")" ;;
'Copy'*) output="$translation" ;;
*) exit 0 ;;
esac
echo "$output" | eval "$CLIP_COPY" || err 'Failed to copy! Is CLIP_COPY setting set properly?'
notify-send 'dmenu-translate' 'Translation copied to clipboard!'