Skip to content

Commit 6534f73

Browse files
add support for refactor command
introduced by microsoft/TypeScript#15569
1 parent cf618f9 commit 6534f73

File tree

2 files changed

+53
-8
lines changed

2 files changed

+53
-8
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ at point.
145145

146146
<kbd>M-x tide-fix</kbd> Apply code fix for the error at point.
147147

148+
<kbd>M-x tide-refactor</kbd> Refactor code at point.
149+
148150
### Features
149151

150152
* ElDoc

tide.el

+51-8
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,9 @@ above."
126126
:type 'boolean
127127
:group 'tide)
128128

129-
(defcustom tide-allow-popup-select '(code-fix)
129+
(defcustom tide-allow-popup-select '(code-fix refactor)
130130
"The list of commands where popup selection is allowed."
131-
:type '(set (const code-fix) (const jump-to-implementation))
131+
:type '(set (const code-fix) (const jump-to-implementation) (const refactor))
132132
:group 'tide)
133133

134134
(defmacro tide-def-permanent-buffer-local (name &optional init-value)
@@ -236,6 +236,9 @@ ones and overrule settings in the other lists."
236236
(defun tide-tsserver-version-not-supported ()
237237
(error "Only tsserver 2.0 or greater is supported. Upgrade your tsserver or use older version of tide."))
238238

239+
(defun tide-tsserver-feature-not-supported (min-version)
240+
(error "tsserver %S or greater is required for this feature." min-version))
241+
239242
(defmacro tide-on-response-success (response &rest body)
240243
(declare (indent 1))
241244
`(if (tide-response-success-p ,response)
@@ -834,6 +837,13 @@ Noise can be anything like braces, reserved keywords, etc."
834837

835838
;;; Code-fixes
836839

840+
(defun tide-apply-code-edits (file-code-edits)
841+
(save-excursion
842+
(dolist (file-code-edit file-code-edits)
843+
(with-current-buffer (find-file-noselect (plist-get file-code-edit :fileName))
844+
(tide-format-regions (tide-apply-edits (plist-get file-code-edit :textChanges)))
845+
(basic-save-buffer)))))
846+
837847
(defun tide-get-flycheck-errors-ids-at-point ()
838848
(-map #'flycheck-error-id (flycheck-overlay-errors-at (point))))
839849

@@ -845,12 +855,7 @@ Noise can be anything like braces, reserved keywords, etc."
845855

846856
(defun tide-apply-codefix (fix)
847857
"Apply a single `FIX', which may apply to several files."
848-
(let ((file-changes (plist-get fix :changes)))
849-
(save-excursion
850-
(dolist (file-change file-changes)
851-
(with-current-buffer (find-file-noselect (plist-get file-change :fileName))
852-
(tide-format-regions (tide-apply-edits (plist-get file-change :textChanges)))
853-
(basic-save-buffer))))))
858+
(tide-apply-code-edits (plist-get fix :changes)))
854859

855860

856861
(defun tide-fix ()
@@ -866,6 +871,44 @@ Noise can be anything like braces, reserved keywords, etc."
866871
(t (tide-apply-codefix
867872
(tide-select-item-from-list "Select fix: " fixes #'tide-get-fix-description (tide-can-use-popup-p 'code-fix)))))))))
868873

874+
;;; Refactor
875+
876+
(defun tide-command:getEditsForRefactor (refactor action)
877+
(tide-send-command-sync "getEditsForRefactor"
878+
`(:refactor ,refactor :action ,action :file ,buffer-file-name :line ,(tide-line-number-at-pos) :offset ,(tide-current-offset))))
879+
880+
(defun tide-command:getApplicableRefactors ()
881+
(tide-send-command-sync "getApplicableRefactors" `(:file ,buffer-file-name :line ,(tide-line-number-at-pos) :offset ,(tide-current-offset))))
882+
883+
(defun tide-get-refactor-description (refactor)
884+
(plist-get refactor :description))
885+
886+
(defun tide-select-refactor (applicable-refactor-infos)
887+
(let ((available-refactors
888+
(-mapcat
889+
(lambda (applicable-refactor-info)
890+
(-map (lambda (refactor-action-info)
891+
`(:action ,(plist-get refactor-action-info :name)
892+
:refactor ,(plist-get applicable-refactor-info :name)
893+
:inlineable ,(plist-get applicable-refactor-info :inlineable)
894+
:description ,(plist-get refactor-action-info :description)))
895+
(plist-get applicable-refactor-info :actions)))
896+
applicable-refactor-infos)))
897+
(tide-select-item-from-list "Select refactor: " available-refactors #'tide-get-refactor-description (tide-can-use-popup-p 'refactor))))
898+
899+
(defun tide-apply-refactor (selected)
900+
(let ((response (tide-command:getEditsForRefactor (plist-get selected :refactor) (plist-get selected :action))))
901+
(tide-on-response-success response
902+
(tide-apply-code-edits (tide-plist-get response :body :edits)))))
903+
904+
(defun tide-refactor ()
905+
"Refactor code at point"
906+
(interactive)
907+
(let ((response (tide-command:getApplicableRefactors)))
908+
(cond ((tide-command-unknown-p response) (tide-tsserver-feature-not-supported "2.4"))
909+
((tide-response-success-p response) (tide-apply-refactor
910+
(tide-select-refactor (plist-get response :body))))
911+
(t (message "No refactors available.")))))
869912

870913
;;; Auto completion
871914

0 commit comments

Comments
 (0)