#!/usr/bin/env bash # This is a Rofi script-mode script creating an interface for Recoll (https://www.lesbonscomptes.com/recoll/). # The selected path is then opened with its desktop launcher (e.g., xdg-open) and its location is copied on the clipboard. # # Dependencies: # * GNU Bash v5.0.13 # * Recoll v1.27.0 with Xapian v1.4.15 # * Dunst v1.4.1 with libnotify v0.7.9 # * A desktop launcher (like xdg-open). # * A clipboard manager (like xclip). # For getting started, you can view the documentation in https://github.com/davatorium/rofi/blob/next/doc/rofi-script.5.markdown. # As of 2020-06-06, the official version is not yet release and this script is developed for the 'next' branch which may have bugs present. # Exit immediately if it's not run as a Rofi script. if [ -z "$ROFI_OUTSIDE" ] then echo "This script is not being run as a Rofi script." echo "Usage: 'rofi -show -modi :$0" exit 1 fi # Do stuff on first boot. if [ "$ROFI_RETV" = 0 ] then # Set the delimiter to '\x1'. # This is useful for creating entries with newlines (though, you have to manually set '-eh' option with >1). echo -en "\x00delim\x1f\\x1\n" message="Search something..." fi # Some constants to be used. # Btw, don't use primary selection of the location for copying it from xclip, it will freeze Rofi (and may cause this script to be empty which I found out the hard way). open_launcher_cmd="xdg-open" copy_to_clipboard_cmd="xclip -selection clipboard" prompt="Recoll" function show_help() { echo -en "To search files, simply prepend the query with '##'.\x1" echo -en "Anything else should get you back reading this help section.\x1" echo -en "Happy searching, boisengirls! :)\x1" } # By the time the user provided an input, this conditional will always fail. if [ -z "$@" ] then show_help else # If the entry is detected with the 'file://' URI protocol (which is returned from the Recoll query), it will open it and exit the script. if [[ "$@" == file://* ]] then coproc ( "$open_launcher_cmd" "$@" > /dev/null 2>&1 ) && notify-send "Opening file at $@..." exec 1>&- exit # If the argument is detected as a query string (which is in format '##'), it will run the Recoll query. elif [[ "$@" == \#\#* ]] then recoll_query=${@#\#\#} # The duration is in units of miliseconds. # This is a crude way but it is the simplest solution I could easily fit for now. duration_start=$(date +%s%N) readarray -d '\n' search_result <<< $(recoll -b -t -q "$recoll_query" 2>/dev/null) # Since the Recoll command-line interface doesn't have indications whether the query has successfully delivered at least one item or not, counting the length of the resulting string is the next best thing. # If the string is only composed of one character, it most likely contain only a newline or something. if [ "${#search_result}" -gt 1 ] then # We're reducing it by one since there's a newline in the beginning in the result. query_count=$(echo "$search_result" | wc -l) awk '{print $0}' <<< "$search_result" | xargs -I% echo -en "%\x1" duration_end=$((($(date +%s%N) - $duration_start)/1000000)) message="You've searched '$recoll_query' with ($query_count - 1) results completed in $duration_end ms." else message="Lol, no results." echo -en "I use Rofi btw.\x1" fi # Otherwise, all entries that lead to nothing simply go back to the help section as promised. >:) else show_help fi fi # Display the current message and the prompt, whatever that is. echo -en "\x00prompt\x1f$prompt\x1" echo -en "\x00message\x1f$message\x1"