SHARE
TWEET

Untitled

a guest Feb 6th, 2017 77 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (defvar region-history (make-ring region-history-size))
  2.  
  3. (cl-defstruct region-history-entry buffer beg end)
  4.  
  5. (defun region-history-set-size (symbol value)
  6.   (set-default symbol value)
  7.   (region-history-extend-if-necessary))
  8.  
  9. (defun region-history-extend-if-necessary ()
  10.   (let ((current-size (ring-size region-history)))
  11.     (when (> region-history-size
  12.              (ring-size region-history))
  13.       (ring-extend region-history
  14.                    (- region-history-size current-size)))))
  15.  
  16. (defcustom region-history-size 50
  17.   "Maximum number of entries in transient mark history."
  18.   :type 'number
  19.   :set 'region-history-set-size)
  20.  
  21. (defun region-history-insert (beg end)
  22.   (unless (markerp beg)
  23.     (error "First argument must be a marker, %s provided" (type-of (point-marker))))
  24.   (unless (markerp end)
  25.     (error "Second argument must be a marker, %s provided" (type-of (point-marker))))
  26.   (let ((buffer (marker-buffer beg)))
  27.     (unless (eq (marker-buffer end) buffer)
  28.       (error "Markers do not belong to the same buffer"))
  29.     (ring-insert region-history
  30.                  (make-region-history-entry
  31.                   :buffer buffer
  32.                   :beg beg
  33.                   :end end))))
  34.  
  35. (defun region-history-is-entry-valid (entry)
  36.   (and (buffer-live-p (region-history-entry-buffer entry))
  37.        (not (eq (marker-position (region-history-entry-beg entry))
  38.                 (marker-position (region-history-entry-end entry))))))
  39.  
  40. (defun region-history-prev ()
  41.   (interactive)
  42.   (message "%S" (ring-length region-history))
  43.   (unless (ring-empty-p region-history)
  44.    (with-region-history-mode-disabled
  45.      (let ((entry (ring-remove region-history 0)))
  46.        (if (region-history-is-entry-valid entry)
  47.            (progn
  48.              (ring-insert-at-beginning region-history entry)
  49.              (switch-to-buffer (region-history-entry-buffer entry))
  50.              (set-mark (region-history-entry-beg entry))
  51.              (goto-char (region-history-entry-end entry)))
  52.          (region-history-prev))))))
  53.  
  54. (defun region-history-next ()
  55.   (interactive)
  56.   (unless (ring-empty-p region-history)
  57.    (with-region-history-mode-disabled
  58.      (let ((entry (ring-remove region-history)))
  59.        (if (region-history-is-entry-valid entry)
  60.            (progn
  61.              (ring-insert region-history entry)
  62.              (switch-to-buffer (region-history-entry-buffer entry))
  63.              (set-mark (region-history-entry-beg entry))
  64.              (goto-char (region-history-entry-end entry)))
  65.          (region-history-next))))))
  66.  
  67. (defmacro with-region-history-mode-disabled (&rest body)
  68.   "Evaluate body with region-history-mode disabled."
  69.   (declare (indent 0) (debug t))
  70.   `(unwind-protect
  71.         (progn (region-history-mode -1)
  72.                ,@body)
  73.      (region-history-mode 1)))
  74.  
  75. (defun region-history-reset ()
  76.   (interactive)
  77.   (setq region-history (make-ring region-history-size)))
  78.  
  79. (defun region-history-deactivate-mark-hook ()
  80.   (region-history-insert (mark-marker) (point-marker)))
  81.  
  82. (defvar region-history-mode-)
  83.  
  84. (define-minor-mode region-history-mode
  85.     "Minor mode for saving and navigating history of selected regions."
  86.   :global t
  87.   :keymap
  88.   (easy-mmode-define-keymap
  89.    (list (cons (kbd "M-p") 'region-history-prev)
  90.          (cons (kbd "M-n") 'region-history-next)))
  91.   (if region-history-mode
  92.       (add-hook 'deactivate-mark-hook 'region-history-deactivate-mark-hook)
  93.     (remove-hook 'deactivate-mark-hook 'region-history-deactivate-mark-hook)))
RAW Paste Data
Top