rce search path."
  (interactive "DDirectory for search path: ")
  (setq po-search-path (cons (list (if (string-match "/$" directory)
                                         directory
                                       (concat directory "/")))
                             po-search-path))
  (setq po-reference-check 0)
  (po-show-source-path))

(defun po-ignore-source-path ()
  "Delete a directory, selected with completion, from the source search path."
  (interactive)
  (setq po-search-path
        (delete (list (completing-read (_"Directory to remove? ")
                                       po-search-path nil t))
                po-search-path))
  (setq po-reference-check 0)
  (po-show-source-path))

(defun po-ensure-source-references ()
  "Extract all references into a list, with paths resolved, if necessary."
  (po-find-span-of-entry)
  (if (= po-start-of-entry po-reference-check)
      nil
    (setq po-reference-alist nil)
    (save-excursion
      (goto-char po-start-of-entry)
      (if (re-search-forward "^#:" po-start-of-msgid t)
          (let (current name line path file)
            (while (looking-at "\\(\n#:\\)? *\\([^: ]*\\):\\([0-9]+\\)")
              (goto-char (match-end 0))
              (setq name (match-string-no-properties 2)
                    line (match-string-no-properties 3)
                    path po-search-path)
              (if (string-equal name "")
                  nil
                (while (and (not (file-exists-p
                                  (setq file (concat (car (car path)) name))))
                            path)
                  (setq path (cdr path)))
                (setq current (and path file)))
              (if current
                  (setq po-reference-alist
                        (cons (list (concat current ":" line)
                                    current
                                    (string-to-number line))
                              po-reference-alist)))))))
    (setq po-reference-alist (nreverse po-reference-alist)
          po-reference-cursor po-reference-alist
          po-reference-check po-start-of-entry)))

(defun po-show-source-context (triplet)
  "Show the source context given a TRIPLET which is (PROMPT FILE LINE)."
  (find-file-other-window (car (cdr triplet)))
  (goto-line (car (cdr (cdr triplet))))
  (other-window 1)
  (let ((maximum 0)
        position
        (cursor po-reference-alist))
    (while (not (eq triplet (car cursor)))
      (setq maximum (1+ maximum)
            cursor (cdr cursor)))
    (setq position (1+ maximum)
          po-reference-cursor cursor)
    (while cursor
      (setq maximum (1+ maximum)
            cursor (cdr cursor)))
    (message (_"Displaying %d/%d: \"%s\"") position maximum (car triplet))))

(defun po-cycle-source-reference ()
  "Display some source context for the current entry.
If the command is repeated many times in a row, cycle through contexts."
  (interactive)
  (po-ensure-source-references)
  (if po-reference-cursor
      (po-show-source-context
       (car (if (eq last-command 'po-cycle-source-reference)
                (or (cdr po-reference-cursor) po-reference-alist)
              po-reference-cursor)))
    (error (_"No resolved source references"))))

(defun po-select-source-reference ()
  "Select one of the available source contexts for the current entry."
  (interactive)
  (po-ensure-source-references)
  (if po-reference-alist
      (po-show-source-context
       (assoc
        (completing-read (_"Which source context? ") po-reference-alist nil t)
        po-reference-alist))
    (error (_"No resolved source references"))))
