Skip to content
MikeSS8 edited this page Jan 13, 2025 · 2 revisions

Given a file too long to listen to all at once, record a time index from which to resume later.

cmus-bookmark.bash

#!/usr/bin/env bash

set -euo pipefail

bm="$HOME/.config/cmus/bookmarks"
[ -f "$bm" ] || touch "$bm"

usage() {
	printf "%s -<a|d|s> Add, Delete, or Seek to a bookmark of the file playing now." "$(basename "$0")"
	exit
}

[ $# -ne 1 ] && usage

cr() { cmus-remote -Q | grep "^$1 " | cut -f2- -d' '; }

delete-record() {
	local tmpfile=$(mktemp -p /tmp cmbm.XXXXXXXX)
	grep -vF "${1}$(printf '\t')" "$bm" > $tmpfile || true

	if [ "$(diff $tmpfile "$bm")" ]; then
		mv $tmpfile "$bm"
		[ $# -gt 1 ] && echo "Deleted bookmark" || true
	else
		rm $tmpfile
		[ $# -gt 1 ] && echo "No bookmark to delete" || true
	fi
}

main() {
	local file="$(cr file)"
	local pos

	case $1 in
	-a)
		delete-record "$file"
		[ -f "$file" ] || { printf "File %s not found; aborting" "$file"; exit 1; }

		pos=$(cr position)
		printf "%s\t%s\n" "$file" "$pos" >> "$bm"
		printf "Added bookmark at %s\n" "$pos" ;;
	-d)
		delete-record "$file" "with feedback" ;;
	-s)
		pos=$(grep -F "${file}$(printf '\t')" "$bm" | cut -f2) || { echo "No bookmark for this file"; exit 1; }
		cmus-remote --seek $pos
		printf "Seeking to %d\n" $pos ;;
	*)
		printf "Unknown argument: %s\n" "$1"
		usage ;;
	esac
}

main "$1"

SXHKDRC

Here's how you might use it, using a few programs:

  • sxhkd (a hotkey manager for X11)
  • dmenu
  • libnotify (probably from your package manager)

Aside from exercising the script, you can also enqueue files from the bookmark table.

mod4 + c ; d ; {a,s,d}
	cmus-bookmark -{a,s,d} | while read line; do notify-send "CMUS Bookmarks" "$line"; done
mod4 + c ; d ; e
	cut -f1 ~/.config/cmus/cmus-bookmarks | dmenu -l 20 | xargs -d'\n' cmus-remote -q

Clone this wiki locally