 ;;    more stable.
 ;; 4. No external dependencies (e.g. Cask) for plugin management.
 
-(defvar doom-packages '((quelpa-use-package))
-  "List of packages that have been explicitly installed (not dependencies) with
-`package!'. Each element is a list whose car is the package symbol, and cdr is
-its quelpa recipe, if available.")
-
-(defvar doom-modules nil
+(defvar doom-enabled-modules nil
   "List of enabled modules; each element is a cons cell (MODULE . SUBMODULE),
 where MODULE is the module's property symbol, e.g. :lang, and SUBMODULE is the
 submodule symbol, e.g. 'evil.")
 
+(defvar doom-packages nil
+  "A list of enabled packages.")
+
+(defvar doom-protected-packages '(quelpa-use-package f s dash)
+  "A list of packages that shouldn't be deleted.")
+
 (defvar doom--init nil
   "Non-nil if doom's package system has been initialized or not. It may not be
 if you have byte-compiled your configuration (as intended).")

  "If non-nil, install missing packages. Otherwise, strip :ensure and :quelpa
from `package!' calls.")

(defvar doom--dont-load-p nil
  "If non-nil, don't actually load modules, only keep track of them.")

(defvar doom--load-path (append (list doom-core-dir
                                      doom-modules-dir)

    ;; MELPA lookups by quelpa.
    (when (and recipe (= 0 (mod (length recipe) 2)))
      (push name recipe)
      (setq plist (plist-put plist :quelpa recipe)))
    (unless doom--auto-install-p
      (setq plist (use-package-plist-delete plist :ensure))
      (setq plist (use-package-plist-delete plist :quelpa)))
    ;; (package--save-selected-packages (cons name package-selected-packages))
    (pushnew name doom-packages)
    (macroexpand `(use-package ,name ,@plist))))

(defmacro load! (file-or-module-sym &optional submodule file)
  "Load a module from `doom-modules-dir'. Plays the same role as
`load-relative', but is specific to DOOM emacs modules and submodules. If
`doom--prefer-el-p' is non-nil, prefer the un-compiled elisp file.

Examples:
 (load! :lang emacs-lisp)

  Loads modules/lang/emacs-lisp/FILE.el (defaults to config.el).

 (load! +local-module)

  Loads +local-module.el relative to `__DIR__' or `doom-core-dir'."
  (let (path file)
    (cond ((null submodule)
           (setq path (or __DIR__ doom-core-dir)
                 file (concat (if (symbolp file-or-module-sym)
                                  (symbol-name file-or-module-sym)
                                file-or-module-sym)
                              ".el")))
          (t
           (setq path (doom-module-path file-or-module-sym submodule)
                 file (or file "config.el"))))
    (setq path (f-slash path)
          file (concat path file))
    `(let ((__FILE__ ,file)
           (__DIR__  ,path))
       (load (if doom--prefer-el-p ,file ,(f-no-ext file))
             nil (not doom-debug-mode) doom--prefer-el-p))))

(defun doom-module-path (module submodule &optional file)
  "Get the full path to a module: e.g. :lang emacs-lisp maps to
~/.emacs.d/modules/lang/emacs-lisp/. Will append FILE if non-nil."
  (when (symbolp module)
    (setq module (symbol-name module)))
  (when (string-prefix-p ":" module)
    (setq module (substring module 1)))
  (when (symbolp submodule)
    (setq submodule (symbol-name submodule)))
  (f-expand (concat module "/" submodule "/" file)
            doom-modules-dir))


;;
;; Defuns
;;

(defun doom/refresh-autoloads ()
  "Refreshes the autoloads.el file, which tells Emacs where to find all the
autoloaded functions in the modules you use or among the core libraries.

Rerun this whenever you modify your init.el (or use `make autoloads` from the
command line)."
  (interactive)
  (unless doom--init
    (doom-reload-modules))
  (let ((generated-autoload-file (concat doom-local-dir "autoloads.el"))
        (autoload-files
         (append (-flatten (mapcar (lambda (dir)
                                     (let ((auto-dir  (f-expand "autoload" dir))
                                           (auto-file (f-expand "autoload.el" dir)))
                                       (cond ((f-directory-p auto-dir)
                                              (f-glob "*.el" auto-dir))
                                             ((f-exists-p auto-file)
                                              auto-file))))
                                   (--map (doom-module-path (car it) (cdr it)) doom-enabled-modules)))
                 (f-glob "autoload/*.el" doom-core-dir))))
    (when (f-exists-p generated-autoload-file)
      (f-delete generated-autoload-file)
      (message "Deleted old autoloads.el"))
    (dolist (file autoload-files)
      (update-file-autoloads file)
      (message "Detected: %s" (f-relative file doom-emacs-dir)))
    (with-current-buffer (get-file-buffer generated-autoload-file)
      (save-buffer))
    (load generated-autoload-file nil t t)
    (message "Done!")))

(defun doom/byte-compile ()
  "Byte (re)compile the important files in your emacs configuration (i.e.
