पैकेज नामों की सूची निर्दिष्ट करके स्वचालित रूप से Emacs संकुल कैसे स्थापित करें?


123

मैं packageअपने Emacs एक्सटेंशन का प्रबंधन करने के लिए उपयोग कर रहा हूं । विभिन्न कंप्यूटरों पर मेरी Emacs सेटिंग्स को सिंक्रनाइज़ करने के लिए, मैं .emacsफ़ाइल में पैकेज नामों की सूची निर्दिष्ट करने का एक तरीका चाहूंगा और फिर packageस्वचालित रूप से पैकेजों को खोज और स्थापित कर सकता हूं, ताकि मुझे कॉल करके मैन्युअल रूप से इंस्टॉल करने की आवश्यकता न हो M-x package-list-packages। उसको कैसे करे?


6
यदि आप अपने कॉन्फ़िगरेशन को स्थापित करने के लिए पैकेज प्रबंधक पर भरोसा कर रहे हैं, तो आप संभवतः सटीक संस्करण निर्दिष्ट करना चाहेंगे (और यदि यह संभव नहीं है, तो संस्करण नियंत्रण में सब कुछ संग्रहीत करने पर विचार करें), अन्यथा पुस्तकालयों के अपडेट होने और शुरू होने पर आप संरक्षित नहीं होते हैं संघर्ष करना।
फिल्स

जवाबों:


107
; list the packages you want
(setq package-list '(package1 package2))

; list the repositories containing them
(setq package-archives '(("elpa" . "http://tromey.com/elpa/")
                         ("gnu" . "http://elpa.gnu.org/packages/")
                         ("marmalade" . "http://marmalade-repo.org/packages/")))

; activate all the packages (in particular autoloads)
(package-initialize)

; fetch the list of packages available 
(unless package-archive-contents
  (package-refresh-contents))

; install the missing packages
(dolist (package package-list)
  (unless (package-installed-p package)
    (package-install package)))

7
मैं पसंद करता हूं: (या (फ़ाइल-मौजूद-पी-पैकेज-उपयोगकर्ता-डीआईआर) (पैकेज-रिफ्रेश-सामग्री)) स्वीकृत उत्तर से। यहां रीफ्रेश किए गए पैकेज में सिस्टम पर स्टार्टअप टाइम बढ़ जाता है, जिसमें पहले से ही पैकेज इंस्टॉल होते हैं। इस जवाब के बाकी सही है, यद्यपि।
rfinz

चर के रूप में प्रतीक का मूल्य शून्य है: पैकेज-संग्रह-सामग्री। क्या कोई तरीका है कि मैं .emacs में एक सूची बना सकता हूं और सूची में सभी पैकेजों को स्थापित करने के लिए इसमें परिभाषित फ़ंक्शन का उपयोग कर सकता हूं (छोड़ें यदि स्थापित किया गया है, तो पुराना हो तो अपडेट करें) जैसे Vimle for Vim। चूँकि मैं सभी पैकेजों को elpa / github में धकेलना नहीं चाहता, इसलिए मुझे हर बार ऐसा करना होगा जब पैकेज को अपडेट किया जाए package
कोडिचन

आपका क्या मतलब है @rfinz? ऐसा लगता है package-refresh-contentsकि पैकेज स्थापित नहीं होने पर ही चलाया जाएगा? कैसे है (or (file-exists-p package-user-dir))बेहतर / कैसे यह और भी संकुल स्थापित कर रहे हैं अगर जाँच करता है?
स्टार्ट

@Startec हाँ आप सही हैं! यह देखने के लिए जांचता है कि क्या उपयोगकर्ता की पैकेज निर्देशिका मौजूद है, और यदि यह नहीं चलता है package-refresh-contents। यह संभवत: केवल पहली बार चला होगा जब आप एक नए कंप्यूटर पर emacs खोलेंगे, और मैं इसके साथ ठीक हूं। यदि एक पैकेज को अपडेट करने की आवश्यकता है जो मैन्युअल रूप से किया जा सकता है।
rfinz

2
यदि आप पहले से ही उपयोग कर रहे हैं use-package, तो आप :ensureसंकुल को स्वचालित रूप से स्थापित करने के लिए खोजशब्द का उपयोग कर सकते हैं । यह भी सेट करता है package-selected-packagesयदि आपको अनुकूलित या प्रोग्राम के माध्यम से पैकेज सूची तक पहुंचने की आवश्यकता है।
निक मैक्युरी

45

प्रोफेसरपत्स की टिप्पणियों और नीचे दिए गए जवाबों के आधार पर:

