Skip to content

Instantly share code, notes, and snippets.

@darrylhebbes
Created April 29, 2016 20:33
Show Gist options
  • Select an option

  • Save darrylhebbes/878bbc5dff183f043ea422dee9d742df to your computer and use it in GitHub Desktop.

Select an option

Save darrylhebbes/878bbc5dff183f043ea422dee9d742df to your computer and use it in GitHub Desktop.
marker-visit.el --- navigate through a buffer's marks in order in Emacs
;;; marker-visit.el --- navigate through a buffer's marks in order
;; Copyright (C) 2001 Benjamin Rutt
;;
;; Maintainer: Benjamin Rutt <brutt@bloomington.in.us>
;; Version: 1.1
;; This file is not part of GNU Emacs.
;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published
;; by the Free Software Foundation; either version 2, or (at your
;; option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, send e-mail to
;; this program's maintainer or write to the Free Software Foundation,
;; Inc., 59 Temple Place, Suite 330; Boston, MA 02111-1307, USA.
;;; Commentary:
;; This file provides a simple way to navigate among marks in a
;; buffer. C-u C-SPC is similar, but takes you haphazardly around the
;; buffer. Setting bookmarks is a lot of extra work if you just want
;; to jump around your buffer quickly; plus, you have to come up with
;; a name for every bookmark.
;; All the marks you've left while editing a buffer serve as bread
;; crumb trails of areas in the buffer you've edited. It is
;; convenient to navigate back and forth among these marks in order.
;; This file provides two methods to do just that, marker-visit-prev
;; and marker-visit-next. These two functions will take you, from
;; point, to the nearest mark in either direction. The function
;; marker-visit-truncate-mark-ring will truncate the mark ring.
;; The marks you can visit in a buffer consist of: "the mark" plus the
;; contents of the mark-ring.
;;; Usage:
;; put this file in your load-path and add the line
;;
;; (require 'marker-visit)
;;
;; to your ~/.emacs file.
;;
;; This package is most useful when some easy-to-press keys are bound
;; to the functions marker-visit-prev and marker-visit-next. See C-h
;; i m Emacs RET m Key Bindings RET for info on emacs key bindings.
;;; History:
;; 1.0 -> 1.1 Incorporated patch from Colin Walters to make the code
;; consistent with elisp code conventions mentioned in
;; (Info-goto-node "(elisp) Coding Conventions").
;;; Code:
;;utility remove-dupes function
(defun marker-visit-remove-dupes (ls)
(cond
((null ls) '())
((member (car ls) (cdr ls)) (marker-visit-remove-dupes (cdr ls)))
(t (cons (car ls) (marker-visit-remove-dupes (cdr ls))))))
;;create a sorted list of marks, including the point as mark, the
;;mark, and the contents of the mark-ring.
(defun marker-visit-get-sorted-mark-set (current-point-mark)
(marker-visit-remove-dupes
(sort
(append (cons current-point-mark
(if (mark-marker) (list (mark-marker)) nil))
(mapcar (lambda (id) id) mark-ring))
(lambda (a b) (< a b)))))
(defun marker-visit-no-markers-p ()
(and (null mark-ring)
(or (not (mark-marker))
(not (marker-position (mark-marker))))))
(defun marker-visit-warn (error-message)
(message error-message)
(beep))
;;;###autoload
(defun marker-visit-prev ()
"From point, visit the nearest mark earlier in the buffer."
(interactive)
(if (marker-visit-no-markers-p)
(marker-visit-warn "Mark does not point anywhere")
(let* ((current-point-mark (point-marker))
(sorted-marks (marker-visit-get-sorted-mark-set current-point-mark))
(dest-mark nil))
(while (not (equal current-point-mark (car sorted-marks)))
(setq dest-mark (car sorted-marks))
(setq sorted-marks (cdr sorted-marks)))
(if dest-mark
(goto-char dest-mark)
(marker-visit-warn "No previous mark to visit")))))
;;;###autoload
(defun marker-visit-next ()
"From point, visit the nearest mark later in the buffer."
(interactive)
(if (marker-visit-no-markers-p)
(marker-visit-warn "Mark does not point anywhere")
(let* ((current-point-mark (point-marker))
(sorted-marks (marker-visit-get-sorted-mark-set current-point-mark))
(dest-mark nil)
(done nil))
(while (not done)
(if (equal current-point-mark (car sorted-marks))
(progn
(setq dest-mark (cadr sorted-marks))
(setq done t))
(setq sorted-marks (cdr sorted-marks))))
(if dest-mark
(goto-char dest-mark)
(marker-visit-warn "No next mark to visit")))))
;;;###autoload
(defun marker-visit-truncate-mark-ring ()
"Truncate the `mark-ring'."
(interactive)
(setq mark-ring nil))
(provide 'marker-visit)
;; marker-visit.el ends here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment