 to and including character (1- go-mode-mark-cs-end)).")
 (make-variable-buffer-local 'go-mode-mark-cs-end)
 
-(defvar go-mode-mark-cs-state nil
-  "The `parse-partial-sexp' state of the comment/string parser as
-of the point `go-mode-mark-cs-end'.")
-(make-variable-buffer-local 'go-mode-mark-cs-state)
-
 (defvar go-mode-mark-nesting-end 1
   "The point at which the nesting cache ends.  The buffer will be
 marked from the beginning up to this point.")
 (make-variable-buffer-local 'go-mode-mark-nesting-end)
 
-(defun go-mode-mark-clear-cache (b e l)
-  "An after-change-function that clears the comment/string and
+(defun go-mode-mark-clear-cache (b e)
+  "A before-change-function that clears the comment/string and
 nesting caches from the modified point on."
 
   (save-restriction
     (widen)
-    (when (< b go-mode-mark-cs-end)
-      (remove-text-properties b (min go-mode-mark-cs-end (point-max)) '(go-mode-cs nil))
-      (setq go-mode-mark-cs-end b
-            go-mode-mark-cs-state nil))
-
+    (when (<= b go-mode-mark-cs-end)
+      ;; Remove the property adjacent to the change position.
+      ;; It may contain positions pointing beyond the new end mark.
+      (let ((b (let ((cs (get-text-property (max 1 (1- b)) 'go-mode-cs)))
+		 (if cs (car cs) b))))
+	(remove-text-properties
+	 b (min go-mode-mark-cs-end (point-max)) '(go-mode-cs nil))
+	(setq go-mode-mark-cs-end b)))
     (when (< b go-mode-mark-nesting-end)
       (remove-text-properties b (min go-mode-mark-nesting-end (point-max)) '(go-mode-nesting nil))
       (setq go-mode-mark-nesting-end b))))


  (unless pos
    (setq pos (point)))
  (if (= pos 1)
      nil
    (when (> pos go-mode-mark-cs-end)
      (go-mode-mark-cs pos))
    (get-text-property (- pos 1) 'go-mode-cs)))

(defun go-mode-mark-cs (end)
  "Mark comments and strings up to point END.  Don't call this
directly; use `go-mode-cs'."

  (setq end (min end (point-max)))
  (go-mode-parser
   (let* ((pos go-mode-mark-cs-end)
          (state (or go-mode-mark-cs-state (syntax-ppss pos))))
     ;; Mark comments and strings
     (when (nth 8 state)
       ;; Get to the beginning of the comment/string
       (setq pos (nth 8 state)
             state nil))
     (while (> end pos)
       ;; Find beginning of comment/string
       (while (and (> end pos)
                   (progn
                     (setq state (parse-partial-sexp pos end nil nil state 'syntax-table)
                           pos (point))
                     (not (nth 8 state)))))
       ;; Find end of comment/string
       (let ((start (nth 8 state)))
         (when start
           (setq state (parse-partial-sexp pos (point-max) nil nil state 'syntax-table)
                 pos (point))
           ;; Mark comment
           (put-text-property start (- pos 1) 'go-mode-cs (cons start pos))
           (when nil
             (put-text-property start (- pos 1) 'face
                                `((:background "midnight blue")))))))
     ;; Update state
     (setq go-mode-mark-cs-end   pos
           go-mode-mark-cs-state state))))

(defsubst go-mode-nesting (&optional pos)
  "Return the nesting at point POS.  The nesting is a list


  ;; Reset the syntax mark caches
  (setq go-mode-mark-cs-end      1
        go-mode-mark-nesting-end 1)
  (add-hook 'before-change-functions #'go-mode-mark-clear-cache nil t)

  ;; Indentation
  (set (make-local-variable 'indent-line-function)
