radian-software / straight.el

🍀 Next-generation, purely functional package manager for the Emacs hacker.
MIT License
2.71k stars 150 forks source link

Install multiple package hosted in recipe repositories (such as MELPA) with one (straight-)use-package command. #792

Closed hongyi-zhao closed 3 years ago

hongyi-zhao commented 3 years ago

On Ubuntu 20.04, according to the instruction here, I use the following settings in my Emacs init file:

;;Bootstrap straight
(defvar bootstrap-version)
(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
      (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

;; Install use-package via straight
(straight-use-package 'use-package)

;; Setting this to `t' makes it so that you don't need to include the :straight
;; keyword in use-package declarations unless you want to add/extend the package
;; installation recipe.

(setq straight-use-package-by-default t) ; straight's equivalent of `use-package-always-ensure'.

Now, I want to install multiple package hosted in recipe repositories (such as MELPA) as shown below with only one (straight-)use-package command, is it possible?

(use-package flycheck)
(use-package lsp-mode)
(use-package dash)
(use-package posframe)
(use-package s)
(use-package ein)
(use-package smartparens)
(use-package valign)
(use-package multi-term)
hongyi-zhao commented 3 years ago

Based on the code snippets here and here, I figured out the following solution with straight-use-package command:

(defvar package-list)
(setq package-list '(
       flycheck lsp-mode dash posframe
       s ein smartparens valign
       multi-term
))

(mapc (lambda(package-name)
    (straight-use-package package-name)) package-list)

But I still can't figure out the corresponding implementation with use-package command.

progfolio commented 3 years ago

Frankly, that seems a bit over-engineered. If you're using use-package, and you have straight-use-package-by-default set to t, then you can usually just do:

(use-package package-name)

Doing it this way also keeps everything in one spot. Otherwise, you'd have to maintain the list of packages and the use-package declarations separately. What's the use-case for maintaining the list of package names separately?

hongyi-zhao commented 3 years ago

(use-package package-name)

The following code doesn't work. I just want to know how to adapt my above code snippet for use-package command too:

(defvar package-list)
(setq package-list '(
       flycheck lsp-mode dash posframe
       s ein smartparens valign
       multi-term
))

(mapc (lambda(package-name)
    (use-package package-name)) package-list)

What's the use-case for maintaining the list of package names separately?

TBF, just out of my curiosity of learning the power of lisp.

progfolio commented 3 years ago

TBF, just out of my curiosity of learning the power of lisp.

That's great to hear. Emacs has a built in Intro to Programming w elisp. It's accessible via M-x info under the heading "Emacs Lisp Intro".

Unfortunately I don't have too much time to spend teaching elisp, but there are plenty of great resources out there. I'd try asking on reddit.com/r/emacs, or over on the Emacs IRC channel.

The following code doesn't work.

If you do end up reaching out to anyone on those channels, be sure to include what you expected to happen and what is actually happening.

Best of luck with it.

hongyi-zhao commented 3 years ago

Got it. Thanks for the help here and help-gnu-emacs@gnu.org. To summerize, (C-h f use-package RET) shows that use-package is a micro, while (C-h f straight-use-package RET) says that straight-use-package is a function. So, the corresponding implementation of straight-use-package for installation of multiple packages in one run with use-package is something similar to the following:

(defmacro use-multiple-packages (&rest packages)
  `(progn
    ,@(mapcar (lambda (p) `(use-package ,p))
              packages)))

(use-multiple-packages flycheck
                       dash                       
                       )

I'd try asking on reddit.com/r/emacs, or over on the Emacs IRC channel.

You're right. But I want to help myself and others everywhere as much as possible.

If you do end up reaching out to anyone on those channels, be sure to include what you expected to happen and what is actually happening.

Thank you for your sincere suggestion.

raxod502 commented 3 years ago

As a drive-by comment, the simplest possible way to achieve what you asked for is

(mapcar #'straight-use-package '(flycheck lsp-mode dash ...))

or equivalently

(defvar my-package-list '(flycheck lsp-mode dash ...))
(mapcar #'straight-use-package my-package-list)

not that that seems much nicer to me than what you had originally.

hongyi-zhao commented 3 years ago

IMO, your versions are more concise and elegant than mine. Like any other advanced and modern languages, lisp language can also do one thing in a variety of ways. But, TBF, it has a more, if not the most, abstract programming and syntax structure.