     (let ((dirs (split-string (buffer-file-name) "/" t))
           my-dir
           found)
+      ;; FIXME use built-in filename manipulation utils
       (loop for i from (1- (length dirs)) downto 0 do
             (let ((dir "/"))
               (loop for j from 0 below i do

    (set-process-sentinel proc (lambda (_proc _event) (funcall c nil)))
    (set-process-filter proc (lambda (proc output)
                               (when (string-match "Listening on port \\([0-9][0-9]*\\)" output)
                                 (set-process-sentinel proc nil)
                                 (set-process-filter proc nil)
                                 (funcall c (string-to-number (match-string 1 output))))))))

(defvar tern-command-generation 0)
(defvar tern-activity-since-command -1)

(defun tern-complete ()
  (interactive)
  (tern-run-command #'tern-do-complete
                    `((query . ((type . "completions") (file . "infer.js") (end . ,(1- (point))))))))

(defun tern-run-command (f doc)
  (let ((generation tern-command-generation)

              (if (or (file-exists-p (concat dir ".tern-project"))
                      (file-exists-p (concat dir ".tern-port")))
                  (progn (setf found dir) (return)))))
      (setf tern-project-dir (or found my-dir))
      (if (and found (not ignore-port-file) (file-exists-p (concat found ".tern-port")))
          (let ((port (string-to-number (with-temp-buffer
                                          (insert-file-contents (concat found ".tern-port"))
                                          (buffer-string)))))
            (setf tern-known-port port)
            (funcall c port))
        (tern-start-server tern-project-dir c)))))

;; FIXME this probably won't work on other systems...
(defvar tern-command '("/usr/bin/node" "/home/marijn/src/js/tern/desktop.js"))
