From 63be1ca8653c137d12f6753fa93703c103a6732b Mon Sep 17 00:00:00 2001 From: Eric James Michael Ritz Date: Wed, 22 Aug 2018 11:50:09 -0400 Subject: [PATCH] [WIP] Refactor the definitions of RPC functions ---------------------------------------------------------------- IMPORTANT: This code is unfinished and needs a lot more testing. Developers should not build off this commit because it is highly likely we will rebase it once we address all problems. ---------------------------------------------------------------- We define a number of functions whose sole purpose is to invoke Phpactor's RPC commands. The majority of these functions are the same. That is, their only real difference is the name of the RPC command and what we pass to our `phpactor--rpc` function. This patch refactors that code for multiple purposes. 1. We now only need to change one place to add support for a new command: the 'phpactor--rpc-command-data' list. The exception to this are the few RPC commands like "echo" which require additional arguments. It seemed easier to leave those few functions as they are instead of trying to shoe-horn support for a corner case into our now macro. 2. The new 'phpactor-defrpc' macro automatically creates the functions we previously wrote by hand. This both reduces bloat and decreases chances for errors, since now our code for such functions is all in one place: the macro definition itself. 3. We create a list of relevant data about the RPC commands which we can loop over, apply our new macro to each. This lets us introduce support for a new RPC command by modifying a single line in a list as opposed to writing an entire function. (Again, the exception are those few commands like "echo" which require additional arguments.) --- phpactor.el | 89 +++++++++++++++++++++++++---------------------------- 1 file changed, 42 insertions(+), 47 deletions(-) diff --git a/phpactor.el b/phpactor.el index 47e1ae2..8d49961 100644 --- a/phpactor.el +++ b/phpactor.el @@ -491,47 +491,55 @@ function." ;; ;; See https://phpactor.github.io/phpactor/rpc.html#phpactor-commands -;;;###autoload -(defun phpactor-copy-class () - "Execute Phpactor RPC copy_class command." - (interactive) - (let ((arguments (phpactor--command-argments :source_path))) - (apply #'phpactor-action-dispatch (phpactor--rpc "copy_class" arguments)))) +(defmacro phpactor-defrpc (name command-arguments) + "Define a function which calls a Phpactor RPC command. -;;;###autoload -(defun phpactor-move-class () - "Execute Phpactor RPC move_class command." - (interactive) - (let ((arguments (phpactor--command-argments :source_path))) - (apply #'phpactor-action-dispatch (phpactor--rpc "move_class" arguments)))) +The NAME must be the name of the RPC command as a string, +e.g. 'classs_search', with underscores if needed. The macro will +convert those underscores to dashes for the function name, +e.g. it would define the function 'phpactor-class-search' given +the example NAME above. -;;;###autoload -(defun phpactor-offset-info () - "Execute Phpactor RPC offset_info command." - (interactive) - (let ((arguments (phpactor--command-argments :source :offset))) - (apply #'phpactor-action-dispatch (phpactor--rpc "offset_info" arguments)))) +The COMMAND-ARGUMENTS must be a list of symbols acceptable to the +`phpactor--command-argments' function. Even if there is only one +argument, it must be in a list nonetheless. -;;;###autoload -(defun phpactor-transform () - "Execute Phpactor RPC transform command." - (interactive) - (let ((arguments (phpactor--command-argments :source :path))) - (apply #'phpactor-action-dispatch (phpactor--rpc "transform" arguments)))) +For example: + + (phpactor-defrpc \"class_search\" '(:source_path)) + +This will create a function, `phpactor-class-search', which will +invoke the 'class_search' Phpactor RPC command. The resulting +function will accept no arguments. And it will have a generic +docstring. + +See `phpactor--rpc-command-data' for a list of the data we pass along +to this macro." + (let ((function-name (intern (concat "phpactor-" (replace-regexp-in-string "_" "-" name))))) + `(defun ,function-name () + ,(format "Execute Phpactor RPC %s command." name) + (interactive) + (let ((arguments ((phpactor--command-argments ,@command-arguments)))) + (apply #'phpactor-action-dispatch (phpactor--rpc ,name arguments)))))) ;;;###autoload -(defun phpactor-context-menu () - "Execute Phpactor PRC context_menu command." - (interactive) - (let ((arguments (phpactor--command-argments :source :offset :current_path))) - (apply #'phpactor-action-dispatch (phpactor--rpc "context_menu" arguments)))) +(defconst phpactor--rpc-command-data + '(("complete" . ()) + ("class_search" . ()) + ("copy_class" . (:source_path)) + ("move_class" . (:source_path)) + ("offset_info" . (:source :offset)) + ("transform" . (:source :path)) + ("context_menu" . (:source :offset :current_path)) + ("navigate" . (:source_path)) + ("status" . ()) + ("goto_definition" . (:source :offset :path))) + "A list of all Phpactor RPC commands and the respective data +necessary for `phpactor-defrpc' to create functions for each.") ;;;###autoload -(defun phpactor-navigate () - "Execute Phpactor RPC navigate command." - (interactive) - (let ((arguments (phpactor--command-argments :source_path))) - (apply #'phpactor-action-dispatch (phpactor--rpc "navigate" arguments)))) +(dolist (rpc-data phpactor--rpc-command-data) + (phpactor-defrpc (car rpc-data) (cdr rpc-data))) ;;;###autoload (defun phpactor-echo (message) @@ -540,19 +548,6 @@ function." (let ((phpactor-action--message-format "Message from Phpactor: %s")) (apply #'phpactor-action-dispatch (phpactor--rpc "echo" (list :message message))))) -;;;###autoload -(defun phpactor-status () - "Execute Phpactor RPC status command, and pop to buffer." - (interactive) - (apply #'phpactor-action-dispatch (phpactor--rpc "status" []))) - -;;;###autoload -(defun phpactor-goto-definition () - "Execute Phpactor RPC goto_definition command." - (interactive) - (let ((arguments (phpactor--command-argments :source :offset :path))) - (apply #'phpactor-action-dispatch (phpactor--rpc "goto_definition" arguments)))) - ;;;###autoload (defun phpactor-import-class (name) "Execute Phpactor PRC import_class command for class NAME."