#!/usr/bin/env bash # This is Burokufi, a Rofi frontend for Buku (https://github.com/jarun/Buku). # Mainly ~stolen~ inspired from the 'buku_run' script (https://github.com/carnager/buku_run/). # It is meant to be run as a modi (or script mode). # To get started, simply plop this script somewhere and run 'rofi -show buku -modi buku:' and some of your personal options (e.g., custom keybindings, fullscreen, position). # # Dependencies (or at least the version by the time I made this): # * Buku v4.3 # * GNU Bash v5.0.13 # * Dunst v1.4.1 with libnotify # * Rofi v1.6.0 # * jq v1.6 # The cache location. cachepath="${XDG_CACHE_HOME:-"$HOME/.cache"}/burokufi" mkdir -p $cachepath # Tracking the last mode entered with a file. _name="Burokufi" modepath="$cachepath/recent-mode" debugpath="$cachepath/debug" # Detects if it's run outside of Rofi script mode. if [ -z "$ROFI_OUTSIDE" ] then echo "This script is not supposed to run outside of Rofi script mode." echo "Usage: 'rofi -show -modi :$0" exit 1 fi # Getting the last mode state. mode=$(<"$modepath") # Some first-time boot stuff. if [ "$ROFI_RETV" -eq 0 ] then mode='help' echo "$_name is here, boisengirls!" > "$debugpath" fi # Defining some constants for convenience. message="'kb-custom-1' (Alt+1, by default) for bookmarks. 'kb-custom-2' (Alt+2) to view info on selected URL." # Append to the logfile. function log() { echo "$@" >> "$debugpath" } # Defining some functions also for convenience. # Overriding the Buku command with default actions. # It turns out when Buku is run within a non-TTY environment, it will print something like 'waiting for input' to the stdout. # So, there's an additional process to go through cutting some of it. # Here is the code block in question: https://github.com/jarun/buku/blob/a9fc0bd04297ef12349c0fe1d45bb3452e8c5425/buku#L4773 # $@ - Its arguments. function buku() { command buku $@ | sed -e '1d' } # This is the function that will print out the results. # It will always have an additional hidden URL info attached for convience. # You may freely edit this function to change the formatting of the URL list except for the ASCII delimiters at the end which is pretty important. # $1 - The JSON data of the Buku database. # The function will always assume the JSON is a top-level array with the Buku bookmarks as its items. # (See the command 'buku --print --json' for an example.) function print_to_rofi() { local buku_json="$1" [ "${#buku_json}" -eq 0 ] && return 1 echo "$buku_json" | jq --raw-output '.[] | "<\(.index)> \(.uri)\\x00info\\x1f\(.uri)\\n"' | xargs --null echo -en } # Print the help section. :) function print_help() { echo "Hey, listen!" echo "To open the selected URL, press 'kb-custom-2' (Alt+2 by default)." echo "To view details on the selected URL, press 'kb-custom-3' (Alt+3 by default)." echo "To go back to this help section, simply enter '??'." echo "To search for tags ('--stag'), prepend the query with '##'." echo "To search with a regex, prepend the query with '@@'." echo "To search with '--print', prepend the query with '..'." echo "To search for certain index ('--sany'), prepend the query with '>>'." } # Here's the meat of the code. # This is the part that you might want to keep the attention. # It is simply a case statement for individual keybindings and their associated view. # You can view what other keybindings you can interact at https://github.com/davatorium/rofi/blob/next/doc/rofi-script.5.markdown. # Keypresses and their events. case "$ROFI_RETV" in # 'kb-custom-1' (Alt+1, by default) 10) mode='bookmark' ;; esac # Typing '??' will go into help mode. if [ "$(expr match "$@" '??')" -ne 0 ] then mode='help' fi log "$LINENO: mode before result is '$mode'" # Detecting on what mode should be active. # For the most part, this should be the last part to be executed. case "$mode" in # The help mode where the help section is printed out. 'help') prompt="Help" message="This is the help page, alright." print_help # Once the help section is printed, automatically go into bookmark mode. mode='bookmark' ;; # The bookmark mode. # This is also the default mode. 'bookmark') prompt="Bookmarks" if [ "$ROFI_RETV" -eq 11 ] then prompt="Info" active_url="$ROFI_INFO" buku --deep --sany "$active_url" --json | jq --raw-output '.[0] | keys[] as $k | "\($k): \(.[$k])\\x00nonselectable\\x1ftrue\\n"' | xargs --null echo -en elif [ "$(expr match "$@" '<[0-9]*>\s*')" -ne 0 ] then url=$(echo "$@" | tr -d "<[:digit:]*>[:space:]*") xdg-open "$url" && exit elif [[ "$@" == \#\#* ]] then print_to_rofi "$(buku --stag "${@#\#\#}" --json)" || echo -ne "No bookmark with the specified tag(s).\x00nonselectable\x1ftrue\n" elif [[ "$@" == \@\@* ]] then print_to_rofi "$(buku --sreg "${@#@@}" --json)" || echo -ne "No bookmark with the specified regex.\x00nonselectable\x1ftrue\n" elif [[ "$@" == \.\.* ]] then print_to_rofi "$(buku --print "${@#\.\.}" --json)" || echo -ne "No bookmark with the specified range.\x00nonselectable\x1ftrue\n" elif [[ "$@" == \>\>* ]] then print_to_rofi "$(buku --sany "${@#\>\>}" --json)" || echo -ne "No query result.\x00nonselectable\x1ftrue\n" else print_to_rofi "$(buku --print --json)" fi ;; esac log "$LINENO: final mode before restart '$mode'" # The message and prompt and whatnot. echo -en "\x00prompt\x1f$prompt\n" echo -en "\x00message\x1f$message\n" echo "$mode" > "$modepath"