#!/bin/fish # fuzzy bookmark opener, read links from `~/.config/bookmarks.md` to fzf/dmenu and then open selected links with # default browser # `~/.config/bookmarks.md` sample: # ```markdown # # email # - [hotmail](https://hotmail.com) # - [gmail](https://gmail.com) # ``` set -q BOOKMARK_PATH; or set BOOKMARK_PATH $HOME/Documents/bookmarks.md if set -q BOOKMARK_SEARCHER set BOOKMARK_SEARCHER (string split ' ' $BOOKMARK_SEARCHER) else set BOOKMARK_SEARCHER fzf --layout reverse end function _help echo "Organize your bookmark with markdown" echo echo "Usage bm [command ...args]" echo echo "commands:" echo ' list [query]' echo ' open ' echo echo 'examples:' echo ' bm list "# daily" "# emails" list all links under daily/emails folder' echo ' bm list "reddit" "github" list all links contains specified keywords' echo ' bm open "# daily" "# emails" open all links under daily/emails folder' echo ' bm open "reddit" "github" open all links contains specified keywords' echo ' bm search with $BOOKMARK_SEARCHER and then open selected' end function list set -e categories set -e names for arg in $argv if string match -q '#*' $arg set --append categories $arg else set --append names $arg end end _filter_category $categories < $BOOKMARK_PATH | _filter_name $names end function open if not count $argv &>/dev/null _search else list $argv | _open_urls end end function update set url (xsel -ob) if ! string match 'http*' $url echo "no url found on clipboard" exit 1 end set query (sed -r '/^(#.*|\s*)$/d' $BOOKMARK_PATH | $BOOKMARK_SEARCHER) echo url: $url echo query: $query mv $BOOKMARK_PATH $BOOKMARK_PATH.bak awk '$0 == "'$query'" { sub(/\(http.*\)/, "('$url')") } { print }' $BOOKMARK_PATH.bak > $BOOKMARK_PATH end function _filter_category if not count $argv >/dev/null cat - return end set categories $argv set -e output_indent while read LINE if set heading (string match -r '^(#+) (.*)$' $LINE) set heading_indent (string length $heading[2]) if test -z "$output_indent" contains $LINE $categories && set output_indent $heading_indent else test "$heading_indent" -le "$output_indent" && set -e output_indent end end if test -n "$output_indent" echo $LINE end end end function _filter_name if not count $argv >/dev/null cat - return end set NAMES_PATTERN (string join '|' $argv) while read LINE if not string match -q -r $NAMES_PATTERN $LINE continue end echo $LINE end end function _open_urls set LINK_PATTERN '\[(.*?)\]\((.*?)\)' while read LINE if set link (string match -r $LINK_PATTERN $LINE) echo '' | x-open $link[3] &>/dev/null & disown sleep 0.1 end end end function _search set query (sed -r '/^\s*$/d' $BOOKMARK_PATH | $BOOKMARK_SEARCHER) test -z "$query" && return if string match '#*' $query open $query else echo $query | _open_urls end end switch $argv[1] case list open help update $argv[1..-1] case '*' _search end