 
 (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))
+  (let (diffs)
+    (ycmd--loop-chunks-by-filename (chunks (nreverse diffs))
+      (let* ((filepath (car it))
+             (chunk (cdr it))
              (buffer (find-file-noselect filepath))
              (buffertext (with-current-buffer buffer (buffer-string))))
         (with-temp-buffer

(defun ycmd--apply-fixit (button)
  "Apply BUTTON's FixIt chunk."
  (-when-let* ((chunks (button-get button 'fixit)))
    (let ((chunks-by-filepath
           (--group-by (let-alist it .range.start.filepath)
                       chunks)))
      (dolist (file-chunks chunks-by-filepath)
        (ycmd--replace-chunk-list (cdr file-chunks))))
    (quit-window t (get-buffer-window "*ycmd-fixits*"))))

(define-derived-mode ycmd-fixit-mode ycmd-view-mode "ycmd-fixits"


;;; 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."
