   (integerp (string-match "^DONE" result)))
 
 (defun mural-read-tag ()
-  (setq ido-dynamic-match-fn 'mural-query-save-tag)
-  (unwind-protect ;; i have no idea what's going on here
-      (ido-completing-read "tag: " '("nope"))
-    (setq ido-dynamic-match-fn nil)))
-
+  (let ((file-base (buffer-file-name)))
+    (if (not file-base)
+        (error "no file associated with buffer"))
+    (setq mural-current-tagfile (mural-tagfile-for-filename file-base))
+    (if (not mural-current-tagfile)
+        (error "no tagfile associated with %s" file-base))
+    (setq ido-dynamic-match-fn 'mural-query-save-tag)
+    (unwind-protect ;; i have no idea what's going on here
+        (ido-completing-read "tag: " '("nope"))
+      (setq ido-dynamic-match-fn nil))))
+
+(defun mural-tag-tagname (tag)
+  (elt tag 0))
 (defun mural-tag-filename (tag)
   (elt tag 1))
 (defun mural-tag-row (tag)


(defvar mural-server-echo nil
  "echo server responses to *muralserver* buffer")
(defvar mural-server-process nil)
(defvar mural-server-output "")
(defvar ido-dynamic-match-fn nil)
(defvar mural-last-query-result nil)

(defun mural-get-server ()
  (if (or (not mural-server-process)
          (not (eq (process-status mural-server-process) 'run)))
      (setq mural-server-process (mural-start-server)))
  mural-server-process)

(defun mural-start-server ()
  (if (not tags-file-name)
      (error "tags-file-name not set"))
  (message "Starting mural server")
  (let ((proc (start-process
               "mural" "*muralserver*"
               mural-server-path tags-file-name)))
    (set-process-filter
     proc
     (lambda (process output)

           (setq mural-server-output (concat mural-server-output output))))))
     proc))

;; I can't believe I have to write this function
(defun filter (pred lst)
  (if (eq 0 (length lst))
      '()
    (let ((fst (car lst))
          (rst (filter pred (cdr lst))))
      (if (funcall pred fst)
        (cons fst rst)
        rst))))

(defun mural-tagfile-for-filename (filename)
  (let ((resolved-fname (file-truename filename)))
    (car (filter
          (lambda (tagfile)
            ;; file-truename resolves symlinks so we make sure to compare the same thing
            (eq 0 (string-match
                   (file-truename (file-name-directory tagfile))
                   resolved-fname)))
          (mapcar 'car mural-tagfile-to-process)))))

(defun mural-query (query tagfile)
  (if (equal "" query)
      '()
    (let ((proc (mural-get-server tagfile)))
      (setq mural-server-output "")
      (process-send-string (process-name proc)
                           (concat query "\n"))

      ;; Wait up to 1/2 second
      (loop for i from 1 to 10
            until (mural-response-complete mural-server-output)
            do (accept-process-output proc .05))
      (if (mural-response-complete mural-server-output)
          (mural-parse-response mural-server-output)
        (progn
