Skip to content

Instantly share code, notes, and snippets.

@adegoodyer
Created August 1, 2025 10:30
Show Gist options
  • Save adegoodyer/7f92fe7ffdafc1743d5a6e8480d51db7 to your computer and use it in GitHub Desktop.
Save adegoodyer/7f92fe7ffdafc1743d5a6e8480d51db7 to your computer and use it in GitHub Desktop.
bm - CLI bookmarks manager
#!/bin/bash
#
# Author: Ade Goodyer
# Date: 21st August 2023
# Description: Fuzzy search browser bookmarks from terminal and open
# Notes:
#
# Usage:
#
set -o pipefail
set -o errexit
set -o nounset
# Constants
BOOKMARKS_PATH="${HOME}/src/github.com/adegoodyer/workbench/scripts/"
OS_TYPE="$(uname)"
BOOKMARKS_FILE="${BOOKMARKS_PATH}generated/bookmarks/bookmarks-chrome.txt"
# ensure the output directory exists
mkdir -p "${BOOKMARKS_PATH}generated/bookmarks"
# Check dependencies
check_dependency() {
local cmd="$1"
local message="$2"
if ! command -v "$cmd" &>/dev/null; then
echo "$message"
exit 1
fi
}
# Extract bookmarks using jq
extract_bookmarks() {
local os_type="$1"
case "$os_type" in
"Linux")
local bookmarks_path="${HOME}/.config/google-chrome/Default/Bookmarks"
;;
"Darwin")
local bookmarks_path="${HOME}/Library/Application Support/Google/Chrome/Default/Bookmarks"
;;
*)
echo "Unsupported OS type: $os_type"
exit 2
;;
esac
[[ ! -f "$bookmarks_path" ]] && echo "Bookmarks file not found." && exit 3
jq -r '.. | objects | select(has("url")) | "\(.name) \(.url)"' "$bookmarks_path" >"$BOOKMARKS_FILE"
# Count number of bookmarks in bookmarks-chrome.txt and display result
bookmark_count=$(wc -l <"${BOOKMARKS_PATH}/generated/bookmarks/bookmarks-chrome.txt" | xargs)
echo "$bookmark_count Bookmarks exported to $BOOKMARKS_FILE"
}
# Launch fzf interface
launch_fzf() {
local keep_open="$1"
local open_command
case "$OSTYPE" in
"darwin"*) open_command="open" ;;
"linux"*) open_command="xdg-open" ;;
esac
local enter_command="enter:execute-silent(${open_command} {-1})"
[[ "$keep_open" == "false" ]] && enter_command="${enter_command}+abort" || enter_command="${enter_command}+clear-query"
cat "$BOOKMARKS_FILE" | fzf \
--border=rounded \
--margin=5% \
--prompt="Search Bookmarks > " \
--with-nth='1..-2' \
--bind="${enter_command}" \
--preview='echo {-1}' \
--preview-window='up,1'
}
# Check dependencies
check_dependency "jq" "This script requires 'jq'. Please install it first."
check_dependency "fzf" "fzf is not installed."
# Extract bookmarks
extract_bookmarks "$OS_TYPE"
# Process command-line arguments
keep_open=false
while [[ "$#" -gt 0 ]]; do
case $1 in
-k | --keep-open) keep_open=true ;;
*)
echo "Unknown parameter passed: $1"
exit 1
;;
esac
shift
done
# Launch fzf interface
launch_fzf "$keep_open"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment