JustToThePoint English Website Version
JustToThePoint en español

Rofi Bookmark Module: Accessing Buku

To err is human, to blame it on someone else is even more human, Jacob’s Law

image info

Introduction

This is the next entry in my series of Rofi modules. While the previous scripts focused on launching applications, searching the web, or expanding text, this module provides a seamless interface for managing and accessing bookmarks via the command-line bookmark manager Buku.

Buku is a powerful, bookmark-agnostic tool that stores URLs in a database. This bash script, _buku, bridges the gap between the command line and your graphical workflow. It queries the Buku database, formats the titles and tags for display in Rofi using awk, and allows you to fuzzy search and open a URL in your browser without ever taking your hands off the keyboard.

Installing and Configuring Buku

Before using the Rofi module, you need to set up your bookmark database. This bash script removes any existing database and populates it with a curated set of starter bookmarks. Run this once before using the Rofi module.

#!/usr/bin/env bash
# Shebang: instructs the kernel to execute this script with `bash`.
# Using `env` locates bash in the user's PATH for portability.

set -euo pipefail
# Strict error handling:
#   -e       : Exit immediately if any command returns a non‑zero status.
#   -u       : Treat references to unset variables as an error.
#   -o pipefail : A pipeline fails if any command in it fails, not just the last.
# This ensures the script stops on any unexpected condition.

DB_PATH="$HOME/.local/share/buku/bookmarks.db"
# The default location of the Buku SQLite database.
# `$HOME` expands to the current user's home directory.

echo "Cleaning buku database..."
rm -f "$DB_PATH"
# Remove the database file if it exists.
# `-f` prevents an error if the file is missing and forces removal without prompt.

echo "Rebuilding bookmarks..."

# Helper function to add a bookmark with a consistent signature.
# It abstracts the `buku` command line, making the main code more readable.
add_bookmark() {
  local url="$1"    # First argument: the URL to bookmark
  local tags="$2"   # Second argument: comma‑separated tags
  local title="$3"  # Third argument: custom title

  # `buku -a` adds a new bookmark.
  # `--tag` assigns one or more tags.
  # `--title` sets a user‑friendly title (otherwise Buku would fetch the page title).
  buku -a "$url" --tag "$tags" --title "$title"
}

# Add a curated set of bookmarks.
# Each call passes URL, tags, and a descriptive title.
add_bookmark "https://www.perplexity.ai/" "ai,search" "Perplexity"
add_bookmark "https://chatgpt.com/" "ai,chat" "ChatGPT"
# [...] (additional bookmarks would follow the same pattern)

echo "Done!"

The Rofi Integration

This function defines the core logic of the module. It handles the retrieval of all Buku bookmarks, presents them in a Rofi menu, and opens the selected URL in Google Chrome.

# Helper function to launch a command in the background.
# The parentheses create a subshell, detaching the command from the current
# process group. The `&` sends it to the background immediately.
# This allows the calling script to continue without waiting for the browser.
_launch() {
  ( "$@" & )
}
# ── TOOLS: Buku bookmarks ─────────────────────────────────────────────────────
#
# Flow:
#   1. `buku --np --print` lists all bookmarks as:
#        1. Title  [Tags: ...]
#           > https://url
#        2. ...
#   2. We reformat each entry to "index  title — url" on a single line
#      using awk so rofi can display and search both title and URL.
#   3. User picks one entry; we extract the URL and open it with Chrome.
#
# Requires: buku
#
_buku() {
  # ── Step 1: Fetch all bookmarks from Buku ──────────────────────────────────
  # `--nostdin` prevents Buku from reading standard input (important in rofi scripts).
  # `--print` lists all bookmarks without interactive mode.
  # `--format 5` outputs tab‑separated fields: index \t title \t tags
  # Any errors (e.g., empty database) are sent to /dev/null.
  local raw
  raw=$(buku --nostdin --print --format 5 2>/dev/null)

  # If the output is empty, there are no bookmarks.
  # Show a desktop notification and exit gracefully.
  if [[ -z "$raw" ]]; then
    _notify "Buku" "No bookmarks found."
    return 0
  fi

  # ── Step 2: Reformat for Rofi display ───────────────────────────────────────
  # The raw data is a set of tab‑separated lines. We use `awk` to produce a
  # clean, single‑line representation for each bookmark that Rofi can display
  # and search. The format becomes:
  #    index  title                                    [tags]
  #
  # `awk -F'\t'` sets the field separator to a tab.
  # `printf "%4s  %-45s  [%s]\n", $1, $2, $3` creates a fixed‑width layout:
  #   - `%4s`   : right‑aligned index, width 4.
  #   - `%-45s` : left‑aligned title, width 45 (truncated/padded).
  #   - `[%s]`  : tags wrapped in brackets.
  # The result is a tidy, scannable menu.
  local formatted
  formatted=$(echo "$raw" | awk -F'\t' '{
    printf "%4s  %-45s  [%s]\n", $1, $2, $3
  }')

  # ── Step 3: Show Rofi menu and capture selection ───────────────────────────
  # The variable `$ROFI` contains the rofi command.
  # Flags used:
  #   -dmenu    : Read options from stdin, output the selected line.
  #   -i        : Case‑insensitive filtering.
  #   -p " buku": Prompt text in the entry box.
  #   -format s : Output the selected string exactly as displayed.
  #   -theme, -font : Apply custom styling.
  #   -lines 15 : Show up to 15 entries (scrollable if more exist).
  local pick
  pick=$(echo "$formatted" | $ROFI \
    -dmenu \
    -i \
    -p "  buku" \
    -format s \
    -theme "$THEME" -font "$FONT" \
    -lines 15)

  # If the user pressed Escape or the selection was empty, exit quietly.
  [[ -z "$pick" ]] && return 0

  # ── Step 4: Extract the bookmark index from the selected line ──────────────
  # The first field of the formatted line is the numeric index.
  # We use `awk` again to pull it out.
  local idx
  idx=$(echo "$pick" | awk '{print $1}')
  [[ -z "$idx" ]] && return 0 # Safety check; should not happen with valid input.

  # ── Step 5: Retrieve the URL for that index from Buku ──────────────────────
  # `--print "$idx"` outputs only the bookmark with the given index.
  # `--format 1` returns tab‑separated: index \t url
  # `head -1` ensures we only take the first line (a little paranoid, but quite safe).
  # `cut -f2` extracts the second field (the URL).
  # Errors (e.g., missing index) are sent to /dev/null.
  local url
  url=$(buku --nostdin --print "$idx" --format 1 2>/dev/null | head -1 | cut -f2)
  [[ -z "$url" ]] && return 0

  # ── Step 6: Open the URL in Google Chrome ──────────────────────────────────
  # `_launch` runs the command in a detached subshell so the browser opens
  # and the script continues (or exits) immediately.
  _launch google-chrome-stable "$url"
}
Bitcoin donation

JustToThePoint Copyright © 2011 - 2026 Anawim. ALL RIGHTS RESERVED. Bilingual e-books, articles, and videos to help your child and your entire family succeed, develop a healthy lifestyle, and have a lot of fun. Social Issues, Join us.

This website uses cookies to improve your navigation experience.
By continuing, you are consenting to our use of cookies, in accordance with our Cookies Policy and Website Terms and Conditions of use.