 ;; URL: http://ternjs.net/
 ;; Version: 0.0.1
 ;; Package-Requires: ((json "1.2") (cl-lib "0.5") (emacs "24"))
+
+;;; Code:
 
 (require 'cl-lib)
 (require 'json)


;; Mode plumbing

(defun tern-before-change (start end)
  (if tern-buffer-is-dirty
      (setf (car tern-buffer-is-dirty) (min (car tern-buffer-is-dirty) start)
            (cdr tern-buffer-is-dirty) (max (cdr tern-buffer-is-dirty) end))
    (setf tern-buffer-is-dirty (cons start end)))
  (when (> (- (cdr tern-buffer-is-dirty) (car tern-buffer-is-dirty)) 4000)
    (run-at-time "200 millisec" nil
                 (lambda (buf)
                   (with-current-buffer buf
                     (when tern-buffer-is-dirty
                       (setf tern-buffer-is-dirty nil)
                       (tern-send-buffer-to-server))))
                 (current-buffer)))
  (setf tern-last-point-pos nil)
  (when (and tern-last-argument-hints (<= start (car tern-last-argument-hints)))
    (setf tern-last-argument-hints nil))
  (when (and tern-last-completions (<= start (cadr tern-last-completions)))
    (setf tern-last-completions nil)))

(defun tern-post-command ()
  (unless (eq (point) tern-last-point-pos)

  (set (make-local-variable 'tern-buffer-is-dirty) (and (buffer-modified-p) (cons (point-min) (point-max))))
  (make-local-variable 'completion-at-point-functions)
  (push 'tern-completion-at-point completion-at-point-functions)
  (add-hook 'after-change-functions 'tern-after-change nil t)
  (when (null tern-idle-timer)
    (setq tern-idle-timer
          (run-with-idle-timer tern-idle-time t #'tern-reparse-on-idle)))
  (add-hook 'post-command-hook 'tern-post-command nil t)
  (add-hook 'buffer-list-update-hook 'tern-left-buffer nil t)
  (tern-send-buffer-to-server))

(defun tern-mode-disable ()
  (setf completion-at-point-functions
        (remove 'tern-completion-at-point completion-at-point-functions))
  (unless (null tern-idle-timer)
    (cancel-timer tern-idle-timer)
    (setq tern-idle-timer nil))
  (remove-hook 'after-change-functions 'tern-after-change t)
  (remove-hook 'post-command-hook 'tern-post-command t)
  (remove-hook 'buffer-list-update-hook 'tern-left-buffer t))

