+ data
+ (seq-map
+ (lambda (i)
+ (let-alist i
+ (if (not limit)
+ (format "%s | [[https://musicbrainz.org/label/%s][%s]] |\n" .name .id .id)
+ (format "%s | %s | %s (%s%s) | [[https://musicbrainz.org/label/%s][%s]] |\n"
+ .score .name
+ (if .disambiguation .disambiguation "")
+ (if .life-span.begin
+ (format "%s " .life-span.begin) "")
+ (if .life-span.end
+ (format "—%s" .life-span.end)
+ "ongoing")
+ .id .id))))
+ .labels))))
+
+
+;; search -> musicbrainz-search-place
+(musicbrainz--defsearch-2 "place"
+ "%s | [[https://musicbrainz.org/place/%s][%s]] |\n"
+ (.name .id .id)
+ .places)
+
+;; search -> musicbrainz-search-recording
+(musicbrainz--defsearch-2 "recording"
+ "%s | %s, %s | [[https://musicbrainz.org/recording/%s][%s]] |\n"
+ (.score .title (musicbrainz--unwrap-0 .artist-credit) .id .id)
+ .recordings)
+
+;; search -> musicbrainz-search-release
+(musicbrainz--defsearch-2 "release"
+ "%s | %s | %s | [[https://musicbrainz.org/release/%s][%s]] |\n"
+ (.score .title (musicbrainz--unwrap-0 .artist-credit) .id .id)
+ .releases)
+
+;; search -> musicbrainz-search-release-group
+(musicbrainz--defsearch-2 "release-group"
+ "%s | %s | %s | [[https://musicbrainz.org/release-group/%s][%s]] |\n"
+ (.first-release-date .title .primary-type .id .id)
+ .release-groups)
+
+;; search -> musicbrainz-search-series
+(musicbrainz--defsearch-2 "series"
+ "%s | [[https://musicbrainz.org/series/%s][%s]] |\n"
+ (.name .id .id)
+ .series)
+
+;; search -> musicbrainz-search-work
+(musicbrainz--defsearch-2 "work"
+ "%s | %s | [[https://musicbrainz.org/work/%s][%s]] |\n"
+ (.score .title .id .id)
+ .works)
+
+;; search -> musicbrainz-search-url
+(musicbrainz--defsearch-2 "url"
+ "%s | [[%s][%s]] | [[https://musicbrainz.org/url/%s][%s]] |\n"
+ (.score .resource .resource .id .id)
+ .urls)
+
+
+;;; ;; ;; ; ; ; ; ; ;
+;;
+;; Lookups
+;; https://musicbrainz.org/doc/MusicBrainz_API#Lookups
+;;
+;;; ;; ;; ; ;
+
+;;;###autoload
+(defun musicbrainz-lookup (entity mbid &optional inc)
+ "Search (lookup not browse) MusicBrainz for ENTITY with MBID.
+Optionally add an INC list.
+
+Subqueries
+ /ws/2/area
+ /ws/2/artist recordings, releases, release-groups, works
+ /ws/2/collection user-collections (requires authentication)
+ /ws/2/event
+ /ws/2/genre
+ /ws/2/instrument
+ /ws/2/label releases
+ /ws/2/place
+ /ws/2/recording artists, releases, isrcs, url-rels
+ /ws/2/release artists, collections, labels, recordings, release-groups
+ /ws/2/release-group artists, releases
+ /ws/2/series
+ /ws/2/work
+ /ws/2/url"
+
+ (interactive "sMusicBrainz entity type: \nsMusicBrainz MBID for entity: ")
+ (message "MusicBrainz: lookup: %s/%s" entity mbid)
+ (if (and (musicbrainz-core-entity-p entity)
+ (musicbrainz-mbid-p mbid))
+ (let* ((add (if inc inc ""))
+ (response
+ (request-response-data
+ (request
+ (url-encode-url
+ (format "%s/%s/%s?inc=%s&fmt=json"
+ musicbrainz-api-url entity mbid add))
+ :type "GET"
+ :parser 'json-read
+ :sync t
+ :success (cl-function
+ (lambda (&key data &allow-other-keys)
+ (when data
+ (message "%s data: %s" entity mbid))))))))
+ (if (called-interactively-p 'any)
+ (message "%s" (pp response))
+ response))
+ (user-error "MusicBrainz: search requires a valid MBID and entity (i.e. one of %s)"
+ musicbrainz-entities-core)))
+
+;; relationship lookups
+
+(defun musicbrainz-relations (entity relation mbid)
+ "Lookup relationships of type RELATION to ENTITY with MBID."
+ ;; no sanity and/or error checks
+ (musicbrainz-lookup entity mbid (format "%s-rels" relation)))
+
+
+;; specific MBID lookup requests & subrequests (limited to 25 results?)
+
+(defmacro musicbrainz--deflookup-1 (name format-string format-args)
+ "Generate lookup function to format a single item.
+NAME FORMAT-STRING FORMAT-ARGS
+See listenbrainz--deformatter for details."
+ (let ((f (intern (concat "musicbrainz-lookup-" name)))
+ (doc "MusicBrainz lookup.")
+ (prompt (format "sMusicBrainz lookup %s by MBID: " name)))
+ `(defun ,f (mbid) ,doc
+ (interactive ,prompt)
+ (let ((response
+ (musicbrainz-lookup ,name mbid)))
+ (let-alist response
+ (format ,format-string ,@format-args))))))
+
+
+(defmacro musicbrainz--deflookup-2 (query subquery format-string format-args alist)
+ "Generate lookup function to format multiple items.
+QUERY SUBQUERY FORMAT-STRING FORMAT-ARGS ALIST
+See listenbrainz--deformatter for details."
+ (let ((f (intern (format "musicbrainz-lookup-%s-%s" query subquery)))
+ (doc "MusicBrainz lookup.")
+ (prompt (format "sMusicBrainz lookup %s %s by MBID: " query subquery)))
+ `(defun ,f (mbid) ,doc
+ (interactive ,prompt)
+ (let ((response
+ (musicbrainz-lookup ,query mbid ,subquery)))
+ (let-alist response
+ (seq-map
+ (lambda (i)
+ (let-alist i
+ (format ,format-string ,@format-args)))
+ ,alist))))))
+
+
+;; (defun musicbrainz-lookup-artist (mbid)
+;; "MusicBrainz lookup for artist with MBID."
+;; (let ((response
+;; (musicbrainz-lookup "artist" mbid)))
+;; (let-alist response
+;; (format "| %s | %s | %s | [[https://musicbrainz.org/artist/%s][%s]] |\n"
+;; .name .disambiguation .type .id .id))))
+
+
+;; (defun musicbrainz-lookup-artist-recordings (mbid)
+;; "MusicBrainz lookup for recordings from artist with MBID."
+;; (let ((response
+;; (musicbrainz-lookup "artist" mbid "recordings")))
+;; (let-alist response
+;; (seq-map
+;; (lambda (i)
+;; (let-alist i
+;; (format "%s | [[https://musicbrainz.org/recording/%s][%s]] |\n"
+;; .title .id .id)))
+;; .recordings))))
+
+
+;; lookup -> musicbrainz-lookup-area
+(musicbrainz--deflookup-1 "area"
+ "| %s | [[https://musicbrainz.org/area/%s][%s]] |\n"
+ (.name .id .id))
+
+;; lookup -> musicbrainz-lookup-artist
+(musicbrainz--deflookup-1 "artist"
+ "| %s | %s | %s | [[https://musicbrainz.org/artist/%s][%s]] |\n"
+ (.name .disambiguation .type .id .id))
+
+;; lookup -> musicbrainz-lookup-artist-recordings
+(musicbrainz--deflookup-2 "artist" "recordings"
+ "%s | [[https://musicbrainz.org/recording/%s][%s]] |\n"
+ (.title .id .id)
+ .recordings)
+
+;; lookup -> musicbrainz-lookup-artist-releases
+(musicbrainz--deflookup-2 "artist" "releases"
+ "%s | %s | %s | [[https://musicbrainz.org/release/%s][%s]] |\n"
+ (.date .title .packaging .id .id)
+ .releases)
+
+;; lookup -> musicbrainz-lookup-artist-release-groups
+(musicbrainz--deflookup-2 "artist" "release-groups"
+ "%s | %s | %s | [[https://musicbrainz.org/release-group/%s][%s]] |\n"
+ (.first-release-date .title .primary-type .id .id)
+ .release-groups)
+
+;; lookup -> musicbrainz-lookup-artist-works
+(musicbrainz--deflookup-2 "artist" "works"
+ " %s | [[https://musicbrainz.org/work/%s][%s]] |\n"
+ (.title .id .id)
+ .works)
+
+;; lookup -> musicbrainz-lookup-collection
+(musicbrainz--deflookup-1 "collection"
+ "| %s | [[https://musicbrainz.org/collection/%s][%s]] |\n"
+ (.name .id .id))
+
+;; lookup -> musicbrainz-lookup-collection-user-collections (requires authentication)
+(musicbrainz--deflookup-2 "collection" "user-collections"
+ " %s | [[https://musicbrainz.org/collection/%s][%s]] |\n"
+ (.name .id .id)
+ .collection)
+
+;; lookup -> musicbrainz-lookup-event
+(musicbrainz--deflookup-1 "event"
+ "| %s | [[https://musicbrainz.org/event/%s][%s]] |\n"
+ (.name .id .id))
+
+;; lookup -> musicbrainz-lookup-genre
+(musicbrainz--deflookup-1 "genre"
+ "| %s | [[https://musicbrainz.org/genre/%s][%s]] |\n"
+ (.name .id .id))
+
+;; lookup -> musicbrainz-lookup-instrument
+(musicbrainz--deflookup-1 "instrument"
+ "| %s | %s | [[https://musicbrainz.org/instrument/%s][%s]] |\n"
+ (.name .type .id .id))
+
+;; lookup -> musicbrainz-lookup-label
+(musicbrainz--deflookup-1 "label"
+ "| %s | %s | [[https://musicbrainz.org/label/%s][%s]] |\n"
+ (.name .disambiguation .id .id))
+
+
+;; lookup -> musicbrainz-lookup-label-releases
+(musicbrainz--deflookup-2 "label" "releases"
+ "%s | %s | [[https://musicbrainz.org/release/%s][%s]] |\n"
+ (.date .title .id .id)
+ .releases)
+
+;; lookup -> musicbrainz-lookup-place
+(musicbrainz--deflookup-1 "place"
+ "| %s | [[https://musicbrainz.org/place/%s][%s]] |\n"
+ (.name .id .id))
+
+;; lookup -> musicbrainz-lookup-recording
+(musicbrainz--deflookup-1 "recording"
+ "| %s | %s | [[https://musicbrainz.org/recording/%s][%s]] |\n"
+ (.first-release-date .title .id .id))
+
+
+;; lookup -> musicbrainz-lookup-recording-artists
+(musicbrainz--deflookup-2 "recording" "artists"
+ "%s | [[https://musicbrainz.org/artist/%s][%s]] |\n"
+ (.artist.name .artist.id .artist.id)
+ .artist-credit)
+
+;; lookup -> musicbrainz-lookup-recording-releases
+(musicbrainz--deflookup-2 "recording" "releases"
+ "%s | %s | %s | [[https://musicbrainz.org/release/%s][%s]] |\n"
+ (.date .title .packaging .id .id)
+ .releases)
+
+;; lookup -> musicbrainz-lookup-recording-isrcs
+(musicbrainz--deflookup-2 "recording" "isrcs"
+ "%s | [[https://musicbrainz.org/isrc/%s][%s]] |\n"
+ (.name .id .id)
+ .isrcs)
+
+;; lookup -> musicbrainz-lookup-recording-url-rels
+(musicbrainz--deflookup-2 "recording" "url-rels"
+ "%s | [[https://musicbrainz.org/recording/%s][%s]] |\n"
+ (.name .id .id)
+ .relations)
+
+;; lookup -> musicbrainz-lookup-release
+(musicbrainz--deflookup-1 "release"
+ "| %s | %s | %s | [[https://musicbrainz.org/release/%s][%s]] |\n"
+ (.date .title .packaging .id .id))
+
+;; lookup -> musicbrainz-lookup-release-artists
+(musicbrainz--deflookup-2 "release" "artists"
+ "%s | [[https://musicbrainz.org/artist/%s][%s]] |\n"
+ (.artist.name .artist.id .artist.id)
+ .artist-credit)
+
+;; lookup -> musicbrainz-lookup-release-collections
+
+;; lookup -> musicbrainz-lookup-release-labels
+
+;; lookup -> musicbrainz-lookup-release-recordings
+
+;; lookup -> musicbrainz-lookup-release-release-groups
+
+;; lookup -> musicbrainz-lookup-release-group
+(musicbrainz--deflookup-1 "release-group"
+ "| %s | %s | %s | [[https://musicbrainz.org/release-group/%s][%s]] |\n"
+ (.first-release-date .title .primary-type .id .id))
+
+;; lookup -> musicbrainz-lookup-release-group-artists
+(musicbrainz--deflookup-2 "release-group" "artists"
+ "%s | [[https://musicbrainz.org/artist/%s][%s]] |\n"
+ (.artist.name .artist.id .artist.id)
+ .artist-credit)
+
+;; lookup -> musicbrainz-lookup-release-group-releases
+
+;; lookup -> musicbrainz-lookup-series
+(musicbrainz--deflookup-1 "series"
+ "| %s | [[https://musicbrainz.org/series/%s][%s]] |\n"
+ (.title .id .id))
+
+;; lookup -> musicbrainz-lookup-work
+(musicbrainz--deflookup-1 "work"
+ "| %s | [[https://musicbrainz.org/work/%s][%s]] |\n"
+ (.title .id .id))
+
+;; lookup -> musicbrainz-lookup-url
+(musicbrainz--deflookup-1 "url"
+ "| %s | [[https://musicbrainz.org/url/%s][%s]] |\n"
+ (.name .id .id))