         (when (empty? @name-endpoint-map)
           (Thread/sleep 100)
           (when (= 20 count)
-            ((:print opts) "\nSearching for devices ..."))
+            ((println-fn opts) "\nSearching for devices ..."))
           (recur (inc count))))
       (Thread/sleep 500)                                    ;; Sleep a little more to catch stragglers
       (loop [current-name-endpoint-map @name-endpoint-map]
-        ((:print opts))
+        ((println-fn opts))
         (print-discovered-devices current-name-endpoint-map opts)
         (when-not choose-first-discovered?
-          ((:print opts) "\n[R] Refresh\n")
-          ((:print-no-newline opts) "Choice: ")
-          ((:flush opts)))
+          ((println-fn opts) "\n[R] Refresh\n")
+          ((print-fn opts) "Choice: ")
+          ((flush-fn opts)))
         (let [choice (if choose-first-discovered? "1" (read-line))]
           (if (= "r" (.toLowerCase choice))
             (recur @name-endpoint-map)

          output-dir (io/file webdav-mount-point)
          env (ana/empty-env)
          core (io/resource "cljs/core.cljs")]
      ((:print opts) "\nConnecting to" (bonjour-name->display-name bonjour-name) "...\n")
      (reset! (:webdav-mount-point repl-env) webdav-mount-point)
      (when (.exists output-dir)
        (shell/sh "umount" webdav-mount-point))


(defn print-discovered-devices [name-endpoint-map opts]
  (if (empty? name-endpoint-map)
    ((println-fn opts) "(No devices)")
    (doseq [[choice-number [bonjour-name _]] (name-endpoint-map->choice-list name-endpoint-map)]
      ((println-fn opts) (str "[" choice-number "] " (bonjour-name->display-name bonjour-name))))))

(defn discover-and-choose-device
  "Looks for Ambly WebDAV devices advertised via Bonjour and presents
