server on textDocument/didOpen and similar calls. TRUENAME is the
expensive cached value of `file-truename'.")
-(defun eglot--flymake-fix (data)
- "Return fix suggestions for Flymake diagnostic with DATA."
+(defun eglot--flymake-fix (server data)
+ "Return fix suggestions from SERVER for Flymake diagnostic with DATA."
(eglot--dbind ((Diagnostic) range) (alist-get 'eglot-lsp-diag data)
(pcase-let ((`(,beg . ,end) (eglot--diag-range-region range)))
(let ((actions (eglot-code-actions beg end "quickfix")))
(seq-keep
- (eglot--lambda ((CodeAction) title edit)
- (eglot--dbind
- ((WorkspaceEdit) changes documentChanges)
- edit
- (let ((prepared
- (mapcar
- (eglot--lambda ((TextDocumentEdit) textDocument edits)
- (eglot--dbind ((VersionedTextDocumentIdentifier)
- uri version)
- textDocument
- (list (eglot-uri-to-path uri) edits version)))
- documentChanges)))
- (unless (and changes documentChanges)
- (cl-loop for (uri edits) on changes by #'cddr
- do (push (list (eglot-uri-to-path uri) edits)
- prepared)))
- (when prepared
- (list title
- (mapcar
- (pcase-lambda (`(,file ,edits . ,_))
- (let ((buf (find-file-noselect file)))
- (cons buf
- (seq-map (eglot--lambda ((TextEdit)
- range newText)
- (pcase (with-current-buffer buf
- (eglot-range-region range))
- (`(,beg . ,end)
- (list beg end newText))))
- edits))))
- prepared))))))
+ (eglot--lambda ((CodeAction) title edit command)
+ (cond
+ (edit
+ (eglot--dbind
+ ((WorkspaceEdit) changes documentChanges)
+ edit
+ (let ((prepared
+ (mapcar
+ (eglot--lambda ((TextDocumentEdit) textDocument edits)
+ (eglot--dbind ((VersionedTextDocumentIdentifier)
+ uri version)
+ textDocument
+ (list (eglot-uri-to-path uri) edits version)))
+ documentChanges)))
+ (unless (and changes documentChanges)
+ (cl-loop for (uri edits) on changes by #'cddr
+ do (push (list (eglot-uri-to-path uri) edits)
+ prepared)))
+ (when prepared
+ (list title
+ (mapcar
+ (pcase-lambda (`(,file ,edits . ,_))
+ (let ((buf (find-file-noselect file)))
+ (cons buf
+ (seq-map (eglot--lambda ((TextEdit)
+ range newText)
+ (pcase (with-current-buffer buf
+ (eglot-range-region range))
+ (`(,beg . ,end)
+ (list beg end newText))))
+ edits))))
+ prepared))))))
+ (command
+ (list title
+ (lambda ()
+ (eglot--request server :workspace/executeCommand command))))))
actions)))))
(defun eglot--diag-range-region (range)
when (alist-get tag eglot--tag-faces)
collect it)))
`((face . ,faces)))
- #'eglot--flymake-fix)))
+ (apply-partially #'eglot--flymake-fix server))))
into diags
finally (cond ((and
;; only add to current report if Flymake
FIX-FUNCTION, if non-nil, is a function that takes DATA and returns a
list of fix suggestions for this diagnostic. Each fix suggestion is a
list (TITLE EDITS), where TITLE is a string describing the fix and EDITS
-is a list of (FILE-OR-BUFFER . CHANGES) cons cells, where FILE-OR-BUFFER
-is the file name or buffer to edit, and CHANGES is a list of changes to
-perform in FILE-OR-BUFFER. Each element of CHANGES is in turn a
-list (BEG END STR), where BEG and END are buffer positions to delete and
-STR is the string to insert at BEG afterwards."
+is a list of edits in the format that `refactor-apply-edits' expects.
+Alternatively, EDITS can also be a function of no arguments that
+performs the fix."
(when (stringp locus)
(setq locus (expand-file-name locus)))
(flymake--diag-make :locus locus :beg beg :end end
(i 1))
(dolist (fix fixes)
(define-key menu (vector (intern (format "flymake-fix-%d" i)))
- `(menu-item ,(format "Fix: %s" (car fix))
- ,(lambda ()
- (interactive)
- (refactor-apply-edits (cadr fix)))
- ,@(cddr fix)))
+ `(menu-item
+ ,(format "Fix: %s" (car fix))
+ ,(let ((edits (cadr fix)))
+ (if (functionp edits)
+ (lambda () (interactive) (funcall edits))
+ (lambda () (interactive) (refactor-apply-edits edits))))
+ ,@(cddr fix)))
(cl-incf i)))
menu)
(if-let ((diags (flymake-diagnostics pos)))
(if-let ((diag (seq-find #'flymake--diag-fix-function diags))
(fixes (funcall (flymake--diag-fix-function diag)
- (flymake--diag-data diag))))
- (refactor-apply-edits
- (car (if (cdr fixes)
- (alist-get
- (completing-read (format-prompt "Fix" (caar fixes))
- fixes nil t nil nil (caar fixes))
- fixes nil nil #'string=)
- (cdar fixes))))
+ (flymake--diag-data diag)))
+ (edits (car (if (cdr fixes)
+ (alist-get
+ (completing-read (format-prompt "Fix" (caar fixes))
+ fixes nil t nil nil (caar fixes))
+ fixes nil nil #'string=)
+ (cdar fixes)))))
+ (if (functionp edits) (funcall edits) (refactor-apply-edits edits))
(message "No fix available for this diagnostic"))
(user-error "No diagnostic at this position")))