Once I have pushed a mark into the ring with C-c %
, org-mark-ring-push
and have cycled through the ring with C-c &
, org-mark-ring-goto
, how can I remove a mark that I don't need anymore? I tried C-u C-u
set-mark-command-repeat-pop
but nothing happens.
1 Answer
org-mark-ring-goto
is buggy in the current org-mode master as of 2017-12-22.
All markers in the mark ring are set to nil
at the beginning of an emacs session and org-mark-ring-goto
does not treat this case correctly.
If org-mark-ring-goto
is corrected deleting the current mark is a piece of cake. One can just set the mark at org-mark-ring-last-goto
to nil
.
Here is a corrected version of org-mark-ring-goto
with a corresponding possible org-mark-ring-delete
:
(require 'subr-x)
(defun org-mark-ring-marker-p (ring-pos)
"Return marker at RING-POS if it has a non-nil buffer
and nil otherwise."
(when (consp ring-pos)
(let* ((marker (car ring-pos))
buffer)
(when (and (markerp marker)
(buffer-live-p (setq buffer (marker-buffer marker))))
marker))))
(defun org-mark-ring-next (&optional ring-pos n)
"Find next `org-mark-ring' position with valid marker starting at
`org-mark-ring-last-goto' if non-nil or `org-mark-ring' otherwise.
With non-nil RING-POS start there.
Return nil if all markers have no buffer."
(unless n (setq n 1))
(let (marker
(pos (setq ring-pos (or ring-pos org-mark-ring-last-goto org-mark-ring))))
(while (and
(or (null (setq marker (org-mark-ring-marker-p pos)))
(prog1 (> n 0) (cl-decf n)))
(null (eq ring-pos
(setq pos (cdr pos))))))
(and marker pos)))
(defun org-mark-ring-goto-ad (&optional n)
"Jump to N -th previous position in `org-mark-ring'."
(let ((p (if (eq last-command this-command)
(org-mark-ring-next nil n)
(org-mark-ring-next org-mark-ring 0))))
(if p
(let ((m (car p)))
(setq org-mark-ring-last-goto p)
(pop-to-buffer-same-window (marker-buffer m))
(goto-char m)
(when (or (org-invisible-p) (org-invisible-p2)) (org-show-context 'mark-goto)))
(message "There are not as many as %d marks in `org-mark-ring'." n))))
(advice-add #'org-mark-ring-goto :override #'org-mark-ring-goto-ad)
(defun org-mark-ring-delete ()
"Delete the mark pointed to by `org-mark-ring-last-goto' in `org-mark-ring'.
That is mark holding the position reached by the last `org-mark-ring-goto'."
(interactive)
(when (org-mark-ring-marker-p org-mark-ring-last-goto)
(set-marker (car org-mark-ring-last-goto) nil)))
org-mark-ring
in Orgmode.