+(defun elopher-make-node (parent address getter &optional content pos)
+ (list parent address getter content pos))
+
+(defun elopher-node-parent (node)
+ (elt node 0))
+
+(defun elopher-node-address (node)
+ (elt node 1))
+
+(defun elopher-node-getter (node)
+ (elt node 2))
+
+(defun elopher-node-content (node)
+ (elt node 3))
+
+(defun elopher-node-pos (node)
+ (elt node 4))
+
+(defun elopher-set-node-content (node content)
+ (setcar (nthcdr 3 node) content))
+
+(defun elopher-set-node-pos (node pos)
+ (setcar (nthcdr 4 node) pos))
+
+(defun elopher-save-pos ()
+ (when elopher-current-node
+ (elopher-set-node-pos elopher-current-node (point))))
+
+(defun elopher-restore-pos ()
+ (let ((pos (elopher-node-pos elopher-current-node)))
+ (if pos
+ (goto-char pos)
+ (goto-char (point-min)))))
+
+;; Node graph traversal
+
+(defvar elopher-current-node)
+
+(defun elopher-visit-node (node)
+ (elopher-save-pos)
+ (elopher-prepare-buffer)
+ (setq elopher-current-node node)
+ (funcall (elopher-node-getter node)))
+
+(defun elopher-visit-parent-node ()
+ (let ((parent-node (elopher-node-parent elopher-current-node)))
+ (when parent-node
+ (elopher-visit-node parent-node))))
+
+(defun elopher-reload-current-node ()
+ (elopher-set-node-content elopher-current-node nil)
+ (elopher-visit-node elopher-current-node))
+
+
+;;; Buffer preparation
+;;
+
+(defun elopher-prepare-buffer ()
+ (switch-to-buffer "*elopher*")
+ (elopher-mode)
+ (let ((inhibit-read-only t))
+ (erase-buffer)))