                   files-changed)
               (dolist (fixit fixits)
                 (-when-let (chunks (cdr (assq 'chunks fixit)))
-                  (let ((chunks-sorted
-                         (--group-by (let-alist it .range.start.filepath)
-                                     chunks)))
-                    (dolist (chunk chunks-sorted)
-                      (ycmd--replace-chunk-list (cdr chunk))
-                      (cl-incf num-changes-applied (length (cdr chunk)))
-                      (unless (member (car chunk) files-changed)
-                        (setq files-changed (append (list (car chunk))
+                  (ycmd--loop-chunks-by-filename (chunks)
+                    (let ((chunk-path (car it))
+                          (chunk (cdr it)))
+                      (ycmd--replace-chunk-list chunk)
+                      (cl-incf num-changes-applied (length chunk))
+                      (unless (member chunk-path files-changed)
+                        (setq files-changed (append (list chunk-path)
                                                     files-changed)))))))
               (when (> num-changes-applied 0)
                 (let* ((num-files-changed (length files-changed))


(defun ycmd--get-fixit-diff (chunks)
  "Return diff string for CHUNKS."
  (let ((chunks-by-filepath
         (--group-by (let-alist it .range.start.filepath)
                     chunks))
        diffs)
    (dolist (file-chunk chunks-by-filepath (nreverse diffs))
      (let* ((filepath (car file-chunk))
             (chunk (cdr file-chunk))
             (buffer (find-file-noselect filepath))
             (buffertext (with-current-buffer buffer (buffer-string))))
        (with-temp-buffer


;;; FixIts

(defmacro ycmd--loop-chunks-by-filename (spec &rest body)
  "Loop over an alist of fixit chunks grouped by filepath.
Evaluate BODY with `it' bound to each car from FIXIT-CHUNKS, in
turn. The structure of `it' is a cons cell (FILEPATH CHUNK-LIST).
Then evaluate RESULT to get return value, default nil.

\(fn (FIXIT-CHUNKS [RESULT]) BODY...)"
  (declare (indent 1) (debug ((symbolp form &optional form) body)))
  `(let ((chunks-by-filepath
          (--group-by (let-alist it .range.start.filepath)
                      ,(car spec))))
     (dolist (it chunks-by-filepath)
       ,@body)
     ,@(cdr spec)))

(defun ycmd--show-fixits (fixits &optional title)
  "Select a buffer and display FIXITS.
Optional TITLE is shown on first line."
