anchor.diff:                        (when file
                           (deserialize-bookmarks file)))))
             (when data
  -            (echo "Loading ~a bookmarks." (length data))
  +            (echo "Loading ~a bookmarks from ~a."
  +                  (length data)
  +                  (bookmarks-path *interface*))
               (setf (slot-value *interface* 'bookmarks-data) data)))
         (error (c)
           (echo-warning "Failed to load bookmarks from ~a: ~a" path c)))))
  
positive.code:                         :direction :output
                          :if-does-not-exist :create
                          :if-exists :supersede)
      ;; TODO: Sort by customizable function, ignore protocol by default.
      (write-string "(" file)
      (dolist (entry (bookmarks-data *interface*))
        (write-char #\newline file)
        (serialize-object entry file))
      (write-char #\newline file)
      (write-string ")" file)))
  
  (defun restore-sexp-bookmarks ()
    "Restore the bookmarks from the interface `bookmarks-path'."
  
negative.code:               (format nil " (~{~a~^, ~})" (tags entry))
                "")))
  
  (defun url-sans-protocol (url)
    (let ((uri (quri:uri url)))
      (str:concat (quri:uri-host uri)
                  (quri:uri-path uri))))
  
  (defun equal-url (url1 url2)
    "URLs are equal if the hosts and the paths are equal.
  In particular, we ignore the protocol (e.g. HTTP or HTTPS does not matter)."
    (string= (url-sans-protocol url1) (url-sans-protocol url2)))
  
  (defmethod equals ((e1 bookmark-entry) (e2 bookmark-entry))
    "Entries are equal if the hosts and the paths are equal.
  In particular, we ignore the protocol (e.g. HTTP or HTTPS does not matter)."
    (equal-url (url e1) (url e2)))
  
  (defun bookmark-add (url &key title tags)
    (unless (or (str:emptyp url)
  