download: Use 'with-imported-modules'.
[jackhill/guix/guix.git] / emacs / guix-history.el
1 ;;; guix-history.el --- History of buffer information
2
3 ;; Copyright © 2014 Alex Kost <alezost@gmail.com>
4
5 ;; This file is part of GNU Guix.
6
7 ;; GNU Guix is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation, either version 3 of the License, or
10 ;; (at your option) any later version.
11
12 ;; GNU Guix is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20 ;;; Commentary:
21
22 ;; This file provides support for history of buffers similar to the
23 ;; history of a `help-mode' buffer.
24
25 ;;; Code:
26
27 (require 'cl-macs)
28
29 (defvar-local guix-history-stack-item nil
30 "Current item of the history.
31 A list of the form (FUNCTION [ARGS ...]).
32 The item is used by calling (apply FUNCTION ARGS).")
33 (put 'guix-history-stack-item 'permanent-local t)
34
35 (defvar-local guix-history-back-stack nil
36 "Stack (list) of visited items.
37 Each element of the list has a form of `guix-history-stack-item'.")
38 (put 'guix-history-back-stack 'permanent-local t)
39
40 (defvar-local guix-history-forward-stack nil
41 "Stack (list) of items visited with `guix-history-back'.
42 Each element of the list has a form of `guix-history-stack-item'.")
43 (put 'guix-history-forward-stack 'permanent-local t)
44
45 (defvar guix-history-size 0
46 "Maximum number of items saved in history.
47 If 0, the history is disabled.")
48
49 (defun guix-history-add (item)
50 "Add ITEM to history."
51 (and guix-history-stack-item
52 (push guix-history-stack-item guix-history-back-stack))
53 (setq guix-history-forward-stack nil
54 guix-history-stack-item item)
55 (when (>= (length guix-history-back-stack)
56 guix-history-size)
57 (setq guix-history-back-stack
58 (cl-loop for elt in guix-history-back-stack
59 for i from 1 to guix-history-size
60 collect elt))))
61
62 (defun guix-history-replace (item)
63 "Replace current item in history with ITEM."
64 (setq guix-history-stack-item item))
65
66 (defun guix-history-goto (item)
67 "Go to the ITEM of history.
68 ITEM should have the form of `guix-history-stack-item'."
69 (or (listp item)
70 (error "Wrong value of history element"))
71 (setq guix-history-stack-item item)
72 (apply (car item) (cdr item)))
73
74 (defun guix-history-back ()
75 "Go back to the previous element of history in the current buffer."
76 (interactive)
77 (or guix-history-back-stack
78 (user-error "No previous element in history"))
79 (push guix-history-stack-item guix-history-forward-stack)
80 (guix-history-goto (pop guix-history-back-stack)))
81
82 (defun guix-history-forward ()
83 "Go forward to the next element of history in the current buffer."
84 (interactive)
85 (or guix-history-forward-stack
86 (user-error "No next element in history"))
87 (push guix-history-stack-item guix-history-back-stack)
88 (guix-history-goto (pop guix-history-forward-stack)))
89
90 (provide 'guix-history)
91
92 ;;; guix-history.el ends here