Как определить, установлен ли пакет в elisp? - PullRequest
24 голосов
/ 17 октября 2011

Я хочу настроить среду, пока конкретный пакет установлен правильно.Как проверить, установлен ли какой-либо пакет в elisp?Как то так?

1002 *

Ответы [ 6 ]

37 голосов
/ 17 октября 2011

ответ tripleee - удобный пример обработки ошибок, но в данном случае он не нужен.

(when (require 'some-library nil 'noerror)
  do-things)

То, что 'noerror может быть любым ненулевым значением, но, конечно, это более наглядно. Я часто вижу, что :noerror также используется, но я не знаю, есть ли какое-то конкретное преимущество в использовании аргумента ключевого слова над символом (комментарии, кто-нибудь? Мне интересно это знать).

require - это встроенная функция в C source code.

(требуется FEATURE и необязательный NOERROR FILENAME)

Если функция FEATURE не загружена, загрузите ее из FILENAME.
Если FEATURE не является членом списка features, то функция
не загружен; так что загружайте файл FILENAME.
Если FILENAME опущено, в качестве имени файла используется печатное имя FEATURE,
и load попытается загрузить это имя с добавлением суффикса .elc или
.el, в таком порядке. Имя без добавленного суффикса не будет использовано.
См. get-load-suffixes для получения полного списка суффиксов.
Если необязательный третий аргумент NOERROR не равен nil,
затем верните nil, если файл не найден, вместо сообщения об ошибке.
Обычно возвращаемое значение равно FEATURE.
Обычные сообщения в начале и в конце загрузки FILENAME подавляются.

8 голосов
/ 17 октября 2011

В случае сбоя (require) выдаст ошибку.Это действительно все, что вам нужно.

Если вы хотите настроить поведение ECB только тогда, когда оно доступно, обратите внимание, прежде всего, на добавление чего-либо в ecb-hook - это обычный способ условной настройки пакета Emacs.

Если нет доступного крючка или вы по какой-то причине хотите его свернуть, попробуйте что-то вроде

(eval-after-load 'ecb '(setq ecb-be-more-like-better-yes-p t))

Если вы действительно хотите бросить его вручную, вы можете поймать его в ловушкуошибка из-за сбоя require, например:

(condition-case nil
   (progn
      (require 'ecb)
      (setq ecb-be-more-like-better-yes-p t) )
   (file-error (message "ECB not available; not configuring") ))

Обратите внимание, что condition-case будет ловить любой file-error изнутри progn, поэтому вы хотите убедиться, что вы ничего не делаетедругие файловые операции внутри.В конечном итоге вы можете захотеть поместить только require в condition-case и использовать это как условие для вашей исходной формы if, но это уже выходит из-под контроля ...

(if (condition-case nil (require 'ecb) (error nil))
   (setq ecb-be-more-like-better-yes-p t)
 (message "ECB not available; not configuring") )
6 голосов
/ 24 октября 2011

Почему бы не использовать "featurep"?

(featurep FEATURE &optional SUBFEATURE)

Вернуть t, если в этом Emacs присутствует FEATURE.

(if (featurep 'ecb)
   (message "ECB is there!"))
3 голосов
/ 21 января 2017

Для людей, интересующихся, как проверить, установлен ли пакет package.el , используйте package-installed-p.

1 голос
/ 25 сентября 2012

Самый простой ответ - использовать require и eval-after-load, как указано в других ответах.

Однако это не всегда удобно, например, в функции, вызываемой ловушкой режима, которая хочет активировать другуювторостепенный режим, но только если пакет для него установлен.В этом случае имеет значение featurep.

Пакеты Emacs все чаще используют автозагрузку для сокращения времени запуска.Если вы проверяете наличие пакета с помощью require, то вы берете на себя расходы по загрузке файлов.Если используются пакеты ELPA / MELPA / Marmalade (доступны по умолчанию начиная с версии 24), тогда многие пакеты могут быть доступны в еще не выгруженном состоянии, но пакет foo с автозагрузкой обеспечит функцию foo-autoloads.Я написал функцию, которая полезна для проверки, доступен ли пакет с точки зрения уже загруженной или установленной для автозагрузки.

(defun autofeaturep (feature)
  "For a feature symbol 'foo, return a result equivalent to:
(or (featurep 'foo-autoloads) (featurep 'foo))
Does not support subfeatures."
  (catch 'result
    (let ((feature-name (symbol-name feature)))
      (unless (string-match "-autoloads$" feature-name)
        (let ((feature-autoloads (intern-soft (concat feature-name "-autoloads"))))
          (when (and feature-autoloads (featurep feature-autoloads))
            (throw 'result t))))
      (featurep feature))))
0 голосов
/ 21 августа 2016

Четыре года спустя по этому вопросу, но ... вот простой макрос, который сделает это за вас.

(defmacro when-feature-loaded (feature &rest body)
  "Executes BODY if and only if FEATURE is loaded."
  (declare (indent defun))
  `(when (featurep ,module)
    @,body))

Например:

(when-feature-loaded 'foo
  (message "foo is loaded!"))

Вот еще одна версия сслучай «иного», на случай, если вам также понадобится разобраться с этим.

(defmacro if-feature-loaded (module then-form else-form)
  "Executes THEN-FORM if and only if MODULE is already loaded, otherwise executes ELSE-FORM."
  (declare (indent 2))
  `(if (featurep ,module)
       ,then-form
     ,else-form))
...