el-get-autoloads.el 4.94 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
;;; el-get.el --- Manage the external elisp bits and pieces you depend upon
;;
;; Copyright (C) 2010-2011 Dimitri Fontaine
;;
;; Author: Dimitri Fontaine <dim@tapoueh.org>
;; URL: http://www.emacswiki.org/emacs/el-get
;; GIT: https://github.com/dimitri/el-get
;; Licence: WTFPL, grab your copy here: http://sam.zoy.org/wtfpl/
;;
;; This file is NOT part of GNU Emacs.
;;
;; Install
13
;;     Please see the README.md file from the same distribution
14

15
(require 'cl)
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
(require 'el-get-core)
(require 'autoload)

(defvar el-get-outdated-autoloads nil
  "List of package names whose autoloads are outdated")

(defun el-get-save-and-kill (file)
  "Save and kill all buffers visiting the named FILE"
  (let (buf)
    (while (setq buf (find-buffer-visiting file))
      (with-current-buffer buf
        (save-buffer)
        (kill-buffer)))))

(defun el-get-ensure-byte-compilable-autoload-file (file)
  "If FILE doesn't already exist, create it as a byte-compilable
  autoload file (the default created by autoload.el has a local
  no-byte-compile variable that suppresses byte compilation)."
  ;; If we don't explicitly strip out the no-byte-compile variable,
  ;; autoload.el will create it on demand
  (unless (file-exists-p file)
    (write-region
     (replace-regexp-in-string ";; no-byte-compile: t\n" ""
Ryan C. Thompson's avatar
Ryan C. Thompson committed
39
                               (autoload-rubric file)) nil file)))
40 41 42 43 44 45 46 47 48 49 50 51

(defun el-get-load-fast (file)
  "Load the compiled version of FILE if it exists; else load FILE verbatim"
  (load (file-name-sans-extension file) nil (not el-get-verbose)))

(defun el-get-eval-autoloads ()
  "Evaluate the autoloads from the autoload file."
  (when (and el-get-generate-autoloads
             (file-exists-p el-get-autoload-file))
    (el-get-verbose-message "el-get: evaluating autoload file")
    (el-get-load-fast el-get-autoload-file)))

52 53
(defun el-get-update-autoloads (package)
  "Regenerate, compile, and load any outdated packages' autoloads."
54 55
  (when (el-get-want-autoloads-p package)
    (message "el-get: updating autoloads for %s" package)
56

57 58 59 60 61 62 63
    (let ( ;; Generating autoloads runs theses hooks; disable then
          fundamental-mode-hook
          prog-mode-hook
          emacs-lisp-mode-hook
          ;; use dynamic scoping to set up our loaddefs file for
          ;; update-directory-autoloads
          (generated-autoload-file el-get-autoload-file))
64

65 66
      ;; make sure we can actually byte-compile it
      (el-get-ensure-byte-compilable-autoload-file generated-autoload-file)
67

68 69 70 71
      (when (el-get-package-is-installed package)
        (mapc 'update-directory-autoloads
              (remove-if-not #'file-directory-p
                             (el-get-load-path package))))
72

73
      (el-get-save-and-kill el-get-autoload-file)
74

75 76 77 78
      (when (file-exists-p el-get-autoload-file)
        (message "el-get: byte-compiling autoload file")
        (when el-get-byte-compile
          (el-get-byte-compile-file el-get-autoload-file))
79

80
        (el-get-eval-autoloads)))))
81

82 83 84 85 86 87
(defconst el-get-autoload-regexp
  (let ((tmp nil))
    (dolist (suf (get-load-suffixes))
      (unless (string-match "\\.elc" suf) (push suf tmp)))
    (concat "^[^=.].*" (regexp-opt tmp t) "\\'"))
  "copied from `update-directory-autoloads'")
88 89 90 91 92

(defun el-get-remove-autoloads (package)
  "Remove from `el-get-autoload-file' any autoloads associated
with the named PACKAGE"
  (when (file-exists-p el-get-autoload-file)
93 94 95 96 97 98 99 100 101 102 103 104
    (let* ((files (mapcan (lambda (dir)
                            (when (file-directory-p dir)
                              (directory-files dir t el-get-autoload-regexp)))
                          (el-get-load-path package)))
           (generated-autoload-file el-get-autoload-file)
           (load-names (mapcar #'autoload-file-load-name files)))
      (with-current-buffer (find-file-noselect el-get-autoload-file)
        (widen) (goto-char (point-min))
        (while (search-forward generate-autoload-section-header nil t)
          (when (member (nth 2 (autoload-read-section-header)) load-names)
            ;; We found a matching section, remove it.
            (autoload-remove-section (match-beginning 0))))))
105
    (el-get-update-autoloads package)))
106 107 108 109 110 111 112 113

(defun el-get-want-autoloads-p (package)
  "Return t iff the given PACKAGE should have its autoloads
automatically generated by el-get"
  (let ((source (el-get-package-def package)))
    (or (not (plist-member source :autoloads))
        (eq (plist-get source :autoloads) t))))

114
(defun el-get-invalidate-autoloads (&optional package)
115 116 117 118 119 120 121 122
  "Mark the named PACKAGE as needing new autoloads.  If PACKAGE
is nil, marks all installed packages as needing new autoloads."

  ;; If we're invalidating everything, try to start from a clean slate
  (unless package
    (ignore-errors
      (delete-file el-get-autoload-file)
      (delete-file
123 124 125
       (concat (file-name-sans-extension el-get-autoload-file) ".elc"))))

  (let ((packages
Ryan C. Thompson's avatar
Ryan C. Thompson committed
126 127
         (if package (list package)
           (el-get-list-package-names-with-status "installed"))))
128
    (mapc 'el-get-update-autoloads packages)))
129 130

(provide 'el-get-autoloads)