Skip to content

Commit f921a42

Browse files
add support for refactor command
introduced by microsoft/TypeScript#15569
1 parent 1a1a378 commit f921a42

File tree

2 files changed

+54
-8
lines changed

2 files changed

+54
-8
lines changed

README.md

+3
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
@@ -157,6 +159,7 @@ at point.
157159
* Compile On Save
158160
* Highlight Identifiers
159161
* Code Fixes
162+
* Code Refactor
160163

161164
### Debugging
162165

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 ignore-empty-response &rest body)
240243
(declare (indent 1))
241244
`(if (tide-response-success-p ,response)
@@ -838,6 +841,13 @@ Noise can be anything like braces, reserved keywords, etc."
838841

839842
;;; Code-fixes
840843

844+
(defun tide-apply-code-edits (file-code-edits)
845+
(save-excursion
846+
(dolist (file-code-edit file-code-edits)
847+
(with-current-buffer (find-file-noselect (plist-get file-code-edit :fileName))
848+
(tide-format-regions (tide-apply-edits (plist-get file-code-edit :textChanges)))
849+
(basic-save-buffer)))))
850+
841851
(defun tide-get-flycheck-errors-ids-at-point ()
842852
(-map #'flycheck-error-id (flycheck-overlay-errors-at (point))))
843853

@@ -849,12 +859,7 @@ Noise can be anything like braces, reserved keywords, etc."
849859

850860
(defun tide-apply-codefix (fix)
851861
"Apply a single `FIX', which may apply to several files."
852-
(let ((file-changes (plist-get fix :changes)))
853-
(save-excursion
854-
(dolist (file-change file-changes)
855-
(with-current-buffer (find-file-noselect (plist-get file-change :fileName))
856-
(tide-format-regions (tide-apply-edits (plist-get file-change :textChanges)))
857-
(basic-save-buffer))))))
862+
(tide-apply-code-edits (plist-get fix :changes)))
858863

859864

860865
(defun tide-fix ()
@@ -870,6 +875,44 @@ Noise can be anything like braces, reserved keywords, etc."
870875
(t (tide-apply-codefix
871876
(tide-select-item-from-list "Select fix: " fixes #'tide-get-fix-description (tide-can-use-popup-p 'code-fix)))))))))
872877

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

874917
;;; Auto completion
875918

0 commit comments

Comments
 (0)