On Thu, Nov 21, 2024 at 12:32 PM Nikolay Kudryavtsev <nikolay.kudryavtsev@gmail.com> wrote:
I still don't understand why do you need more than one mark for your use
case?

You are comparing two sexps. You put the foo buffer sexp position into
the mark ring. Now you go to the bar buffer and select the sexp there.
Why do you need to put the bar into the mark ring? Why do you need the
second foo mark? You can just use the first(and only) foo mark and be
done with it.

Er...yeah.  That's exactly what I want to do.  Not sure how I gave a different impression.

Here's what I have now, minus some defensive coding to keep it short:

    ;; Helper function:
    (defun write-sexp-at (pos dest-file)
      (write-region pos (save-excursion (goto-char pos) (forward-sexp) (point)) dest-file))

    (defun json-diff ()
      (interactive)
      (let ((file-a (make-temp-file "json-diff"))
            (file-b (make-temp-file "json-diff")))
        (with-current-buffer (marker-buffer last-global-mark)
          (write-sexp-at (marker-position last-global-mark) file-a))
        (write-sexp-at (point) file-b)
        (shell-command (format "~/bin/json-diff %s %s" file-a file-b))))

Originally I tried using (car global-mark-ring) instead of last-global-mark, but that doesn't work, per my original bug report.  I also tried saying (mark t) instead of (marker-position (car global-mark-ring)).  That would have returned the correct position, but it doesn't matter because (marker-buffer (car global-mark-ring)) can't be relied upon to return the right buffer.