             (p 1))
         (while (not (null p))
           (let ((np (compilation-next-single-property-change p 'compilation-message)))
-            ;; TODO(adonovan): this can be verbose in the *Messages* buffer.
-            ;; (message "Post-processing link (%d%%)" (/ (* p 100) (point-max)))
             (if np
                 (when (equal (line-number-at-pos p) (line-number-at-pos np))
-                  ;; np is (typically) the space following ":"; consume it too.
-                  (put-text-property p np 'display "▶")
+                  ;; Using a fixed width greatly improves readability, so
+                  ;; if the filename is longer than 20, show ".../last/17chars.go".
+                  ;; This usually includes the last segment of the package name.
+                  ;; Don't show the line or column number.
+                  (let* ((loc (buffer-substring p np)) ; "/home/foo/go/pkg/file.go:1:2-3:4"
+                         (i (search ":" loc)))
+                    (setq loc (cond
+                               ((null i)  "...")
+                               ((>= i 17) (concat "..." (substring loc (- i 17) i)))
+                               (t         (substring loc 0 i))))
+                    ;; np is (typically) the space following ":"; consume it too.
+                    (put-text-property p np 'display (concat loc ":")))
                   (goto-char np)
-                  (insert " ")))
+                  (insert " ")
+                  (incf np))) ; so we don't get stuck (e.g. on a panic stack dump)
             (setq p np)))
         (message nil))
 

(defun go-oracle-callees ()
  "Show possible callees of the function call at the current point."
  (interactive)
  (go-oracle--run "callees"))

(defun go-oracle-callers ()
  "Show the set of callers of the function containing the current point."
  (interactive)
  (go-oracle--run "callers"))

(defun go-oracle-callgraph ()
  "Show the callgraph of the current program."
  (interactive)
  (go-oracle--run "callgraph"))

(defun go-oracle-callstack ()
  "Show an arbitrary path from a root of the call graph to the
function containing the current point."
  (interactive)
  (go-oracle--run "callstack"))

(defun go-oracle-definition ()
  "Show the definition of the selected identifier."

  nil
  "History of values supplied to `go-oracle-set-scope'.")

;; Extend go-mode-map.
(let ((m go-mode-map))
  (define-key m (kbd "C-c C-o t") #'go-oracle-describe) ; t for type
  (define-key m (kbd "C-c C-o f") #'go-oracle-freevars)
  (define-key m (kbd "C-c C-o g") #'go-oracle-callgraph)
  (define-key m (kbd "C-c C-o i") #'go-oracle-implements)
  (define-key m (kbd "C-c C-o c") #'go-oracle-peers)  ; c for channel
  (define-key m (kbd "C-c C-o r") #'go-oracle-referrers)
  (define-key m (kbd "C-c C-o d") #'go-oracle-definition)
  (define-key m (kbd "C-c C-o p") #'go-oracle-pointsto)
  (define-key m (kbd "C-c C-o s") #'go-oracle-callstack)
  (define-key m (kbd "C-c C-o <") #'go-oracle-callers)
  (define-key m (kbd "C-c C-o >") #'go-oracle-callees)
  (define-key m (kbd "<f5>") #'go-oracle-describe)
  (define-key m (kbd "<f6>") #'go-oracle-referrers))

;; TODO(dominikh): Rethink set-scope some. Setting it to a file is
;; painful because it doesn't use find-file, and variables/~ aren't
