           (when (buffer-file-name) (message "merlin can only operate on ml files"))
           (merlin-mode -1)))
     (when (merlin-can-handle-buffer)
+      (merlin-error-gc)
       (when merlin-lock-zone-highlight-overlay
         (delete-overlay merlin-lock-zone-highlight-overlay))
       (when merlin-lock-zone-margin-overlay

                      nil 'make-it-local)
            (add-hook 'after-save-hook 'merlin-after-save
                      nil 'make-it-local)
            (add-hook 'pre-command-hook
                      'merlin-show-current-error nil 'make-it-local)
            (add-hook 'post-command-hook
                      'merlin-show-error-on-current-line-soon
                      nil 'make-it-local)))

(defun merlin-kill-all-processes ()
  "Kill all the remaining buffers containing merlin processes."

          (setq errors (cdr errors)))))
    found))

(defvar merlin-error-timer nil
  "Timer to show the error at point in the echo area.")

(defun merlin-error-start-timer ()
  "Start the error timer as an idle timer.
When it expires, the current Merlin error is shown in the echo
area."
  (merlin-error-cancel-timer)
  (setq merlin-error-timer
        (run-with-idle-timer 0.1 'repeat 'merlin-show-error-on-current-line))
  (merlin-error-start-gc-timer))

(defun merlin-error-cancel-timer ()
  "Cancel the error display timer."
  (when merlin-error-timer
    (cancel-timer merlin-error-timer)
    (setq merlin-error-timer nil)))

(defvar merlin-error-gc-timer nil
  "Timer to collect unused Merlin timers.
This triggers `merlin-error-gc' to check whether there are any
buffers left using Merlin.  If not, we can cancel this timer and
`merlin-error-timer'.")

(defun merlin-error-gc ()
  "Check whether there are still buffers using Merlin.
Clean up Merlin timers if there are none."
  (when (not (member t
                     (mapcar
                      (lambda (buf) (buffer-local-value 'merlin-mode buf))
                      (buffer-list))))
    ;; No buffer uses Merlin anymore. Kill all hu^H^Htimers.
    (merlin-error-cancel-timer)
    (merlin-error-cancel-gc-timer)))

(defun merlin-error-start-gc-timer ()
  "Start the Merlin GC timer (see `merlin-error-gc-timer').
The timer fires every 10 seconds of idle time."
  (merlin-error-cancel-gc-timer)
  (setq merlin-error-gc-timer (run-at-time 10 10 'merlin-error-gc)))

(defun merlin-error-cancel-gc-timer ()
  "Cancel the Merlin GC timer (see `merlin-error-gc-timer')."
  (when merlin-error-gc-timer
    (cancel-timer merlin-error-gc-timer)
    (setq merlin-error-gc-timer nil)))

(defun merlin-chomp (str)
  "Remove whitespace at the beginning and end of STR."
  (replace-regexp-in-string "\\(^[[:space:]\\n]*\\|[[:space:]\\n]*$\\)" "" str))

(defun merlin-show-error-on-current-line ()
  "Show the error of the current line in the echo area.
If there is no error, do nothing."
  (when (and merlin-mode (not (current-message)))
    (lexical-let* ((current-line (line-number-at-pos))
                   (err (merlin-find-error-for-line
                         (line-number-at-pos) merlin-pending-errors)))
      (if err (message (merlin-chomp (cdr (assoc 'message err))))))))

(defun merlin-error-next ()
  "Jump to the next error."
