2011-10-17 21 views

risposta

32

di tripleee è un esempio pratico di errore gestione, ma non necessario in questo caso.

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

Che 'noerror può essere qualsiasi valore non nullo, ma ovviamente è più descrittivo in questo modo. Spesso vedo anche lo :noerror, ma non ho idea se ci sia un particolare vantaggio nell'usare un argomento di parole chiave su un simbolo (commenti, chiunque? Sono abbastanza interessato a sapere).

richiedono è una funzione incorporata in C source code.

(FEATURE richiedono & opzionale FILENAME NOERROR)

Se l'elemento FEATURE non è caricato, caricarlo da FILENAME.
Se FEATURE non è un membro della lista features, la funzione
non viene caricata; quindi carica il file FILENAME.
Se NOMEFILE viene omesso, l'printname di FEATURE viene utilizzato come il nome del file,
e load cercherà di caricare questo nome seguita dal suffisso .elc o
.el, in questo ordine. Il nome senza suffisso aggiunto non verrà utilizzato.
Vedere get-load-suffixes per l'elenco completo dei suffissi.
Se il terzo argomento opzionale NOERROR è diverso da zero,
, restituire nil se il file non viene trovato invece di segnalare un errore.
Normalmente il valore di ritorno è FEATURE.
I messaggi normali all'inizio e alla fine del caricamento di FILENAME vengono eliminati.

+1

Per quello che vale, il controllo è solo per vedere se "noerror" è definito, quindi qualsiasi valore non nullo funzionerà. Sto usando 't' me stesso. – clintm

+4

: noerror è lo stile common-lisp. Che è più bello :-). – user239558

+0

Questo non funziona con 'AUCTeX' perché' AUCTeX' non può essere richiesto. È necessario usare 'package-installed-p' per' AUCTeX' –

6

Il (require) genera un errore se non riesce. Questo dovrebbe essere tutto ciò di cui hai bisogno.

Se si desidera configurare il comportamento di ECB solo quando è disponibile, cercare principalmente di aggiungere elementi a ecb-hook - questo è il modo normale di configurare un pacchetto Emacs in modo condizionale.

Se nessun gancio è disponibile, o se si vuole a rotolare a mano per qualche motivo, provare qualcosa di simile

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

Se davvero si vuole veramente a rotolare tutto a mano, è possibile intercettare l'errore da un fallito require come questo:

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

si noti che il condition-case cattura qualsiasi file-error dall'interno del progn modo si vuole fare in modo di non fare altre operazioni sui file al suo interno. In definitiva si può decidere di mettere solo il require all'interno di un condition-case e l'uso che come condizione per la forma originale if, ma questo è già sfuggendo di mano ... risposta

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

'eval-after-load' sembra non caricare il pacchetto. Così ho cambiato la risposta qui sotto: (quando (...)) – Vivodo

+0

Sì, lo scopo di 'eval-after-load' è quello di specificare un'azione di rinvio da eseguire se e quando si carica il pacchetto specificato. È utile per evitare impostazioni non necessarie quando si avvia Emacs per un'attività che non comporta il caricamento di 'ecb' (la compilazione di byte batch è un esempio perenne). – tripleee

3

Perché non utilizzare "featurep"?

(featurep FEATURE &optional SUBFEATURE) 

Restituisce t se FEATURE è presente in questo Emacs.

(if (featurep 'ecb) 
    (message "ECB is there!")) 
+1

Questo è applicabile solo alle funzionalità che sono già state caricate (e quindi è meno rilevante per questa particolare domanda). – phils

1

La risposta più semplice è quello di utilizzare require e eval-after-load come detto in altre risposte.

Tuttavia ciò non è sempre conveniente, ad esempio in una funzione chiamata da un hook di modalità che desidera attivare un'altra modalità secondaria ma solo se il pacchetto per esso è installato. In questo caso è rilevante featurep.

I pacchetti Emacs utilizzano sempre più il caricamento automatico per migliorare i tempi di avvio. Se si verifica la presenza di un pacchetto utilizzando require, si consuma il costo del caricamento dei file. Se si utilizzano pacchetti ELPA/MELPA/Marmalade (disponibili per impostazione predefinita dalla versione 24), molti pacchetti potrebbero essere disponibili in uno stato ancora non scaricato, ma un pacchetto foo con caricamento automatico fornirà una funzionalità foo-autoloads. Ho scritto una funzione che è utile per verificare se un pacchetto è disponibile in termini di già caricato o impostato per il caricamento automatico.

 
(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

Quattro anni di ritardo su questa domanda, ma ... ecco una semplice macro che farà questo per voi.

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

Ad esempio:

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

Ecco un'altra versione con un caso "altro", nel caso in cui è necessario gestire anche quello.

(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)) 
1

Per persone chiedendo come verificare se è stato installato un pacchetto package.el, utilizzare package-installed-p.

Problemi correlati