Bits and bytes of code
Bytes is my collection of short-form posts, tips, and things I learn as I build software.
Bytes is my collection of short-form posts, tips, and things I learn as I build software.
Ever wanted to open your browser bookmarks from the terminal? Maybe not, but if you have a lot of bookmarks and you also happen to spend a lot of time in the terminal, this can be a great way to quickly launch your bookmarks straight from the terminal.
The bash script for doing this is actually fairly beefy, but I’ve broken into two parts:
The main reason for splitting the script into these two parts is so that it can support multiple browsers. All it takes to support a different browser is to create a shell script for that browser that parses into the normalized structure, then plug that into the main script and viola.
Let’s get started with the script to normalize the Chrome bookmarks into a
structure that our main script can read. We are using
jq extensively in this entire process
including most importantly parsing the Chrome bookmarks.
I won’t explain every detail, but in essence we are collapsing the recursive nature of Chrome bookmarks into a flat list and creating a slug for each entry (e.g. “My bookmark” becomes “my-bookmark”).
#!/usr/bin/env bash
path="$HOME/Library/Application Support/Google/Chrome/Default/Bookmarks"
jq '.roots
| to_entries[].value
| recurse(.children[]?)
| select(.type == "url")
| {
name,
url,
slug: .name
| gsub("'\''"; "")
| gsub("[^a-zA-Z0-9]"; "-")
| gsub("-{2,}"; "-")
| gsub("(^-|-$)"; "")
| ascii_downcase
}
' "$path"Now that we have the script to read and normalize our Chrome bookmarks, we
can create our main script to fuzzy-find and open our bookmarks. If called
with an argument, the script will filter the results based on which results
start with the given string and either open
fzf if there are multiple results, or
open the bookmark if it is an exact match.
#!/usr/bin/env bash
list_bookmarks() {
chrome-bookmarks
}
filter_bookmarks() {
jq -c --arg key "$1" --arg value "$2" 'select(.[$key] | startswith($value))'
}
find_bookmark() {
jq -c --arg key "$1" --arg value "$2
Here are some examples of how we might call our script in our terminal:
bm
bm my-bookmarkAs I mentioned, supporting other browsers is fairly trivial, one simply needs to create a shell script for the desired browser. I’ve created a version for the Arc browser which you can view in my dotfiles.
The script is setup in a way that makes shell completions very simple to
add. Simply add the --json flag along with jq to format the results in
a way that works for your shell’s completion mechanism.
Here is an example for the Fish shell:
function __bm_complete_bookmarks
bm --json | jq -r '.slug'
end
complete -c bm -f -n __fish_use_subcommand -a '(__bm_complete_bookmarks)'