 (define-key intero-help-mode-map (kbd "C-c C-i") 'intero-help-info)
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Intero highlight uses mode
+
+(defvar intero-highlight-uses-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "n") 'intero-highlight-uses-mode-next)
+    (define-key map (kbd "TAB") 'intero-highlight-uses-mode-next)
+    (define-key map (kbd "p") 'intero-highlight-uses-mode-prev)
+    (define-key map (kbd "S-TAB") 'intero-highlight-uses-mode-prev)
+    (define-key map (kbd "<backtab>") 'intero-highlight-uses-mode-prev)
+    (define-key map (kbd "RET") 'intero-highlight-uses-mode-stop-here)
+    (define-key map (kbd "r") 'intero-highlight-uses-mode-replace)
+    (define-key map (kbd "C-g") 'intero-highlight-uses-mode)
+    (define-key map (kbd "q") 'intero-highlight-uses-mode)
+    map)
+  "Keymap for using `intero-highlight-uses-mode'.")
+
+(defvar-local intero-highlight-uses-mode-point nil)
+(defvar-local intero-highlight-uses-buffer-old-mode nil)
+
+;;;###autoload
+(define-minor-mode intero-highlight-uses-mode
+  "Minor mode for highlighting and jumping between uses."
+  :lighter " Uses"
+  :keymap intero-highlight-uses-mode-map
+  (if intero-highlight-uses-mode
+      (progn (setq intero-highlight-uses-buffer-old-mode buffer-read-only)
+             (setq buffer-read-only t)
+             (setq intero-highlight-uses-mode-point (point)))
+    (progn (setq buffer-read-only intero-highlight-uses-buffer-old-mode)
+           (when intero-highlight-uses-mode-point
+             (goto-char intero-highlight-uses-mode-point))))
+  (remove-overlays (point-min) (point-max) 'intero-highlight-uses-mode-highlight t))
+
+(defun intero-highlight-uses-mode-replace ()
+  "Replace all highlighted instances in the buffer with something
+  else."
+  (interactive)
+  (save-excursion
+    (goto-char (point-min))
+    (let ((o (intero-highlight-uses-mode-next)))
+      (when o
+        (let ((replacement
+               (read-from-minibuffer
+                (format "Replace uses %s with: "
+                        (buffer-substring
+                         (overlay-start o)
+                         (overlay-end o))))))
+          (let ((inhibit-read-only t))
+            (while o
+              (goto-char (overlay-start o))
+              (delete-region (overlay-start o)
+                             (overlay-end o))
+              (insert replacement)
+              (setq o (intero-highlight-uses-mode-next))))))))
+  (intero-highlight-uses-mode -1))
+
+(defun intero-highlight-uses-mode-stop-here ()
+  "Stop at this point."
+  (interactive)
+  (setq intero-highlight-uses-mode-point (point))
+  (intero-highlight-uses-mode -1))
+
+(defun intero-highlight-uses-mode-next ()
+  "Jump to next result."
+  (interactive)
+  (let ((os (sort (cl-remove-if (lambda (o)
+                                  (or (<= (overlay-start o) (point))
+                                      (not (overlay-get o 'intero-highlight-uses-mode-highlight))))
+                                (overlays-in (point) (point-max)))
+                  (lambda (a b)
+                    (< (overlay-start a)
+                       (overlay-start b))))))
+    (when os
+      (mapc
+       (lambda (o)
+         (when (overlay-get o 'intero-highlight-uses-mode-highlight)
+           (overlay-put o 'face 'isearch-lazy-highlight)))
+       (overlays-in (line-beginning-position) (line-end-position)))
+      (goto-char (overlay-start (car os)))
+      (overlay-put (car os) 'face 'isearch)
+      (car os))))
+
+(defun intero-highlight-uses-mode-prev ()
+  "Jump to previous result."
+  (interactive)
+  (let ((os (sort (cl-remove-if (lambda (o)
+                                  (or (>= (overlay-end o) (point))
+                                      (not (overlay-get o 'intero-highlight-uses-mode-highlight))))
+                                (overlays-in (point-min) (point)))
+                  (lambda (a b)
+                    (> (overlay-start a)
+                       (overlay-start b))))))
+    (when os
+      (mapc
+       (lambda (o)
+         (when (overlay-get o 'intero-highlight-uses-mode-highlight)
+           (overlay-put o 'face 'isearch-lazy-highlight)))
+       (overlays-in (line-beginning-position) (line-end-position)))
+      (goto-char (overlay-start (car os)))
+      (overlay-put (car os) 'face 'isearch)
+      (car os))))
+
+(defun intero-highlight-uses-mode-highlight (start end current)
+  "Make a highlight overlay at the given span."
+  (let ((o (make-overlay start end)))
+    (overlay-put o 'priority 999)
+    (overlay-put o 'face
+                 (if current
+                     'isearch
+                   'isearch-lazy-highlight))
+    (overlay-put o 'intero-highlight-uses-mode-highlight t)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (provide 'intero)
 



(define-key intero-mode-map (kbd "C-c C-t") 'intero-type-at)
(define-key intero-mode-map (kbd "C-c C-i") 'intero-info)
(define-key intero-mode-map (kbd "M-.") 'intero-goto-definition)
(define-key intero-mode-map (kbd "C-c C-l") 'intero-repl-load)

    (insert expression)
    (font-lock-ensure)
    (buffer-string)))

(defun intero-uses-at ()
  "Highlight uses of the identifier at point."
  (interactive)
  (let* ((thing (intero-thing-at-point))
         (uses (split-string (apply #'intero-get-uses-at thing)
                             "\n"
                             t)))
    (unless (null uses)
      (let ((highlighted nil))
        (cl-loop
         for use in uses
         when (string-match
               "\\(.*?\\):(\\([0-9]+\\),\\([0-9]+\\))-(\\([0-9]+\\),\\([0-9]+\\))$"
               use)
         do (let* ((fp (match-string 1 use))
                   (sline (string-to-number (match-string 2 use)))
                   (scol (string-to-number (match-string 3 use)))
                   (eline (string-to-number (match-string 4 use)))
                   (ecol (string-to-number (match-string 5 use)))
                   (start (save-excursion (goto-char (point-min))
                                          (forward-line (1- sline))
                                          (forward-char (1- scol))
                                          (point))))
              (when (string= fp (intero-temp-file-name))
                (unless highlighted
                  (intero-highlight-uses-mode))
                (setq highlighted t)
                (intero-highlight-uses-mode-highlight
                 start
                 (save-excursion (goto-char (point-min))
                                 (forward-line (1- eline))
                                 (forward-char (1- ecol))
                                 (point))
                 (= start (car thing))))))))))

(defun intero-type-at (insert)
  "Get the type of the thing or selection at point.
