       (use-package-plist-delete rest :quelpa)))
   (macroexpand-all `(use-package ,name ,@rest)))
 
-(defmacro load-internal! (module package)
-
-  )
-
-(defmacro load! (plugin)
-
-  )
-
-
-;;
-;; Commands
-;;
-
-(defun doom-package-outdated-p (package &optional inhibit-refresh)
-  "Determine whether PACKAGE (a symbol) is outdated or not. If INHIBIT-REFRESH
-is non-nil, don't run `package-refresh-contents' (which is slow. Use for batch
-processing, and run `package-refresh-contents' once, beforehand)."
-  (unless inhibit-refresh
+(defmacro load! (file-or-module-sym &optional submodule noerror)
+  "Load a module from `doom-modules-dir'. Plays the same role as
+`load-relative', but is specific to DOOM emacs modules and submodules.
+
+Examples:
+  (load! :lang emacs-lisp)  loads modules/lang/emacs-lisp/{packages,config}.el
+  (load! +local-module)     if called from ./config.el, loads ./+local-module.el
+                            Note: requires that config.el be loaded with `load!'"
+  (let* ((module-name (symbol-name file-or-module-sym))
+         (module (if (and submodule (string-prefix-p ":" module-name)) (substring module-name 1) module-name)))
+    (if submodule
+        (let ((path (concat doom-modules-dir module "/" (symbol-name submodule) "/")))
+          (macroexp-progn
+           (mapcar (lambda (file)
+                     (when (file-exists-p (concat path file ".el"))
+                       (doom--load path file (not doom-debug-mode))))
+                   (append (list "packages")
+                           (unless noninteractive (list "config"))))))
+      (let ((path (concat (f-dirname load-file-name) "/")))
+        (doom--load path module (not doom-debug-mode))))))
+
+(defvar __DIR__ nil "The directory of the currently loaded file (with `load!')")
+(defvar __FILE__ nil "The full path of the currently loaded file (with `load!')")
+
+(defun doom--load (path file &optional noerror)
+  `(let ((__FILE__ ,(concat path file (if noninteractive ".el")))
+         (__DIR__ ,path))
+     (load __FILE__ nil ,noerror noninteractive noninteractive)))
+
+(defun doom-package-outdated-p (package &optional inhibit-refresh-p)
+  "Determine whether PACKAGE (a symbol) is outdated or not. If INHIBIT-REFRESH-P
+is non-nil, don't run `package-refresh-contents' (which is slow, but useful if
+you intend to use this method for batch processing -- be sure to run
+`package-refresh-contents' beforehand however)."
+  (unless inhibit-refresh-p
     (package-refresh-contents))
   (when (and (package-installed-p package)
              (cadr (assq package package-archive-contents)))

           (when quelpa-modified-p
             (quelpa-save-cache))))))

(defun doom/byte-compile ()
  "Byte (re)compile the important files in your emacs configuration. No more no
less."
  (interactive)
  (doom-package-init)
  (mapc 'byte-compile-file
        (append (list (expand-file-name "init.el" doom-emacs-dir)
                      (expand-file-name "core.el" doom-core-dir))
                (reverse
                 (file-expand-wildcards
                  (expand-file-name "core*.el" doom-core-dir)))
                (file-expand-wildcards
                 (expand-file-name "*/*/packages.el" doom-modules-dir)))))

(defun doom/refresh-autoloads (&optional inhibit-require)
  "Refreshes your emacs config's autoloads file. Use this if you modify an
autoload.el file in any module."
  (interactive)
  (let ((generated-autoload-file (concat doom-modules-dir "autoloads.el"))
        (interactive-p (called-interactively-p 'interactive))
        (autoload-files
         (file-expand-wildcards
          (expand-file-name "*/*/autoload.el" doom-modules-dir))))
    (when (file-exists-p generated-autoload-file)
      (delete-file generated-autoload-file)
      (when interactive-p (message "Deleted old autoloads.el")))
    (dolist (file autoload-files)
      (update-file-autoloads file t)
      (when interactive-p
        (message "Detected: %s"
                 (file-relative-name (directory-file-name parent)
                                     doom-emacs-dir))))
    (when interactive-p (message "Done!"))
    (with-demoted-errors "WARNING: %s"
      (load "autoloads"))))

(provide 'core-packages)
;;; core-packages.el ends here

        ("melpa" . "http://melpa.org/packages/")
        ("org"   . "http://orgmode.org/elpa/"))

      use-package-always-defer t
      use-package-always-ensure nil
      use-package-debug doom-debug-mode
      quelpa-checkout-melpa-p nil
      quelpa-update-melpa-p nil
      quelpa-use-package-inhibit-loading-quelpa t
      quelpa-dir (expand-file-name "quelpa" doom-packages-dir))


;;
;; Library
;;

(defun doom-package-init (&optional force-p)
  "Initialize DOOM, its essential packages and package.el. This must be used on
first run. If you byte compile core/core.el, this file is avoided to speed up
startup. Returns `load-path'."
  (when (or (not doom-init) force-p)
    (package-initialize)
    (when (or (not (file-exists-p package-user-dir)) force-p)
      (package-refresh-contents))
    (unless (package-installed-p 'quelpa-use-package)
      (package-install 'quelpa-use-package t))

    (require 'quelpa-use-package)
    (setq use-package-always-ensure t)
    (quelpa-use-package-activate-advice)

    (add-to-list 'load-path doom-local-dir)
    (add-to-list 'load-path doom-modules-dir)
    (add-to-list 'load-path doom-core-dir)

    (setq doom-init t)))

(defmacro package! (name &rest rest)
  "Declare a package. Wraps around `use-package', and takes the same arguments
that it does. NOTE: Packages are deferred by default."
  (declare (indent defun))
  (add-to-list 'doom-packages name)
  ;; If `use-package-always-ensure' is nil, then remove any possibility of an
  ;; installation by package.el or quelpa.
  (unless use-package-always-ensure
    (when (and (plist-member rest :ensure)
               (plist-get rest :ensure))
      (setq rest (plist-put rest :ensure nil)))