(defun ensure-package-installed (&rest packages)
  "Assure every package is installed, ask for installation if it’s not.

Return a list of installed packages or nil for every skipped package."
  (mapcar
   (lambda (package)
     ;; (package-installed-p 'evil)
     (if (package-installed-p package)
         nil
       (if (y-or-n-p (format "Package %s is missing. Install it? " package))
           (package-install package)
         package)))
   packages))

;; make sure to have downloaded archive description.
;; Or use package-archive-contents as suggested by Nicolas Dudebout
(or (file-exists-p package-user-dir)
    (package-refresh-contents))

(ensure-package-installed 'iedit 'magit) ;  --> (nil nil) if iedit and magit are already installed

;; activate installed packages
(package-initialize)

2
है कि ... साइड इफेक्ट के साथ एक नक्शा? और आलस्य का दुरुपयोग or? ओह वाह।
प्रोफ़ेसटच

1
खैर, mapcसाइड इफेक्ट के लिए है। लेकिन उपयोग क्यों नहीं unless?
प्रोफैट्सैच

पहले मैंने इस कोड का उपयोग किया था और कभी-कभी यह किसी अज्ञात कारण से काम नहीं करता था "पैकेज ब्ला-ब्लाह इंस्टॉलेशन के लिए उपलब्ध नहीं है" (यहां ब्ला-ब्ला हमेशा सूची का पहला तत्व है)। यदि मैं पहले पैकेज को मैन्युअल रूप से स्थापित करता हूं, तो सब कुछ ठीक काम करता है, लेकिन यह एक समाधान नहीं है। वैसे भी, निकोलस डूडोबिस का जवाब ठीक काम करता है।
avp

मुझे (package-initialize)इस संदर्भ से पहले जरूरत थीpackage-user-dir
फ्रैंक हेनार्ड

3
इसलिए हम वास्तव में उन पैकेजों को सूचीबद्ध करते हैं जिन्हें हम स्थापित करना चाहते हैं?
एंड्री Drozdyuk

41

Emacs 25.1+ स्वचालित रूप से अनुकूलन package-selected-packagesचर में उपयोगकर्ता-स्थापित पैकेज का ट्रैक रखेगा । package-installअनुकूलित चर को अद्यतन करेगा, और आप package-install-selected-packagesफ़ंक्शन के साथ सभी चयनित पैकेजों को स्थापित कर सकते हैं ।

इस दृष्टिकोण का एक और सुविधाजनक लाभ यह है कि आप उन package-autoremoveपैकेजों को स्वचालित रूप से हटाने के लिए उपयोग कर सकते हैं जो इसमें शामिल नहीं हैं package-selected-packages(हालांकि यह निर्भरता को बनाए रखेगा)।

(package-initialize)
(unless package-archive-contents
  (package-refresh-contents))
(package-install-selected-packages)

स्रोत: http://endlessparentheses.com/new-in-package-el-in-emacs-25-1-user-selected-packages.html


17

यहाँ मैं Emacs प्रस्तावना के लिए उपयोग किए जाने वाला कोड है :

(require 'package)
(require 'melpa)
(add-to-list 'package-archives
             '("melpa" . "http://melpa.milkbox.net/packages/") t)
(package-initialize)

(setq url-http-attempt-keepalives nil)

(defvar prelude-packages
  '(ack-and-a-half auctex clojure-mode coffee-mode deft expand-region
                   gist haml-mode haskell-mode helm helm-projectile inf-ruby
                   magit magithub markdown-mode paredit projectile
                   python sass-mode rainbow-mode scss-mode solarized-theme
                   volatile-highlights yaml-mode yari yasnippet zenburn-theme)
  "A list of packages to ensure are installed at launch.")

(defun prelude-packages-installed-p ()
  (loop for p in prelude-packages
        when (not (package-installed-p p)) do (return nil)
        finally (return t)))

(unless (prelude-packages-installed-p)
  ;; check for new packages (package versions)
  (message "%s" "Emacs Prelude is now refreshing its package database...")
  (package-refresh-contents)
  (message "%s" " done.")
  ;; install the missing packages
  (dolist (p prelude-packages)
    (when (not (package-installed-p p))
      (package-install p))))

(provide 'prelude-packages)

यदि आप MELPA का उपयोग नहीं कर रहे हैं, तो आपको इसकी आवश्यकता नहीं है (और यदि आप करते हैं, तो आप melpa.elअपने load-path(या ZELPA के माध्यम से स्थापित) हो गए हैं। पैकेज db को हर बार ताज़ा नहीं किया जाता है (क्योंकि यह स्टार्टअप को काफी धीमा कर देगा। ) - केवल जहाँ मौजूद संकुल की स्थापना रद्द की जाती है।


यदि आपका जवाब आधार पर, मैं यह थोड़ा संशोधित और 'पाश' उपयोग हटा दिया है github.com/slipset/emacs/blob/master/ensure-packages.el
slipset

हाँ, इस उदाहरण की तुलना में यह वास्तव में अधिक जटिल है। वर्तमान में मैं Prelude में जो कोड उपयोग करता हूं वह बहुत सरल है।
बोहिदर बटसोव

7

किसी ने अभी तक कास्क का उल्लेख नहीं किया है, लेकिन यह इस कार्य के लिए काफी उपयुक्त है।

मूल रूप से आप ~/.emacs.d/Caskउन पैकेजों की सूची बनाते हैं जिन्हें आप इंस्टॉल करना चाहते हैं। उदाहरण के लिए:

(source melpa)
(depends-on "expand-region")
(depends-on "goto-last-change")
; ... etc

caskकमांड लाइन से रनिंग इन पैकेजों को आपके लिए, और किसी भी निर्भरता की आवश्यकता होगी।

इसके अलावा, आप स्वचालित रूप से इंस्टॉल किए गए पैकेज का उपयोग करके अपडेट कर सकते हैं cask update


मैं पिछले कुछ समय से अपने डॉटफाइल्स में पीपा का उपयोग कर रहा हूं , बढ़िया काम करता है।
एलेस्टेयर

एक दया केक को पाइथन की आवश्यकता प्रतीत होती है। मुझे आश्चर्य है कि क्या कोई एकमात्र-वैकल्पिक विकल्प है? (यह एक पैकेज में है; स्पष्ट रूप से इस पृष्ठ पर उत्तर अनिवार्य आवश्यकता को पूरा करते हैं।)
पीटर जरीक

1
: अजगर स्क्रिप्ट यदि आप चाहें तो पीपा-cli.el है, जो आपको सीधे आह्वान कर सकते हैं चारों ओर एक पतली आवरण है/path/to/emacs -Q --script /path/to/cask/cask-cli.el -- [args]
एलिस्टेयर

दिलचस्प! क्या Emacs के अंदर से इसका इस्तेमाल संभव नहीं है? मुझे लगता है कि यह इसलिए है क्योंकि यह एक देव उपकरण भी है, लेकिन यह Emacs को प्रबंधित करने के लिए Emacs से एक CLI के बाहर कदम रखना असामान्य है।
पीटर जरीक

4

package-installप्रतीक के रूप में पैकेज नाम के साथ कॉल करें । आप package-installअंतःक्रियात्मक रूप से कॉल करके और नाम पर पूरा करके अपने पैकेज के पैकेज के नाम पा सकते हैं । फ़ंक्शन package-installed-pआपको बताएगा कि क्या यह पहले से स्थापित है।

उदाहरण के लिए:

(mapc
 (lambda (package)
   (or (package-installed-p package)
       (package-install package)))
 '(package1 package2 package3))

1
धन्यवाद, लेकिन मुझे एक त्रुटि मिली error: Package + स्थापना 'के लिए उपलब्ध नहीं है। dired + एक पैकेज है जिसे मैंने आपके कोड के साथ आज़माया है।
आरएनए

dired+जब आप दौड़ते हैं तब क्या दिखाई देता है package-list-packages? मेरा मानना ​​है कि आपको मुरब्बा या मेलपा को अपने साथ जोड़ना होगा package-archives। यदि हां, तो क्या आप चला सकते हैं (package-install 'dired+)?
ataylor

उस स्थिति में, (package-installed-p 'dired+)वापस आ जाना चाहिए tऔर इसे उपरोक्त कोड में छोड़ दिया जाएगा।
ataylor

package-installed-pअकेले ठीक काम करता है, लेकिन कोड के पूरे ब्लॉक नहीं करता है। मैंने कई पैकेज की कोशिश की है।
RNA

2
लगता है कि निकोलस डूडेबाउट के जवाब में प्रस्तावना को हल किया जाएगा।
19

4
(require 'cl)
(require 'package)

(setq cfg-var:packages '(
       emmet-mode
       ergoemacs-mode
       flycheck
       flycheck-pyflakes
       monokai-theme
       py-autopep8
       py-isort
       rainbow-mode
       yafolding
       yasnippet))

(defun cfg:install-packages ()
    (let ((pkgs (remove-if #'package-installed-p cfg-var:packages)))
        (when pkgs
            (message "%s" "Emacs refresh packages database...")
            (package-refresh-contents)
            (message "%s" " done.")
            (dolist (p cfg-var:packages)
                (package-install p)))))

(add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/") t)
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t)
(add-to-list 'package-archives '("melpa-stable" . "http://stable.melpa.org/packages/") t)
(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t)
(package-initialize)

(cfg:install-packages)

3

मुझे यह जांचना पसंद है कि क्या उपयोगकर्ता इस उत्तर में पहले किए गए पैकेजों को स्थापित करना चाहता है । इसके अलावा मैं कुछ भी स्थापित करने से पहले एक बार अपने पैकेज सामग्री को ताज़ा कर रहा हूँ। मुझे यकीन नहीं है कि यह सबसे अच्छा तरीका है, लेकिन मुझे नहीं लगता कि शीर्ष उत्तर मेरे लिए कर रहे थे।

(setq required-pkgs '(jedi flycheck cider clojure-mode paredit markdown-mode jsx-mode company))

(require 'cl)

(setq pkgs-to-install
      (let ((uninstalled-pkgs (remove-if 'package-installed-p required-pkgs)))
        (remove-if-not '(lambda (pkg) (y-or-n-p (format "Package %s is missing. Install it? " pkg))) uninstalled-pkgs)))

(when (> (length pkgs-to-install) 0)
  (package-refresh-contents)
  (dolist (pkg pkgs-to-install)
    (package-install pkg)))

1

मैं कोई समस्या हुई थी कि कुछ भी नहीं जोड़ने के बाद हुआ (package-install 'org)में .emacs। मैं अप-टू-डेट संस्करण स्थापित करना चाहता था org-modeऔर बिल्ट-इन org-modeकाफी पुराना है।

मैंने package-installEmacs के स्रोत कोड को 25.3.1 से खोदा। फ़ंक्शन स्व पहले से ही जांच करता है कि पैकेज स्थापित है या नहीं और यदि पैकेज पहले से ही स्थापित है तो इसे स्थापित करने से इंकार कर दें। तो (unless (package-installed-p package) ...)उत्तर 10093312 से जांच वास्तव में के लिए बिना रुके है।

(defun package-install (pkg &optional dont-select)
  "Install the package PKG.
PKG can be a package-desc or a symbol naming one of the available packages
in an archive in `package-archives'.  Interactively, prompt for its name.

If called interactively or if DONT-SELECT nil, add PKG to
`package-selected-packages'.

If PKG is a package-desc and it is already installed, don't try
to install it but still mark it as selected."
  (interactive
   (progn
     ;; Initialize the package system to get the list of package
     ;; symbols for completion.
     (unless package--initialized
       (package-initialize t))
     (unless package-archive-contents
       (package-refresh-contents))
     (list (intern (completing-read
                    "Install package: "
                    (delq nil
                          (mapcar (lambda (elt)
                                    (unless (package-installed-p (car elt))
                                      (symbol-name (car elt))))
                                  package-archive-contents))
                    nil t))
           nil)))
  (add-hook 'post-command-hook #'package-menu--post-refresh)
  (let ((name (if (package-desc-p pkg)
                  (package-desc-name pkg)
                pkg)))
    (unless (or dont-select (package--user-selected-p name))
      (package--save-selected-packages
       (cons name package-selected-packages)))
    (if-let ((transaction
              (if (package-desc-p pkg)
                  (unless (package-installed-p pkg)
                    (package-compute-transaction (list pkg)
                                                 (package-desc-reqs pkg)))
                (package-compute-transaction () (list (list pkg))))))
        (package-download-transaction transaction)
      (message "`%s' is already installed" name))))

अंतर्निहित org-modeइनस्टॉल भी गिना जाता है और package-installELPA से नया संस्करण स्थापित करने से इंकार करता है। कुछ समय पैकेज पढ़ने में बिताने के बाद, मैं निम्नलिखित समाधान के साथ आया।

(dolist (package (package-compute-transaction
                  () (list (list 'python '(0 25 1))
                           (list 'org '(20171211)))))
  ;; package-download-transaction may be more suitable here and
  ;; I don't have time to check it
  (package-install package))

कारण यह है कि यह काम करता है package-* परिवार के कार्य अलग-अलग तर्कों को संभालते हैं, भले ही यह एक प्रतीक या package-descवस्तु हो। आप केवल ऑब्जेक्ट के package-installमाध्यम से संस्करण जानकारी निर्दिष्ट कर सकते हैं package-desc


0

यहाँ मेरा है, यह छोटा है :)

(mapc
 (lambda (package)
   (unless (package-installed-p package)
     (progn (message "installing %s" package)
            (package-refresh-contents)
            (package-install package))))
 '(browse-kill-ring flycheck less-css-mode tabbar org auto-complete undo-tree clojure-mode markdown-mode yasnippet paredit paredit-menu php-mode haml-mode rainbow-mode fontawesome))

0

यहाँ एक और तरीका है।

;; assure every package is installed
(defun ensure-package-installed (&rest packages)
  (let ((user-required-packages
         (seq-remove
          (lambda (package) (package-installed-p package))
          packages)))
    (when user-required-packages
      (package-refresh-contents)
      (dolist (package user-required-packages)
        (package-install package)))))

;; list of packages to install
(ensure-package-installed
 'try
 'which-key)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.