Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (defvar region-history (make-ring region-history-size))
- (cl-defstruct region-history-entry buffer beg end)
- (defun region-history-set-size (symbol value)
- (set-default symbol value)
- (region-history-extend-if-necessary))
- (defun region-history-extend-if-necessary ()
- (let ((current-size (ring-size region-history)))
- (when (> region-history-size
- (ring-size region-history))
- (ring-extend region-history
- (- region-history-size current-size)))))
- (defcustom region-history-size 50
- "Maximum number of entries in transient mark history."
- :type 'number
- :set 'region-history-set-size)
- (defun region-history-insert (beg end)
- (unless (markerp beg)
- (error "First argument must be a marker, %s provided" (type-of (point-marker))))
- (unless (markerp end)
- (error "Second argument must be a marker, %s provided" (type-of (point-marker))))
- (let ((buffer (marker-buffer beg)))
- (unless (eq (marker-buffer end) buffer)
- (error "Markers do not belong to the same buffer"))
- (ring-insert region-history
- (make-region-history-entry
- :buffer buffer
- :beg beg
- :end end))))
- (defun region-history-is-entry-valid (entry)
- (and (buffer-live-p (region-history-entry-buffer entry))
- (not (eq (marker-position (region-history-entry-beg entry))
- (marker-position (region-history-entry-end entry))))))
- (defun region-history-prev ()
- (interactive)
- (message "%S" (ring-length region-history))
- (unless (ring-empty-p region-history)
- (with-region-history-mode-disabled
- (let ((entry (ring-remove region-history 0)))
- (if (region-history-is-entry-valid entry)
- (progn
- (ring-insert-at-beginning region-history entry)
- (switch-to-buffer (region-history-entry-buffer entry))
- (set-mark (region-history-entry-beg entry))
- (goto-char (region-history-entry-end entry)))
- (region-history-prev))))))
- (defun region-history-next ()
- (interactive)
- (unless (ring-empty-p region-history)
- (with-region-history-mode-disabled
- (let ((entry (ring-remove region-history)))
- (if (region-history-is-entry-valid entry)
- (progn
- (ring-insert region-history entry)
- (switch-to-buffer (region-history-entry-buffer entry))
- (set-mark (region-history-entry-beg entry))
- (goto-char (region-history-entry-end entry)))
- (region-history-next))))))
- (defmacro with-region-history-mode-disabled (&rest body)
- "Evaluate body with region-history-mode disabled."
- (declare (indent 0) (debug t))
- `(unwind-protect
- (progn (region-history-mode -1)
- ,@body)
- (region-history-mode 1)))
- (defun region-history-reset ()
- (interactive)
- (setq region-history (make-ring region-history-size)))
- (defun region-history-deactivate-mark-hook ()
- (region-history-insert (mark-marker) (point-marker)))
- (defvar region-history-mode-)
- (define-minor-mode region-history-mode
- "Minor mode for saving and navigating history of selected regions."
- :global t
- :keymap
- (easy-mmode-define-keymap
- (list (cons (kbd "M-p") 'region-history-prev)
- (cons (kbd "M-n") 'region-history-next)))
- (if region-history-mode
- (add-hook 'deactivate-mark-hook 'region-history-deactivate-mark-hook)
- (remove-hook 'deactivate-mark-hook 'region-history-deactivate-mark-hook)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement