2017-06-08 11:47:56 +02:00
|
|
|
;;; core.el --- the heart of the beast -*- lexical-binding: t; -*-
|
2017-01-16 23:15:48 -05:00
|
|
|
|
2018-05-19 18:01:49 +02:00
|
|
|
(eval-when-compile
|
2018-12-28 15:22:52 -05:00
|
|
|
(and (version< emacs-version "25.3")
|
|
|
|
(error "Detected Emacs %s. Doom only supports Emacs 25.3 and higher"
|
2018-06-12 01:47:43 +02:00
|
|
|
emacs-version)))
|
2018-05-19 18:01:49 +02:00
|
|
|
|
2018-06-15 00:25:20 +02:00
|
|
|
(defvar doom-debug-mode (or (getenv "DEBUG") init-file-debug)
|
2019-05-01 19:12:52 -04:00
|
|
|
"If non-nil, Doom will log more.
|
|
|
|
|
|
|
|
Use `doom/toggle-debug-mode' to toggle it. The --debug-init flag and setting the
|
|
|
|
DEBUG envvar will enable this at startup.")
|
2018-06-15 00:25:20 +02:00
|
|
|
|
2018-06-12 01:48:09 +02:00
|
|
|
|
|
|
|
;;
|
2019-04-20 02:18:17 -04:00
|
|
|
;;; Constants
|
2018-06-12 01:48:09 +02:00
|
|
|
|
|
|
|
(defconst doom-version "2.0.9"
|
2019-05-01 19:12:52 -04:00
|
|
|
"Current version of Doom Emacs.")
|
2016-10-05 12:48:12 +02:00
|
|
|
|
2018-09-07 21:43:32 -04:00
|
|
|
(defconst EMACS26+ (> emacs-major-version 25))
|
|
|
|
(defconst EMACS27+ (> emacs-major-version 26))
|
2018-06-12 01:48:09 +02:00
|
|
|
|
2018-06-08 13:31:45 +02:00
|
|
|
(defconst IS-MAC (eq system-type 'darwin))
|
|
|
|
(defconst IS-LINUX (eq system-type 'gnu/linux))
|
|
|
|
(defconst IS-WINDOWS (memq system-type '(cygwin windows-nt ms-dos)))
|
2019-01-05 16:04:38 -05:00
|
|
|
(defconst IS-BSD (or IS-MAC (eq system-type 'berkeley-unix)))
|
2018-06-08 13:31:45 +02:00
|
|
|
|
2018-05-14 13:05:33 +02:00
|
|
|
|
2018-04-03 19:46:22 -04:00
|
|
|
;;
|
2018-09-19 19:41:46 -04:00
|
|
|
(defvar doom-emacs-dir
|
|
|
|
(eval-when-compile (file-truename user-emacs-directory))
|
2019-05-01 19:12:52 -04:00
|
|
|
"The path to the currently loaded .emacs.d directory. Must end with a slash.")
|
2016-10-02 23:25:08 +02:00
|
|
|
|
2018-08-12 02:45:28 +02:00
|
|
|
(defvar doom-core-dir (concat doom-emacs-dir "core/")
|
2019-05-01 19:12:52 -04:00
|
|
|
"The root directory of Doom's core files. Must end with a slash.")
|
2016-10-02 23:25:08 +02:00
|
|
|
|
2018-08-12 02:45:28 +02:00
|
|
|
(defvar doom-modules-dir (concat doom-emacs-dir "modules/")
|
2019-05-01 19:12:52 -04:00
|
|
|
"The root directory for Doom's modules. Must end with a slash.")
|
2018-02-16 02:02:58 -05:00
|
|
|
|
2018-08-12 02:45:28 +02:00
|
|
|
(defvar doom-local-dir (concat doom-emacs-dir ".local/")
|
2019-05-01 19:12:52 -04:00
|
|
|
"Root directory for local storage.
|
|
|
|
|
|
|
|
Use this as a storage location for this system's installation of Doom Emacs.
|
|
|
|
These files should not be shared across systems. By default, it is used by
|
|
|
|
`doom-etc-dir' and `doom-cache-dir'. Must end with a slash.")
|
2017-03-16 23:38:22 -04:00
|
|
|
|
2018-08-12 02:45:28 +02:00
|
|
|
(defvar doom-etc-dir (concat doom-local-dir "etc/")
|
2019-05-01 19:12:52 -04:00
|
|
|
"Directory for non-volatile local storage.
|
2017-12-22 14:48:07 -05:00
|
|
|
|
2019-05-01 19:12:52 -04:00
|
|
|
Use this for files that don't change much, like server binaries, external
|
|
|
|
dependencies or long-term shared data. Must end with a slash.")
|
2017-06-11 23:50:50 +02:00
|
|
|
|
2018-08-12 02:45:28 +02:00
|
|
|
(defvar doom-cache-dir (concat doom-local-dir "cache/")
|
2019-05-01 19:12:52 -04:00
|
|
|
"Directory for volatile local storage.
|
2017-01-16 23:15:48 -05:00
|
|
|
|
2019-05-01 19:12:52 -04:00
|
|
|
Use this for files that change often, like cache files. Must end with a slash.")
|
2017-04-16 20:36:15 -04:00
|
|
|
|
2018-08-12 02:45:28 +02:00
|
|
|
(defvar doom-packages-dir (concat doom-local-dir "packages/")
|
2019-05-01 19:12:52 -04:00
|
|
|
"Where package.el and quelpa plugins (and their caches) are stored.
|
|
|
|
|
|
|
|
Must end with a slash.")
|
2016-05-23 06:26:28 -04:00
|
|
|
|
2018-08-12 02:45:28 +02:00
|
|
|
(defvar doom-docs-dir (concat doom-emacs-dir "docs/")
|
2019-05-01 19:12:52 -04:00
|
|
|
"Where Doom's documentation files are stored. Must end with a slash.")
|
2018-06-17 21:39:40 +02:00
|
|
|
|
2018-08-12 02:45:28 +02:00
|
|
|
(defvar doom-private-dir
|
2018-09-19 18:18:28 -04:00
|
|
|
(or (getenv "DOOMDIR")
|
2018-10-05 23:29:20 -04:00
|
|
|
(let ((xdg-path
|
|
|
|
(expand-file-name "doom/"
|
|
|
|
(or (getenv "XDG_CONFIG_HOME")
|
|
|
|
"~/.config"))))
|
|
|
|
(if (file-directory-p xdg-path) xdg-path))
|
2018-09-19 18:18:28 -04:00
|
|
|
"~/.doom.d/")
|
2019-05-01 19:12:52 -04:00
|
|
|
"Where your private configuration is placed.
|
|
|
|
|
|
|
|
Defaults to ~/.config/doom, ~/.doom.d or the value of the DOOMDIR envvar;
|
|
|
|
whichever is found first. Must end in a slash.")
|
2018-04-03 03:07:26 -04:00
|
|
|
|
2018-08-12 02:45:28 +02:00
|
|
|
(defvar doom-autoload-file (concat doom-local-dir "autoloads.el")
|
2019-05-01 19:12:52 -04:00
|
|
|
"Where `doom-reload-doom-autoloads' stores its core autoloads.
|
|
|
|
|
|
|
|
This file is responsible for informing Emacs where to find all of Doom's
|
|
|
|
autoloaded core functions (in core/autoload/*.el).")
|
2018-06-11 23:18:15 +02:00
|
|
|
|
2018-08-12 02:45:28 +02:00
|
|
|
(defvar doom-package-autoload-file (concat doom-local-dir "autoloads.pkg.el")
|
2019-05-01 19:12:52 -04:00
|
|
|
"Where `doom-reload-package-autoloads' stores its package.el autoloads.
|
|
|
|
|
|
|
|
This file is compiled from the autoloads files of all installed packages
|
|
|
|
combined.")
|
2018-06-11 23:18:15 +02:00
|
|
|
|
:boom: Replace exec-path-from-shell w/ 'bin/doom env'
IMPORTANT: This is a breaking update for Mac users, as your shell
environment will no longer be inherited correctly (with the removal of
exec-path-from-shell). The quick fix is: 'bin/doom env refresh'. Also,
the set-env! autodef now does nothing (and is deprecated), be sure to
remove calls to it in your config.
Smaller changes:
+ This update also adds --no-* switches to doom quickstart
+ Includes general improvements to the documentation of several bin/doom
commands.
+ Moves doom/reload* commands to core/autoload/config.el
+ doom/reload-project has been removed (it didn't actually do anything)
The breaking change:
This update adds an "envvar file" to Doom Emacs. This file is generated
by `doom env refresh`, populated with variables scraped from your shell
environment (from both non-interactive and interactive sessions). This
file is then (inexpensively) loaded at startup, if it exists.
+ The file is manually generated with `doom env refresh`.
+ It can be regenerated automatically whenever `doom refresh` is run by
running `doom env enable` (`doom env clear` will reverse this and
delete the env file).
+ `doom quickstart` will ask if you want to auto-generate this envvar
file. You won't need it if you're confident Emacs will always be
started from the correct environment, however.
+ Your env file can be reloaded from a running Emacs session with `M-x
doom/reload-env`. Note: this won't work if the Emacs session you're
running it in doesn't have a correct SHELL set. i.e. don't use this to
create your first env file!
The idea isn't mine -- it's borrowed from Spacemacs -- and was
introduced to me in #1053 by @yurimx. I was impressed with it. Prior to
this, I was unhappy with exec-path-from-shell (no hate to the dev, I
understand its necessity), and 'doom patch-macos' wasn't ideal for mac
users (needed to be reapplied every time you update Emacs). What's more,
many users (even Linux users) had to install exec-path-from-shell
anyway.
This solution suffers from none of their shortcomings. More reliable
than patch-macos, more performant and complete than
exec-path-from-shell, and easily handled by bin/doom.
2019-03-28 00:06:10 -04:00
|
|
|
(defvar doom-env-file (concat doom-local-dir "env")
|
2019-05-01 19:12:52 -04:00
|
|
|
"The location of your envvar file, generated by `doom env refresh`.
|
:boom: Replace exec-path-from-shell w/ 'bin/doom env'
IMPORTANT: This is a breaking update for Mac users, as your shell
environment will no longer be inherited correctly (with the removal of
exec-path-from-shell). The quick fix is: 'bin/doom env refresh'. Also,
the set-env! autodef now does nothing (and is deprecated), be sure to
remove calls to it in your config.
Smaller changes:
+ This update also adds --no-* switches to doom quickstart
+ Includes general improvements to the documentation of several bin/doom
commands.
+ Moves doom/reload* commands to core/autoload/config.el
+ doom/reload-project has been removed (it didn't actually do anything)
The breaking change:
This update adds an "envvar file" to Doom Emacs. This file is generated
by `doom env refresh`, populated with variables scraped from your shell
environment (from both non-interactive and interactive sessions). This
file is then (inexpensively) loaded at startup, if it exists.
+ The file is manually generated with `doom env refresh`.
+ It can be regenerated automatically whenever `doom refresh` is run by
running `doom env enable` (`doom env clear` will reverse this and
delete the env file).
+ `doom quickstart` will ask if you want to auto-generate this envvar
file. You won't need it if you're confident Emacs will always be
started from the correct environment, however.
+ Your env file can be reloaded from a running Emacs session with `M-x
doom/reload-env`. Note: this won't work if the Emacs session you're
running it in doesn't have a correct SHELL set. i.e. don't use this to
create your first env file!
The idea isn't mine -- it's borrowed from Spacemacs -- and was
introduced to me in #1053 by @yurimx. I was impressed with it. Prior to
this, I was unhappy with exec-path-from-shell (no hate to the dev, I
understand its necessity), and 'doom patch-macos' wasn't ideal for mac
users (needed to be reapplied every time you update Emacs). What's more,
many users (even Linux users) had to install exec-path-from-shell
anyway.
This solution suffers from none of their shortcomings. More reliable
than patch-macos, more performant and complete than
exec-path-from-shell, and easily handled by bin/doom.
2019-03-28 00:06:10 -04:00
|
|
|
|
2019-05-01 19:12:52 -04:00
|
|
|
This file contains environment variables scraped from your shell environment,
|
|
|
|
which is loaded at startup (if it exists). This is helpful if Emacs can't
|
2019-05-02 21:54:47 -04:00
|
|
|
\(easily) be launched from the correct shell session (particularly for MacOS
|
2019-05-01 19:12:52 -04:00
|
|
|
users).")
|
:boom: Replace exec-path-from-shell w/ 'bin/doom env'
IMPORTANT: This is a breaking update for Mac users, as your shell
environment will no longer be inherited correctly (with the removal of
exec-path-from-shell). The quick fix is: 'bin/doom env refresh'. Also,
the set-env! autodef now does nothing (and is deprecated), be sure to
remove calls to it in your config.
Smaller changes:
+ This update also adds --no-* switches to doom quickstart
+ Includes general improvements to the documentation of several bin/doom
commands.
+ Moves doom/reload* commands to core/autoload/config.el
+ doom/reload-project has been removed (it didn't actually do anything)
The breaking change:
This update adds an "envvar file" to Doom Emacs. This file is generated
by `doom env refresh`, populated with variables scraped from your shell
environment (from both non-interactive and interactive sessions). This
file is then (inexpensively) loaded at startup, if it exists.
+ The file is manually generated with `doom env refresh`.
+ It can be regenerated automatically whenever `doom refresh` is run by
running `doom env enable` (`doom env clear` will reverse this and
delete the env file).
+ `doom quickstart` will ask if you want to auto-generate this envvar
file. You won't need it if you're confident Emacs will always be
started from the correct environment, however.
+ Your env file can be reloaded from a running Emacs session with `M-x
doom/reload-env`. Note: this won't work if the Emacs session you're
running it in doesn't have a correct SHELL set. i.e. don't use this to
create your first env file!
The idea isn't mine -- it's borrowed from Spacemacs -- and was
introduced to me in #1053 by @yurimx. I was impressed with it. Prior to
this, I was unhappy with exec-path-from-shell (no hate to the dev, I
understand its necessity), and 'doom patch-macos' wasn't ideal for mac
users (needed to be reapplied every time you update Emacs). What's more,
many users (even Linux users) had to install exec-path-from-shell
anyway.
This solution suffers from none of their shortcomings. More reliable
than patch-macos, more performant and complete than
exec-path-from-shell, and easily handled by bin/doom.
2019-03-28 00:06:10 -04:00
|
|
|
|
2018-06-11 23:18:15 +02:00
|
|
|
|
|
|
|
;;
|
2019-04-20 02:18:17 -04:00
|
|
|
;;; Doom core variables
|
2018-06-11 23:18:15 +02:00
|
|
|
|
|
|
|
(defvar doom-init-p nil
|
2019-05-01 19:12:52 -04:00
|
|
|
"Non-nil if Doom has been initialized.")
|
2018-06-11 23:18:15 +02:00
|
|
|
|
|
|
|
(defvar doom-init-time nil
|
2019-05-01 19:12:52 -04:00
|
|
|
"The time it took, in seconds, for Doom Emacs to initialize.")
|
2018-06-11 23:18:15 +02:00
|
|
|
|
|
|
|
(defvar doom-emacs-changed-p nil
|
|
|
|
"If non-nil, the running version of Emacs is different from the first time
|
2019-05-01 19:12:52 -04:00
|
|
|
Doom was setup, which may cause problems.")
|
2018-06-11 23:18:15 +02:00
|
|
|
|
2019-04-09 03:43:13 -04:00
|
|
|
(defvar doom-site-load-path (cons doom-core-dir load-path)
|
|
|
|
"The initial value of `load-path', before it was altered by
|
|
|
|
`doom-initialize'.")
|
2019-04-03 00:08:06 -04:00
|
|
|
|
|
|
|
(defvar doom-site-process-environment process-environment
|
2019-04-09 03:43:13 -04:00
|
|
|
"The initial value of `process-environment', before it was altered by
|
|
|
|
`doom-initialize'.")
|
|
|
|
|
|
|
|
(defvar doom-site-exec-path exec-path
|
|
|
|
"The initial value of `exec-path', before it was altered by
|
|
|
|
`doom-initialize'.")
|
|
|
|
|
|
|
|
(defvar doom-site-shell-file-name shell-file-name
|
|
|
|
"The initial value of `shell-file-name', before it was altered by
|
|
|
|
`doom-initialize'.")
|
2018-06-11 23:18:15 +02:00
|
|
|
|
2018-06-13 22:16:08 +02:00
|
|
|
(defvar doom--last-emacs-file (concat doom-local-dir "emacs-version.el"))
|
|
|
|
(defvar doom--last-emacs-version nil)
|
|
|
|
(defvar doom--refreshed-p nil)
|
|
|
|
(defvar doom--stage 'init)
|
|
|
|
|
2018-06-11 23:18:15 +02:00
|
|
|
|
2018-06-18 14:47:36 +02:00
|
|
|
;;
|
2019-04-20 02:18:17 -04:00
|
|
|
;;; Custom error types
|
2018-06-18 14:47:36 +02:00
|
|
|
|
2018-06-20 02:07:12 +02:00
|
|
|
(define-error 'doom-error "Error in Doom Emacs core")
|
2018-06-18 14:47:36 +02:00
|
|
|
(define-error 'doom-hook-error "Error in a Doom startup hook" 'doom-error)
|
2018-06-20 02:07:12 +02:00
|
|
|
(define-error 'doom-autoload-error "Error in an autoloads file" 'doom-error)
|
|
|
|
(define-error 'doom-module-error "Error in a Doom module" 'doom-error)
|
|
|
|
(define-error 'doom-private-error "Error in private config" 'doom-error)
|
|
|
|
(define-error 'doom-package-error "Error with packages" 'doom-error)
|
2018-06-18 14:47:36 +02:00
|
|
|
|
|
|
|
|
2018-08-26 00:16:56 +02:00
|
|
|
;;
|
2019-04-20 02:18:17 -04:00
|
|
|
;;; Custom hooks
|
2018-08-26 00:16:56 +02:00
|
|
|
|
|
|
|
(defvar doom-reload-hook nil
|
2018-09-07 21:43:32 -04:00
|
|
|
"A list of hooks to run when `doom/reload' is called.")
|
2018-08-26 00:16:56 +02:00
|
|
|
|
|
|
|
|
2018-06-11 23:18:15 +02:00
|
|
|
;;
|
2019-04-20 02:18:17 -04:00
|
|
|
;;; Emacs core configuration
|
2016-05-26 18:51:39 -04:00
|
|
|
|
2017-01-31 18:59:58 -05:00
|
|
|
;; UTF-8 as the default coding system
|
2017-05-19 02:54:31 +02:00
|
|
|
(when (fboundp 'set-charset-priority)
|
|
|
|
(set-charset-priority 'unicode)) ; pretty
|
2019-03-02 03:53:13 -05:00
|
|
|
(prefer-coding-system 'utf-8) ; pretty
|
|
|
|
(setq locale-coding-system 'utf-8) ; please
|
2019-03-28 01:46:58 -04:00
|
|
|
(unless IS-WINDOWS
|
|
|
|
(setq selection-coding-system 'utf-8)) ; with sugar on top
|
2017-01-16 23:15:48 -05:00
|
|
|
|
2017-02-19 18:11:28 -05:00
|
|
|
(setq-default
|
2019-05-15 20:22:27 -04:00
|
|
|
ad-redefinition-action 'accept ; silence redefined function warnings
|
2017-02-19 18:11:28 -05:00
|
|
|
apropos-do-all t ; make `apropos' more useful
|
2018-06-11 23:18:15 +02:00
|
|
|
auto-mode-case-fold nil
|
|
|
|
autoload-compute-prefixes nil
|
2018-05-18 01:21:09 +02:00
|
|
|
debug-on-error doom-debug-mode
|
2019-03-28 01:53:15 -04:00
|
|
|
jka-compr-verbose doom-debug-mode ; silence compression messages
|
2018-02-01 19:50:35 -05:00
|
|
|
ffap-machine-p-known 'reject ; don't ping things that look like domain names
|
2018-12-22 14:30:29 -05:00
|
|
|
find-file-visit-truename t ; resolve symlinks when opening files
|
2019-05-15 20:53:11 -04:00
|
|
|
idle-update-delay 1 ; update ui slightly less often
|
2018-06-11 23:18:15 +02:00
|
|
|
;; be quiet at startup; don't load or display anything unnecessary
|
2018-05-19 23:49:25 +02:00
|
|
|
inhibit-startup-message t
|
|
|
|
inhibit-startup-echo-area-message user-login-name
|
|
|
|
inhibit-default-init t
|
|
|
|
initial-major-mode 'fundamental-mode
|
|
|
|
initial-scratch-message nil
|
2017-04-16 20:36:15 -04:00
|
|
|
;; History & backup settings (save nothing, that's what git is for)
|
2017-02-19 18:11:28 -05:00
|
|
|
auto-save-default nil
|
|
|
|
create-lockfiles nil
|
2018-09-18 11:51:08 -04:00
|
|
|
history-length 500
|
2018-02-01 19:50:35 -05:00
|
|
|
make-backup-files nil ; don't create backup~ files
|
2018-06-11 23:18:15 +02:00
|
|
|
;; byte compilation
|
|
|
|
byte-compile-verbose doom-debug-mode
|
|
|
|
byte-compile-warnings '(not free-vars unresolved noruntime lexical make-local)
|
|
|
|
;; security
|
|
|
|
gnutls-verify-error (not (getenv "INSECURE")) ; you shouldn't use this
|
|
|
|
tls-checktrust gnutls-verify-error
|
|
|
|
tls-program (list "gnutls-cli --x509cafile %t -p %p %h"
|
|
|
|
;; compatibility fallbacks
|
|
|
|
"gnutls-cli -p %p %h"
|
|
|
|
"openssl s_client -connect %h:%p -no_ssl2 -no_ssl3 -ign_eof")
|
2018-12-23 23:16:03 -05:00
|
|
|
;; Don't store authinfo in plain text!
|
|
|
|
auth-sources (list (expand-file-name "authinfo.gpg" doom-etc-dir)
|
|
|
|
"~/.authinfo.gpg")
|
2019-05-13 19:29:38 -04:00
|
|
|
;; Don't litter `doom-emacs-dir'
|
2017-04-16 20:36:15 -04:00
|
|
|
abbrev-file-name (concat doom-local-dir "abbrev.el")
|
2019-02-21 02:30:36 -05:00
|
|
|
async-byte-compile-log-file (concat doom-etc-dir "async-bytecomp.log")
|
2017-04-16 20:36:15 -04:00
|
|
|
auto-save-list-file-name (concat doom-cache-dir "autosave")
|
|
|
|
backup-directory-alist (list (cons "." (concat doom-cache-dir "backup/")))
|
2019-03-02 01:04:41 -05:00
|
|
|
desktop-dirname (concat doom-etc-dir "desktop")
|
|
|
|
desktop-base-file-name "autosave"
|
|
|
|
desktop-base-lock-name "autosave-lock"
|
2018-05-18 01:21:09 +02:00
|
|
|
pcache-directory (concat doom-cache-dir "pcache/")
|
|
|
|
request-storage-directory (concat doom-cache-dir "request")
|
2017-04-16 20:36:15 -04:00
|
|
|
server-auth-dir (concat doom-cache-dir "server/")
|
|
|
|
shared-game-score-directory (concat doom-etc-dir "shared-game-score/")
|
|
|
|
tramp-auto-save-directory (concat doom-cache-dir "tramp-auto-save/")
|
2017-03-27 13:05:01 -04:00
|
|
|
tramp-backup-directory-alist backup-directory-alist
|
2017-04-16 20:36:15 -04:00
|
|
|
tramp-persistency-file-name (concat doom-cache-dir "tramp-persistency.el")
|
|
|
|
url-cache-directory (concat doom-cache-dir "url/")
|
2018-08-02 17:06:30 +02:00
|
|
|
url-configuration-directory (concat doom-etc-dir "url/")
|
2018-09-10 09:01:03 -04:00
|
|
|
gamegrid-user-score-file-directory (concat doom-etc-dir "games/"))
|
2017-05-15 11:18:26 +02:00
|
|
|
|
2019-05-15 18:30:20 -04:00
|
|
|
(defun doom*symbol-file (orig-fn symbol &optional type)
|
|
|
|
"If a `doom-file' symbol property exists on SYMBOL, use that instead of the
|
|
|
|
original value of `symbol-file'."
|
|
|
|
(or (if (symbolp symbol) (get symbol 'doom-file))
|
|
|
|
(funcall orig-fn symbol type)))
|
|
|
|
(advice-add #'symbol-file :around #'doom*symbol-file)
|
|
|
|
|
|
|
|
|
|
|
|
;;
|
|
|
|
;;; Minor mode version of `auto-mode-alist'
|
|
|
|
|
2018-04-03 16:24:15 -04:00
|
|
|
(defvar doom-auto-minor-mode-alist '()
|
|
|
|
"Alist mapping filename patterns to corresponding minor mode functions, like
|
|
|
|
`auto-mode-alist'. All elements of this alist are checked, meaning you can
|
|
|
|
enable multiple minor modes for the same regexp.")
|
|
|
|
|
|
|
|
(defun doom|enable-minor-mode-maybe ()
|
|
|
|
"Check file name against `doom-auto-minor-mode-alist'."
|
2019-04-29 18:54:46 -04:00
|
|
|
(when (and buffer-file-name doom-auto-minor-mode-alist)
|
2018-04-03 16:24:15 -04:00
|
|
|
(let ((name buffer-file-name)
|
|
|
|
(remote-id (file-remote-p buffer-file-name))
|
|
|
|
(alist doom-auto-minor-mode-alist))
|
|
|
|
;; Remove backup-suffixes from file name.
|
|
|
|
(setq name (file-name-sans-versions name))
|
|
|
|
;; Remove remote file name identification.
|
|
|
|
(when (and (stringp remote-id)
|
2018-06-06 02:38:39 +02:00
|
|
|
(string-match (regexp-quote remote-id) name))
|
2018-04-03 16:24:15 -04:00
|
|
|
(setq name (substring name (match-end 0))))
|
|
|
|
(while (and alist (caar alist) (cdar alist))
|
|
|
|
(if (string-match-p (caar alist) name)
|
|
|
|
(funcall (cdar alist) 1))
|
|
|
|
(setq alist (cdr alist))))))
|
|
|
|
(add-hook 'find-file-hook #'doom|enable-minor-mode-maybe)
|
|
|
|
|
2019-05-15 18:30:20 -04:00
|
|
|
|
|
|
|
;;
|
|
|
|
;;; MODE-local-vars-hook
|
2018-06-15 14:58:31 +02:00
|
|
|
|
2018-09-29 14:57:17 -04:00
|
|
|
;; File+dir local variables are initialized after the major mode and its hooks
|
|
|
|
;; have run. If you want hook functions to be aware of these customizations, add
|
|
|
|
;; them to MODE-local-vars-hook instead.
|
|
|
|
(defun doom|run-local-var-hooks ()
|
|
|
|
"Run MODE-local-vars-hook after local variables are initialized."
|
|
|
|
(run-hook-wrapped (intern-soft (format "%s-local-vars-hook" major-mode))
|
|
|
|
#'doom-try-run-hook))
|
|
|
|
(add-hook 'hack-local-variables-hook #'doom|run-local-var-hooks)
|
2018-09-28 20:49:58 -04:00
|
|
|
|
2019-05-01 19:12:52 -04:00
|
|
|
;; If `enable-local-variables' is disabled, then `hack-local-variables-hook' is
|
|
|
|
;; never triggered.
|
2019-03-05 17:08:39 -05:00
|
|
|
(defun doom|run-local-var-hooks-if-necessary ()
|
2019-05-01 19:12:52 -04:00
|
|
|
"Run `doom|run-local-var-hooks' if `enable-local-variables' is disabled."
|
2019-03-05 17:08:39 -05:00
|
|
|
(unless enable-local-variables
|
|
|
|
(doom|run-local-var-hooks)))
|
2019-06-16 18:57:14 +02:00
|
|
|
(add-hook 'after-change-major-mode-hook #'doom|run-local-var-hooks-if-necessary 'append)
|
2019-03-05 17:08:39 -05:00
|
|
|
|
2019-05-14 18:45:38 -04:00
|
|
|
(defun doom|create-non-existent-directories ()
|
|
|
|
"Automatically create missing directories when creating new files."
|
|
|
|
(let ((parent-directory (file-name-directory buffer-file-name)))
|
|
|
|
(when (and (not (file-exists-p parent-directory))
|
|
|
|
(y-or-n-p (format "Directory `%s' does not exist! Create it?" parent-directory)))
|
|
|
|
(make-directory parent-directory t))))
|
|
|
|
(add-hook 'find-file-not-found-functions #'doom|create-non-existent-directories)
|
|
|
|
|
2018-04-03 16:24:15 -04:00
|
|
|
|
2018-09-18 11:42:35 -04:00
|
|
|
;;
|
2019-04-20 02:18:17 -04:00
|
|
|
;;; Incremental lazy-loading
|
2018-09-18 11:42:35 -04:00
|
|
|
|
|
|
|
(defvar doom-incremental-packages '(t)
|
|
|
|
"A list of packages to load incrementally after startup. Any large packages
|
|
|
|
here may cause noticable pauses, so it's recommended you break them up into
|
2019-05-01 19:12:52 -04:00
|
|
|
sub-packages. For example, `org' is comprised of many packages, and can be
|
|
|
|
broken up into:
|
2018-09-18 11:42:35 -04:00
|
|
|
|
|
|
|
(doom-load-packages-incrementally
|
|
|
|
'(calendar find-func format-spec org-macs org-compat
|
|
|
|
org-faces org-entities org-list org-pcomplete org-src
|
|
|
|
org-footnote org-macro ob org org-clock org-agenda
|
|
|
|
org-capture))
|
|
|
|
|
|
|
|
This is already done by the lang/org module, however.
|
|
|
|
|
|
|
|
If you want to disable incremental loading altogether, either remove
|
|
|
|
`doom|load-packages-incrementally' from `emacs-startup-hook' or set
|
|
|
|
`doom-incremental-first-idle-timer' to nil.")
|
|
|
|
|
|
|
|
(defvar doom-incremental-first-idle-timer 2
|
|
|
|
"How long (in idle seconds) until incremental loading starts.
|
|
|
|
|
|
|
|
Set this to nil to disable incremental loading.")
|
|
|
|
|
2019-03-04 18:38:25 -05:00
|
|
|
(defvar doom-incremental-idle-timer 1.5
|
2018-09-18 11:42:35 -04:00
|
|
|
"How long (in idle seconds) in between incrementally loading packages.")
|
|
|
|
|
|
|
|
(defun doom-load-packages-incrementally (packages &optional now)
|
|
|
|
"Registers PACKAGES to be loaded incrementally.
|
|
|
|
|
|
|
|
If NOW is non-nil, load PACKAGES incrementally, in `doom-incremental-idle-timer'
|
|
|
|
intervals."
|
|
|
|
(if (not now)
|
|
|
|
(nconc doom-incremental-packages packages)
|
|
|
|
(when packages
|
|
|
|
(let ((gc-cons-threshold doom-gc-cons-upper-limit)
|
|
|
|
file-name-handler-alist)
|
2018-09-28 22:50:39 -04:00
|
|
|
(let* ((reqs (cl-delete-if #'featurep packages))
|
2018-09-18 11:42:35 -04:00
|
|
|
(req (ignore-errors (pop reqs))))
|
|
|
|
(when req
|
2019-03-04 18:38:25 -05:00
|
|
|
(doom-log "Incrementally loading %s" req)
|
2018-12-10 13:48:55 -05:00
|
|
|
(condition-case e
|
2019-05-18 18:02:38 -04:00
|
|
|
(or (while-no-input (require req nil t) t)
|
|
|
|
(push req reqs))
|
2019-03-04 18:38:25 -05:00
|
|
|
((error debug)
|
2018-12-10 13:48:55 -05:00
|
|
|
(message "Failed to load '%s' package incrementally, because: %s"
|
|
|
|
req e)))
|
2019-03-04 18:38:25 -05:00
|
|
|
(if reqs
|
|
|
|
(run-with-idle-timer doom-incremental-idle-timer
|
|
|
|
nil #'doom-load-packages-incrementally
|
|
|
|
reqs t)
|
|
|
|
(doom-log "Finished incremental loading"))))))))
|
2018-09-18 11:42:35 -04:00
|
|
|
|
|
|
|
(defun doom|load-packages-incrementally ()
|
|
|
|
"Begin incrementally loading packages in `doom-incremental-packages'.
|
|
|
|
|
|
|
|
If this is a daemon session, load them all immediately instead."
|
|
|
|
(if (daemonp)
|
|
|
|
(mapc #'require (cdr doom-incremental-packages))
|
|
|
|
(when (integerp doom-incremental-first-idle-timer)
|
|
|
|
(run-with-idle-timer doom-incremental-first-idle-timer
|
|
|
|
nil #'doom-load-packages-incrementally
|
|
|
|
(cdr doom-incremental-packages) t))))
|
|
|
|
|
2019-03-04 20:35:47 -05:00
|
|
|
(add-hook 'window-setup-hook #'doom|load-packages-incrementally)
|
2018-09-18 11:42:35 -04:00
|
|
|
|
|
|
|
|
2018-05-14 18:40:35 +02:00
|
|
|
;;
|
2019-04-20 02:18:17 -04:00
|
|
|
;;; Bootstrap helpers
|
2018-05-14 18:40:35 +02:00
|
|
|
|
2018-06-18 14:47:36 +02:00
|
|
|
(defun doom-try-run-hook (hook)
|
2018-09-07 21:43:32 -04:00
|
|
|
"Run HOOK (a hook function), but handle errors better, to make debugging
|
|
|
|
issues easier.
|
2018-06-18 14:47:36 +02:00
|
|
|
|
|
|
|
Meant to be used with `run-hook-wrapped'."
|
2019-03-04 18:38:25 -05:00
|
|
|
(doom-log "Running doom hook: %s" hook)
|
2018-09-18 11:45:13 -04:00
|
|
|
(condition-case e
|
|
|
|
(funcall hook)
|
|
|
|
((debug error)
|
|
|
|
(signal 'doom-hook-error (list hook e))))
|
|
|
|
;; return nil so `run-hook-wrapped' won't short circuit
|
|
|
|
nil)
|
2018-06-18 14:47:36 +02:00
|
|
|
|
2018-06-11 23:18:15 +02:00
|
|
|
(defun doom-ensure-same-emacs-version-p ()
|
2018-06-13 22:16:08 +02:00
|
|
|
"Check if the running version of Emacs has changed and set
|
|
|
|
`doom-emacs-changed-p' if it has."
|
2018-06-11 23:18:15 +02:00
|
|
|
(if (load doom--last-emacs-file 'noerror 'nomessage 'nosuffix)
|
|
|
|
(setq doom-emacs-changed-p
|
|
|
|
(not (equal emacs-version doom--last-emacs-version)))
|
|
|
|
(with-temp-file doom--last-emacs-file
|
|
|
|
(princ `(setq doom--last-emacs-version ,(prin1-to-string emacs-version))
|
|
|
|
(current-buffer))))
|
|
|
|
(cond ((not doom-emacs-changed-p))
|
|
|
|
((y-or-n-p
|
|
|
|
(format
|
|
|
|
(concat "Your version of Emacs has changed from %s to %s, which may cause incompatibility\n"
|
2018-06-13 22:16:08 +02:00
|
|
|
"issues. If you run into errors, run `bin/doom compile :plugins` or reinstall your\n"
|
|
|
|
"plugins to resolve them.\n\n"
|
2018-06-11 23:18:15 +02:00
|
|
|
"Continue?")
|
|
|
|
doom--last-emacs-version
|
|
|
|
emacs-version))
|
|
|
|
(delete-file doom--last-emacs-file))
|
|
|
|
(noninteractive (error "Aborting"))
|
|
|
|
((kill-emacs))))
|
|
|
|
|
2018-08-08 21:43:50 +02:00
|
|
|
(defun doom-ensure-core-directories-exist ()
|
2018-06-11 23:18:15 +02:00
|
|
|
"Make sure all Doom's essential local directories (in and including
|
|
|
|
`doom-local-dir') exist."
|
|
|
|
(dolist (dir (list doom-local-dir doom-etc-dir doom-cache-dir doom-packages-dir))
|
|
|
|
(unless (file-directory-p dir)
|
|
|
|
(make-directory dir t))))
|
|
|
|
|
|
|
|
(defun doom|display-benchmark (&optional return-p)
|
|
|
|
"Display a benchmark, showing number of packages and modules, and how quickly
|
|
|
|
they were loaded at startup.
|
|
|
|
|
|
|
|
If RETURN-P, return the message as a string instead of displaying it."
|
|
|
|
(funcall (if return-p #'format #'message)
|
|
|
|
"Doom loaded %s packages across %d modules in %.03fs"
|
|
|
|
(length package-activated-list)
|
|
|
|
(if doom-modules (hash-table-count doom-modules) 0)
|
|
|
|
(or doom-init-time
|
|
|
|
(setq doom-init-time (float-time (time-subtract (current-time) before-init-time))))))
|
|
|
|
|
|
|
|
(defun doom|run-all-startup-hooks ()
|
|
|
|
"Run all startup Emacs hooks. Meant to be executed after starting Emacs with
|
|
|
|
-q or -Q, for example:
|
|
|
|
|
|
|
|
emacs -Q -l init.el -f doom|run-all-startup-hooks"
|
2018-08-13 03:45:58 +02:00
|
|
|
(run-hook-wrapped 'after-init-hook #'doom-try-run-hook)
|
|
|
|
(setq after-init-time (current-time))
|
|
|
|
(dolist (hook (list 'delayed-warnings-hook
|
2018-06-19 00:47:20 +02:00
|
|
|
'emacs-startup-hook 'term-setup-hook
|
|
|
|
'window-setup-hook))
|
|
|
|
(run-hook-wrapped hook #'doom-try-run-hook)))
|
2018-05-14 18:40:35 +02:00
|
|
|
|
2019-03-06 21:16:07 -05:00
|
|
|
(defun doom-initialize-autoloads (file)
|
|
|
|
"Tries to load FILE (an autoloads file). Return t on success, throws an error
|
|
|
|
in interactive sessions, nil otherwise (but logs a warning)."
|
|
|
|
(condition-case e
|
|
|
|
(load (file-name-sans-extension file) 'noerror 'nomessage)
|
|
|
|
((debug error)
|
|
|
|
(if noninteractive
|
|
|
|
(message "Autoload file warning: %s -> %s" (car e) (error-message-string e))
|
|
|
|
(signal 'doom-autoload-error (list (file-name-nondirectory file) e))))))
|
2018-06-11 23:18:15 +02:00
|
|
|
|
2019-05-17 20:19:35 -04:00
|
|
|
(defun doom-load-env-vars (file)
|
|
|
|
"Read and set envvars in FILE."
|
|
|
|
(let (vars)
|
|
|
|
(with-temp-buffer
|
|
|
|
(insert-file-contents file)
|
|
|
|
(re-search-forward "\n\n" nil t)
|
|
|
|
(while (re-search-forward "\n\\([^= \n]+\\)=" nil t)
|
|
|
|
(save-excursion
|
|
|
|
(let ((var (match-string 1))
|
|
|
|
(value (buffer-substring-no-properties
|
|
|
|
(point)
|
|
|
|
(1- (or (when (re-search-forward "^\\([^= ]+\\)=" nil t)
|
|
|
|
(line-beginning-position))
|
|
|
|
(point-max))))))
|
|
|
|
(setenv var value)))))
|
|
|
|
vars))
|
|
|
|
|
2019-03-06 21:16:07 -05:00
|
|
|
(defun doom-initialize (&optional force-p)
|
|
|
|
"Bootstrap Doom, if it hasn't already (or if FORCE-P is non-nil).
|
2018-08-08 21:43:50 +02:00
|
|
|
|
2018-06-11 23:18:15 +02:00
|
|
|
The bootstrap process involves making sure 1) the essential directories exist,
|
|
|
|
2) the core packages are installed, 3) `doom-autoload-file' and
|
|
|
|
`doom-package-autoload-file' exist and have been loaded, and 4) Doom's core
|
|
|
|
files are loaded.
|
|
|
|
|
|
|
|
If the cache exists, much of this function isn't run, which substantially
|
|
|
|
reduces startup time.
|
|
|
|
|
|
|
|
The overall load order of Doom is as follows:
|
|
|
|
|
|
|
|
~/.emacs.d/init.el
|
|
|
|
~/.emacs.d/core/core.el
|
|
|
|
~/.doom.d/init.el
|
|
|
|
Module init.el files
|
2019-03-04 20:35:47 -05:00
|
|
|
`doom-before-init-modules-hook'
|
2018-06-11 23:18:15 +02:00
|
|
|
Module config.el files
|
|
|
|
~/.doom.d/config.el
|
2019-03-04 20:35:47 -05:00
|
|
|
`doom-init-modules-hook'
|
2018-06-11 23:18:15 +02:00
|
|
|
`after-init-hook'
|
|
|
|
`emacs-startup-hook'
|
2019-03-04 20:35:47 -05:00
|
|
|
`doom-init-ui-hook'
|
|
|
|
`window-setup-hook'
|
2018-06-11 23:18:15 +02:00
|
|
|
|
|
|
|
Module load order is determined by your `doom!' block. See `doom-modules-dirs'
|
|
|
|
for a list of all recognized module trees. Order defines precedence (from most
|
|
|
|
to least)."
|
|
|
|
(when (or force-p (not doom-init-p))
|
2018-07-09 15:33:31 +02:00
|
|
|
(setq doom-init-p t) ; Prevent infinite recursion
|
|
|
|
|
2019-04-09 03:43:13 -04:00
|
|
|
;; Reset as much state as possible
|
|
|
|
(setq exec-path doom-site-exec-path
|
|
|
|
load-path doom-site-load-path
|
|
|
|
process-environment doom-site-process-environment
|
|
|
|
shell-file-name doom-site-shell-file-name)
|
|
|
|
|
2018-06-11 23:18:15 +02:00
|
|
|
;; `doom-autoload-file' tells Emacs where to load all its autoloaded
|
|
|
|
;; functions from. This includes everything in core/autoload/*.el and all
|
|
|
|
;; the autoload files in your enabled modules.
|
|
|
|
(when (or force-p (not (doom-initialize-autoloads doom-autoload-file)))
|
2018-08-08 21:43:50 +02:00
|
|
|
(doom-ensure-core-directories-exist)
|
2018-06-11 23:18:15 +02:00
|
|
|
(doom-ensure-same-emacs-version-p)
|
2018-07-09 15:33:31 +02:00
|
|
|
|
2018-06-11 23:18:15 +02:00
|
|
|
(require 'core-packages)
|
|
|
|
(doom-ensure-packages-initialized force-p)
|
|
|
|
(doom-ensure-core-packages)
|
2018-07-09 15:33:31 +02:00
|
|
|
|
2018-06-11 23:18:15 +02:00
|
|
|
(unless (or force-p noninteractive)
|
|
|
|
(user-error "Your doom autoloads are missing! Run `bin/doom refresh' to regenerate them")))
|
2018-07-09 15:33:31 +02:00
|
|
|
|
|
|
|
;; Loads `doom-package-autoload-file', which loads a concatenated package
|
|
|
|
;; autoloads file and caches `load-path', `auto-mode-alist',
|
|
|
|
;; `Info-directory-list', `doom-disabled-packages' and
|
2018-06-11 23:18:15 +02:00
|
|
|
;; `package-activated-list'. A big reduction in startup time.
|
2019-03-02 03:55:15 -05:00
|
|
|
(let (command-switch-alist)
|
|
|
|
(unless (or force-p
|
|
|
|
(doom-initialize-autoloads doom-package-autoload-file)
|
|
|
|
noninteractive)
|
2019-03-28 13:15:08 -04:00
|
|
|
(user-error "Your package autoloads are missing! Run `bin/doom refresh' to regenerate them")))
|
2018-07-09 15:33:31 +02:00
|
|
|
|
2019-03-28 13:15:08 -04:00
|
|
|
;; Load shell environment
|
2019-04-03 01:53:20 -04:00
|
|
|
(when (and (not noninteractive)
|
2019-05-17 20:19:35 -04:00
|
|
|
(file-readable-p doom-env-file))
|
|
|
|
(doom-load-env-vars doom-env-file)
|
2019-05-21 12:29:42 -04:00
|
|
|
(setq exec-path (append (split-string (getenv "PATH")
|
|
|
|
(if IS-WINDOWS ";" ":"))
|
2019-04-01 13:15:15 -04:00
|
|
|
(list exec-directory))
|
|
|
|
shell-file-name (or (getenv "SHELL")
|
|
|
|
shell-file-name))))
|
:boom: Replace exec-path-from-shell w/ 'bin/doom env'
IMPORTANT: This is a breaking update for Mac users, as your shell
environment will no longer be inherited correctly (with the removal of
exec-path-from-shell). The quick fix is: 'bin/doom env refresh'. Also,
the set-env! autodef now does nothing (and is deprecated), be sure to
remove calls to it in your config.
Smaller changes:
+ This update also adds --no-* switches to doom quickstart
+ Includes general improvements to the documentation of several bin/doom
commands.
+ Moves doom/reload* commands to core/autoload/config.el
+ doom/reload-project has been removed (it didn't actually do anything)
The breaking change:
This update adds an "envvar file" to Doom Emacs. This file is generated
by `doom env refresh`, populated with variables scraped from your shell
environment (from both non-interactive and interactive sessions). This
file is then (inexpensively) loaded at startup, if it exists.
+ The file is manually generated with `doom env refresh`.
+ It can be regenerated automatically whenever `doom refresh` is run by
running `doom env enable` (`doom env clear` will reverse this and
delete the env file).
+ `doom quickstart` will ask if you want to auto-generate this envvar
file. You won't need it if you're confident Emacs will always be
started from the correct environment, however.
+ Your env file can be reloaded from a running Emacs session with `M-x
doom/reload-env`. Note: this won't work if the Emacs session you're
running it in doesn't have a correct SHELL set. i.e. don't use this to
create your first env file!
The idea isn't mine -- it's borrowed from Spacemacs -- and was
introduced to me in #1053 by @yurimx. I was impressed with it. Prior to
this, I was unhappy with exec-path-from-shell (no hate to the dev, I
understand its necessity), and 'doom patch-macos' wasn't ideal for mac
users (needed to be reapplied every time you update Emacs). What's more,
many users (even Linux users) had to install exec-path-from-shell
anyway.
This solution suffers from none of their shortcomings. More reliable
than patch-macos, more performant and complete than
exec-path-from-shell, and easily handled by bin/doom.
2019-03-28 00:06:10 -04:00
|
|
|
|
2019-03-06 21:16:07 -05:00
|
|
|
(require 'core-lib)
|
|
|
|
(require 'core-modules)
|
2018-06-18 12:04:30 +02:00
|
|
|
(require 'core-os)
|
2019-03-06 21:16:07 -05:00
|
|
|
(if noninteractive
|
|
|
|
(require 'core-cli)
|
2019-03-04 20:35:47 -05:00
|
|
|
(add-hook 'window-setup-hook #'doom|display-benchmark)
|
2019-03-06 21:16:07 -05:00
|
|
|
(require 'core-keybinds)
|
2018-06-11 23:18:15 +02:00
|
|
|
(require 'core-ui)
|
|
|
|
(require 'core-projects)
|
2019-03-06 21:16:07 -05:00
|
|
|
(require 'core-editor)))
|
2018-06-19 17:19:11 +02:00
|
|
|
|
2018-05-19 16:42:31 +02:00
|
|
|
|
|
|
|
;;
|
2019-04-20 02:18:17 -04:00
|
|
|
;;; Bootstrap Doom
|
2018-04-03 22:36:23 -04:00
|
|
|
|
2019-03-08 06:13:07 -05:00
|
|
|
(eval-and-compile
|
|
|
|
(require 'subr-x)
|
2019-03-08 18:06:35 -05:00
|
|
|
(require 'cl-lib)
|
|
|
|
(unless EMACS26+
|
|
|
|
(with-no-warnings
|
2019-06-01 00:13:47 -04:00
|
|
|
;; `kill-current-buffer' was introduced in Emacs 26
|
|
|
|
(defalias 'kill-current-buffer #'kill-this-buffer)
|
2019-03-08 18:06:35 -05:00
|
|
|
;; if-let and when-let were moved to (if|when)-let* in Emacs 26+ so we
|
|
|
|
;; alias them for 25 users.
|
|
|
|
(defalias 'if-let* #'if-let)
|
|
|
|
(defalias 'when-let* #'when-let))))
|
2019-03-08 06:13:07 -05:00
|
|
|
|
2018-05-19 16:42:31 +02:00
|
|
|
(add-to-list 'load-path doom-core-dir)
|
|
|
|
|
2018-05-24 19:00:41 +02:00
|
|
|
(doom-initialize noninteractive)
|
2018-06-11 23:18:15 +02:00
|
|
|
(unless noninteractive
|
2018-06-10 17:24:34 +02:00
|
|
|
(doom-initialize-modules))
|
2019-05-01 19:12:52 -04:00
|
|
|
(with-eval-after-load 'package
|
2019-03-06 21:16:07 -05:00
|
|
|
(require 'core-packages)
|
|
|
|
(doom-initialize-packages))
|
2017-06-08 11:47:56 +02:00
|
|
|
|
2015-06-04 18:23:21 -04:00
|
|
|
(provide 'core)
|
|
|
|
;;; core.el ends here
|