How can I map an unknown list of args to start-pro

2019-02-27 10:08发布

问题:

I'm finally trying to learn elisp but haven't wrapped my head around how to map an unknown list of arguments to variables dynamically.

Here's a working function that passes up to three arguments to start-process. But I would like to pass an infinite number of args to the function.

(defun create-drush-buffer (command &rest a)
  (if (locate-dominating-file default-directory "includes/bootstrap.inc")
      (progn
        (setq opt1 (car a))
        (setq opt2 (cadr a))
        (setq opt3 (caddr a))
        (setq allopt (concat opt1 " " opt2 " " opt3))
        (setq b-name (concat "*drush " command " " allopt "*"))
        (if (buffer-live-p b-name)
            (switch-to-buffer b-name)
          (setq d-buffer (get-buffer-create  b-name))
          (with-current-buffer d-buffer
            (goto-char (point-min))
            (view-mode 1)
            (hl-line-mode 1)
            (if opt3
                (start-process "drush" (current-buffer) drupal-drush-program
                               command
                               opt1
                               opt2
                               opt3)
              (if opt2
                  (start-process "drush" (current-buffer)
                                 drupal-drush-program
                                 command
                                 opt1
                                 opt2)
                (if opt1
                    (start-process "drush" (current-buffer)
                                   drupal-drush-program
                                   command
                                   opt1)
                  (start-process "drush" (current-buffer)
                                 drupal-drush-program
                                 command))))
            (shrink-window-if-larger-than-buffer))
          (switch-to-buffer d-buffer)))
    (message (concat default-directory " is not a drupal project"))))

Here's an example of a calling function I would like to work with create-drush-buffer.

(defun drush-sql-sync ()
  (interactive)
  (create-drush-buffer
   "sql-sync"
   "-y"
   "-d"
   "-v"
   "@cu.wstage1-education"
  "@cu.local-education"))

How can I achieve this and make my code less redundant? Any help with code or even steering me to relevant documentation appreciated.

回答1:

You can use apply:

(apply FUNCTION &rest ARGUMENTS)

Call FUNCTION with our remaining args, using our last arg as list of args. Then return the value FUNCTION returns. Thus, (apply '+ 1 2 '(3 4)) returns 10.

This way, you could call start-process using something like:

(apply 'start-process "drush" (current-buffer)
                             drupal-drush-program
                             command
                             a)

As a side note, you should not create temporary variables using setq, as this creates or modified global variables (if no local ones with the name exists). Instead, use let.

Good luck with your elisp projects!



标签: elisp