├── README.md └── jumplist.el /README.md: -------------------------------------------------------------------------------- 1 | # jumplist.el ![melpa badge][melpa-badge] 2 | 3 | jumplist.el is Emacs port of jumplist(`Ctrl-O`) in vim. 4 | And, as an additional feature, This package provides an another behavior mode(ex-mode) that move like the browser history. 5 | We will describe how to use ex-mode in the Customize Chapter. 6 | 7 | ## Requirements 8 | 9 | Emacs 24.3 or higher. 10 | 11 | ## Installation 12 | 13 | You can install jumplist.el from [MELPA](https://melpa.org/#/jumplist) with package.el. 14 | 15 | install directly: 16 | 17 | ```sh 18 | $ cd load-path-dir 19 | $ wget https://raw.githubusercontent.com/ganmacs/jumplist/master/jumplist.el 20 | ``` 21 | 22 | After Installation add following to your configuration file(`~/.emacs.d/init.el`, `~/.emacs` etc) 23 | 24 | ```lisp 25 | (require 'jumplist) 26 | ``` 27 | 28 | ## Customize 29 | 30 | ### Simple Customize 31 | 32 | ```lisp 33 | (require 'jumplist) 34 | (global-set-key (kbd "C-<") 'jumplist-previous) 35 | (global-set-key (kbd "C->") 'jumplist-next) 36 | ``` 37 | 38 | ### Hooks Customize 39 | 40 | If you want to customize hooks. you can customize it by using `jumplist-hook-commands` 41 | 42 | 43 | ```lisp 44 | (custom-set-variables 45 | '(jumplist-hook-commands 46 | '(helm-swoop dired-jump helm-for-files 47 | isearch-forward end-of-buffer beginning-of-buffer 48 | find-file))) 49 | ``` 50 | 51 | ### Ex-mode Customize 52 | 53 | If you want to use ex-mode, add this code. 54 | 55 | ```lisp 56 | (custom-set-variables 57 | '(jumplist-ex-mode t)) 58 | ``` 59 | 60 | ### Sample Customize 61 | 62 | This is my customize. 63 | 64 | ```lisp 65 | (require 'jumplist) 66 | (global-set-key (kbd "C-<") 'jumplist-previous) 67 | (global-set-key (kbd "C->") 'jumplist-next) 68 | (custom-set-variables 69 | '(jumplist-hook-commands 70 | '(helm-swoop dired-jump helm-for-files 71 | isearch-forward end-of-buffer beginning-of-buffer 72 | find-file)) 73 | '(jumplist-ex-mode t)) 74 | ``` 75 | 76 | 77 | [melpa-badge]: https://melpa.org/packages/jumplist-badge.svg 78 | -------------------------------------------------------------------------------- /jumplist.el: -------------------------------------------------------------------------------- 1 | ;;; jumplist.el --- Jump like vim jumplist or ex jumplist 2 | 3 | ;; Copyright (C) 2015 ganmacs 4 | 5 | ;; Author: ganmacs 6 | ;; Maintainer: ganmacs 7 | ;; URL: https://github.com/ganmacs/jumplist 8 | ;; Version: 0.0.2 9 | ;; Package-Requires: ((cl-lib "0.5")) 10 | ;; Keywords: jumplist vim 11 | 12 | ;; This file is NOT part of GNU Emacs. 13 | 14 | ;; This program is free software; you can redistribute it and/or modify 15 | ;; it under the terms of the GNU General Public License as published by 16 | ;; the Free Software Foundation, either version 3 of the License, or 17 | ;; (at your option) any later version. 18 | 19 | ;; This program is distributed in the hope that it will be useful, 20 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | ;; GNU General Public License for more details. 23 | 24 | ;; You should have received a copy of the GNU General Public License 25 | ;; along with this program. If not, see . 26 | 27 | ;;; Commentary: 28 | 29 | 30 | ;;; Code: 31 | 32 | (require 'cl-lib) 33 | 34 | (defgroup jumplist nil 35 | "jumplist configuration options." 36 | :prefix "jumplist" 37 | :group 'convenience) 38 | 39 | (defcustom jumplist-max-length 100 40 | "Max length of jumplist." 41 | :type 'integer 42 | :group 'jumplist) 43 | 44 | (defcustom jumplist-ex-mode 'nil 45 | "Original vim like jumplist or not." 46 | :type 'boolean 47 | :group 'jumplist) 48 | 49 | (defcustom jumplist-hook-commands '(end-of-buffer beginning-of-buffer find-file) 50 | "Commands to hook." 51 | :type 'list 52 | :group 'jumplist) 53 | 54 | (defvar jumplist--list '() 55 | "Jumplist that save file info.") 56 | 57 | (defvar jumplist--idx 0 58 | "Index of jumplist.") 59 | 60 | (defvar jumplist--jumping nil 61 | "Jumplist state.") 62 | 63 | (defun jumplist--do-jump (buff) 64 | "Do jump to target file and point from BUFF." 65 | (find-file (car buff)) 66 | (goto-char (cdr buff))) 67 | 68 | (defun jumplist--reset-idx () 69 | "Reset `jumplist--idx'." 70 | (setq jumplist--idx 0)) 71 | 72 | (defun jumplist--last? () 73 | "Check `jumplist--idx' is last of list." 74 | (= jumplist--idx (- (length jumplist--list) 1))) 75 | 76 | (defun jumplist--first? () 77 | "Check `jumplist--idx' is first of list." 78 | (= jumplist--idx 0)) 79 | 80 | (defun jumplist--dec-idx () 81 | "Descrement `jumplist--idx'." 82 | (setq jumplist--idx (- jumplist--idx 1))) 83 | 84 | (defun jumplist--inc-idx () 85 | "Increment `jumplist--idx'." 86 | (setq jumplist--idx (+ jumplist--idx 1))) 87 | 88 | (defun jumplist--drop! (idx) 89 | "Drop item form list of IDX." 90 | (setq jumplist--list (nthcdr jumplist--idx jumplist--list))) 91 | 92 | (defun jumplist--push (pointer) 93 | "Push POINTER to `jumplist'." 94 | (while (> (length jumplist--list) jumplist-max-length) 95 | (nbutlast jumplist--list 1)) 96 | (push pointer jumplist--list)) 97 | 98 | (defun jumplist--same-position? (pointer) 99 | (let ((new-point (cdr pointer)) 100 | (top-point (cdar jumplist--list))) 101 | (cond ((not new-point) nil) 102 | ((not top-point) nil) 103 | ((eq (marker-position new-point) (marker-position top-point)) 't)))) 104 | 105 | (defun jumplist--set () 106 | "The record data structure is (file-name . pointer)." 107 | (interactive) 108 | (if (buffer-file-name) 109 | (let ((pointer (cons (buffer-file-name) (point-marker)))) 110 | (unless (jumplist--same-position? pointer) 111 | (when (and jumplist-ex-mode jumplist--jumping) 112 | (jumplist--drop! jumplist--idx) 113 | (setq jumplist--jumping nil) 114 | (jumplist--reset-idx)) 115 | (unless (jumplist--same-position? pointer) 116 | (jumplist--push pointer)))))) 117 | 118 | (defun jumplist--do-command? (command do-hook-command-list) 119 | (if do-hook-command-list 120 | (or 121 | (eq command (car do-hook-command-list)) 122 | (jumplist--do-command? command (cdr do-hook-command-list))))) 123 | 124 | (defun jumplist--command-hook () 125 | "Pre command hook that call `jumplist--set' when registerd command hook called." 126 | (cond 127 | ((jumplist--do-command? this-command jumplist-hook-commands) (jumplist--set)) 128 | ((and jumplist--jumping ; when jump and move 129 | (not (memq this-command '(jumplist-previous jumplist-next)))) 130 | (jumplist--set)))) 131 | (add-hook 'pre-command-hook 'jumplist--command-hook) 132 | 133 | ;;;###autoload 134 | (defun jumplist-previous () 135 | "Jump back." 136 | (interactive) 137 | (if (or (not jumplist--list) 138 | (and (not (jumplist--first?)) 139 | (jumplist--last?))) 140 | (message "No further undo point.") 141 | (if jumplist-ex-mode 142 | (unless jumplist--jumping 143 | (jumplist--set) 144 | (setq jumplist--jumping 't))) 145 | (jumplist--inc-idx) 146 | (let ((buff (nth jumplist--idx jumplist--list))) 147 | (jumplist--do-jump buff)))) 148 | 149 | ;;;###autoload 150 | (defun jumplist-next () 151 | "Jump forward." 152 | (interactive) 153 | (if (or (not jumplist--list) 154 | (jumplist--first?)) 155 | (message "No further redo point.") 156 | (if jumplist-ex-mode 157 | (unless jumplist--jumping 158 | (jumplist--set) 159 | (setq jumplist--jumping 't))) 160 | (jumplist--dec-idx) 161 | (let ((buff (nth jumplist--idx jumplist--list))) 162 | (jumplist--do-jump buff)))) 163 | 164 | (provide 'jumplist) 165 | ;;; jumplist.el ends here 166 | --------------------------------------------------------------------------------