#!/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!'