;;; quick-jump.el ---Remember current position,and jump back ;; Filename: quick-jump.el ;; Description:Remember current position,and jump back cyclely. ;; Author: Joseph <jixiuf@gmail.com> ;; Maintainer: Joseph <jixiuf@gmail.com> ;; Copyright (C) 2011~, Joseph, all rights reserved. ;; Created: 2011-02-22 ;; Version: 0.1.0 ;; URL: http://www.emacswiki.org/quick-jump.el ;; Keywords: quick jump marker ;; Compatibility: (Test on GNU Emacs 23.2.1). ;; ;; ;;; This file is NOT part of GNU Emacs ;; ;;; License ;; ;; This program 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 3, 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 this program; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth ;; Floor, Boston, MA 02110-1301, USA. ;;; Commentary: ;; quick-jump.el works like `register' in Emacs. but it is ;; different to it ,quick-jump.el push current position to a ;; ring named `qj-marker-ring' then you can go back(or forward) ;; to the position ,and you can clear all the position in `qj-marker-ring' ;; to manager the ring by `quick-jump-clear-all-marker'. ;; ;; Suppose you have run `quick-jump-push-marker' on line 1,5,10 ;; then three positions is pushed into `qj-marker-ring'. now the ring is ;; [10,5,1],you are on line 10 now ,then you run `quick-jump-go-back' ;; you will be back to line 5, the ring still is [10,5,1]. but ;; `qj-current-marker' is not the last position you have pushed on line ;; 10, it's line 5 now. ;; go back and go forward are related to `qj-current-marker'. ;; ;; when you `quick-jump-go-back' or `quick-jump-go-forward' ;; it will decide whether push current position to `qj-marker-ring' ;; automaticly or not . when the count of lines between current line ;; and the line of `qj-current-marker' are larger than `qj-line-count', ;; then current position will be automaticly put into `qj-marker-ring' ;; ;; So suppose the ring is [15,10,5,1] and `qj-current-marker' is 10 ,if you ;; are on line 100 now ,and you run `quick-jump-go-back' now you position ;; is go back to line 5,the ring become [100,15,10.5.1],because ;; 100-10>`qj-line-count' it is larger than `qj-line-count' default value ;; 10.but if you are on line 16 and run `quick-jump-go-back', the ring still ;; is [15,10,5,1] ,it isn't [16,15,10,5,1],because 16-10<`qj-line-count'. ;; ;; ;;; Install: ;; ;; Just put quick-jump.el to your load-path. ;; The load-path is usually ~/elisp/. ;; It's set in your ~/.emacs like this: ;; (add-to-list 'load-path (expand-file-name "~/elisp")) ;; ;; And the following to your ~/.emacs startup file. ;; ;; (require 'quick-jump) ;; (quick-jump-default-keybinding) ;; ;; or ;; ;; (autoload 'quick-jump-push-marker "quick-jump" ;; " push current marker in ring. you can jump back" t) ;; (autoload 'quick-jump-go-back "quick-jump" ;; "Go back in `qj-marker-ring'") ;; (autoload 'quick-jump-go-forward "quick-jump" ;; "Go forward in `qj-marker-ring'") ;; (autoload 'quick-jump-clear-all-marker "quick-jump" ;; "clear all marker in `qj-marker-ring'.") ;; (autoload 'quick-jump-default-keybinding "quick-jump" ;; "default keybindings for quick-jump" nil) ;; (quick-jump-default-keybinding) ;;; Commands: ;; ;; Below are complete command list: ;; ;; `quick-jump-push-marker' ;; push current marker in ring. you can jump back ;; `quick-jump-go-back' ;; Go back in `qj-marker-ring'. ;; `quick-jump-go-forward' ;; Go forward in `qj-marker-ring'. ;; `quick-jump-clear-all-marker' ;; clear all marker in `qj-marker-ring'. ;; ;;; Customizable Options: ;; ;; Below are customizable option list: ;; ;; `qj-line-count' ;; about the meaning of me see Commentary. ;; default = 10 (require 'ring) (defgroup quick-jump nil "Remember current position,and jump back." :group 'convenience) (defcustom qj-line-count 10 "about the meaning of me see Commentary." :type 'number :group 'quick-jump) (defvar qj-current-marker nil) (defvar qj-marker-ring (make-ring 5)) (defvar qj-previous-action-flag nil) ;;; util func (defun qj-is-marker-available(marker) "return nil if marker is nil or in dead buffer , return marker if it is live" (if (and marker (markerp marker) (marker-buffer marker)) marker)) (defmacro qj-if+ (test-form then-form &rest else-forms) "Anaphoric if. Temporary variable `it' is the result of test-form.(borrowed from anything.el)" `(let ((it ,test-form)) (if it ,then-form ,@else-forms))) ;;; funcs (defun qj-init() "remove #<marker in no buffer> from `qj-marker-ring'." (let ((tmp-marker-ring)) (while (not (ring-empty-p qj-marker-ring)) (qj-if+ (qj-is-marker-available (ring-remove qj-marker-ring 0)) (setq tmp-marker-ring (append tmp-marker-ring (list it)));;new item first (while (not (ring-empty-p qj-marker-ring));;remove all old marker (ring-remove qj-marker-ring)))) ;;reinsert all available marker to `qj-marker-ring' (mapc (lambda(marker) (ring-insert-at-beginning qj-marker-ring marker)) tmp-marker-ring)) ;;add (point-marker) to marker-ring, when ... (when (and (not (ring-empty-p qj-marker-ring)) (not (ring-member qj-marker-ring (point-marker))) (or (not (equal (marker-buffer qj-current-marker) (current-buffer))) (> (count-lines (point) (marker-position qj-current-marker)) qj-line-count))) (ring-insert qj-marker-ring (point-marker))) (when (ring-empty-p qj-marker-ring) (message "please push marker before jumping. using `quick-jump-push-marker'"))) (defun qj-action-go(marker) "Go to location." (let ((buf (marker-buffer marker)) (pos (marker-position marker))) (when buf (switch-to-buffer buf) (set-buffer buf) (goto-char pos))) (setq qj-current-marker marker)) (defun quick-jump-push-marker() "push current marker in ring. you can jump back by `quick-jump-go-back'" (interactive) (when (not (ring-member qj-marker-ring (point-marker))) (ring-insert qj-marker-ring (point-marker))) (setq qj-current-marker (point-marker)) (message "a marker is pushed.")) (defun quick-jump-go-back() "Go back in `qj-marker-ring'." (interactive) (qj-init) (when (and (qj-is-marker-available qj-current-marker) (ring-member qj-marker-ring qj-current-marker)) (when (and (not (equal qj-previous-action-flag "back")) (equal (current-buffer) (marker-buffer qj-current-marker)) (< (count-lines (point) (marker-position qj-current-marker)) qj-line-count)) (setq qj-current-marker (ring-next qj-marker-ring qj-current-marker))) (message (concat "jump to " (prin1-to-string qj-current-marker))) (qj-action-go qj-current-marker) (setq qj-current-marker (ring-next qj-marker-ring qj-current-marker)) (setq qj-previous-action-flag "back"))) (defun quick-jump-go-forward() "Go forward in `qj-marker-ring'." (interactive) (qj-init) (when (and (qj-is-marker-available qj-current-marker) (ring-member qj-marker-ring qj-current-marker)) (when (and (not (equal qj-previous-action-flag "forward")) (equal (current-buffer) (marker-buffer qj-current-marker)) (< (count-lines (point) (marker-position qj-current-marker)) qj-line-count)) (setq qj-current-marker (ring-previous qj-marker-ring qj-current-marker))) (message (concat "jump to " (prin1-to-string qj-current-marker))) (qj-action-go qj-current-marker) (setq qj-current-marker (ring-previous qj-marker-ring qj-current-marker)) (setq qj-previous-action-flag "forward"))) (defun quick-jump-clear-all-marker() "clear all marker in `qj-marker-ring'." (interactive) (message "clear all marker for joseph-quick-jump.") (setq qj-previous-action-flag nil) (setq qj-current-marker nil) (while (not (ring-empty-p qj-marker-ring)) (ring-remove qj-marker-ring))) (defun quick-jump-default-keybinding() (global-set-key (kbd "C-,") 'quick-jump-go-back) (global-set-key (kbd "C-.") 'quick-jump-push-marker) (global-set-key (kbd "C-<") 'quick-jump-go-forward) (global-set-key (kbd "C->") 'quick-jump-clear-all-marker)) (provide 'quick-jump) ;;;quick-jump.el ends here.