8

I have packages variables that have list of github users and package names.

(defvar packages '('("auto-complete" . "auto-complete")
                   ("defunkt" . "markdown-mode")))

I want to git clone if the file is not exist yet.

(defun git-clone (author name)
  (let* ((repo-url (concat "git@github.com:" author "/" name ".git")))
    (print repo-url)
    (unless (file-exists-p (concat "~/.emacs.d/git/" name))
      (shell-command (concat "git clone " repo-url " ~/.emacs.d/git/" name)))))

And I want to apply git-clone to all packages variable to packages list. But I could not figure out how to apply with arguments.

; This obviously doesn't work
(mapcar `git-clone `packages)
  • 2
    By the way, you have an extra ' in your defvar declaration. – Dan Dec 13 '15 at 13:57
  • 1
    FWIW, this has got to be a duplicate, but I don't have time to search for it. ;-) – Drew Dec 13 '15 at 17:44
8

You can create an anonymous lambda function to take each element of your list and apply your function to it.

Example:

(defvar packages '(("auto-complete" . "auto-complete")
                   ("defunkt" . "markdown-mode")))

(defun toy-fnx (author name)
  "Just testing."
  (message "Package %s by author %s" name author)
  (sit-for 1))

(mapcar (lambda (package)
          (funcall #'toy-fnx (car package) (cdr package)))
        packages)

Note that, if you don't care about the return values (ie, your function is only for side effects, which appears to be the case here), you can use mapc in place of mapcar:

(mapc (lambda (package)
        (funcall #'toy-fnx (car package) (cdr package)))
      packages)

For your specific purposes, a loop may be simplest:

(cl-dolist (package packages)      ; or dolist if you don't want to use cl-lib
  (funcall #'toy-fnx (car package) (cdr package)))
  • There's no advantage to cl-dolist over plain dolist here. – npostavs Dec 13 '15 at 14:09
  • @npostavs: edited. – Dan Dec 13 '15 at 14:30
  • Thanks! I totally forgot about funcall. – ironsand Dec 13 '15 at 15:00
  • 3
    Hmm, I skipped over the funcall before, but looking again it seems redundant, why not just call toy-fnx directly? – npostavs Dec 13 '15 at 15:24
  • @npostavs: correct. It was just a way to illustrate mapcar and friends. – Dan Dec 13 '15 at 16:26
9

If you're happy using dash.el you can use -each and destructuring -let:

(require 'dash)

(--each packages
  (-let [(author . name) it]
    (git-clone author name)))

Alternatively, you can use -lambda from dash.el to create an anonymous function with destructuring:

(mapcar
 (-lambda ((author . name)) (git-clone author name))
 packages)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.