Merge branch 'develop' into solidity-mode
This commit is contained in:
commit
a814c833a2
146 changed files with 3283 additions and 2560 deletions
104
Makefile
104
Makefile
|
@ -1,12 +1,8 @@
|
|||
# Ensure emacs always runs from this makefile's PWD
|
||||
EMACS = emacs -q --eval "(setq user-emacs-directory default-directory load-prefer-newer t)"
|
||||
DOOM = $(EMACS) --batch -l init.el
|
||||
DOOMI = $(subst --batch,,$(DOOM))
|
||||
|
||||
DOOM = bin/doom
|
||||
MODULES = $(patsubst modules/%/, %, $(sort $(dir $(wildcard modules/*/ modules/*/*/))))
|
||||
|
||||
all:
|
||||
@$(DOOM) -f doom//reload-packages
|
||||
@$(DOOM) refresh
|
||||
|
||||
## Shortcuts
|
||||
a: autoloads
|
||||
|
@ -16,88 +12,66 @@ U: upgrade
|
|||
r: autoremove
|
||||
c: compile
|
||||
cc: compile-core
|
||||
ce: compile-elpa
|
||||
cp: compile-plugins
|
||||
re: recompile
|
||||
d: doctor
|
||||
|
||||
quickstart: | ~/.doom.d/init.el all recompile
|
||||
~/.doom.d/init.el:
|
||||
@echo "Creating ~/.doom.d directory"
|
||||
@mkdir ~/.doom.d && cp init.example.el ~/.doom.d/init.el
|
||||
@touch ~/.doom.d/config.el
|
||||
quickstart:
|
||||
@$(DOOM) quickstart
|
||||
|
||||
|
||||
## Package management
|
||||
install: | .local/autoloads.el
|
||||
@$(DOOM) -f doom//packages-install
|
||||
|
||||
update: | .local/autoloads.el
|
||||
@$(DOOM) -f doom//packages-update
|
||||
|
||||
autoremove: | .local/autoloads.el
|
||||
@$(DOOM) -f doom//packages-autoremove
|
||||
|
||||
install:
|
||||
@$(DOOM) install
|
||||
update:
|
||||
@$(DOOM) update
|
||||
autoremove:
|
||||
@$(DOOM) autoremove
|
||||
autoloads:
|
||||
@$(DOOM) -f doom//reload-autoloads
|
||||
|
||||
upgrade: | _upgrade recompile all
|
||||
_upgrade:
|
||||
@git pull origin $(shell git rev-parse --abbrev-ref HEAD)
|
||||
@$(DOOM) autoloads
|
||||
upgrade:
|
||||
@$(DOOM) upgrade
|
||||
|
||||
## Byte compilation
|
||||
# compile
|
||||
# compile-core
|
||||
compile:
|
||||
@$(DOOM) compile
|
||||
compile-core:
|
||||
@$(DOOM) compile :core
|
||||
compile-private:
|
||||
@$(DOOM) compile :private
|
||||
compile-plugins:
|
||||
@$(DOOM) compile :plugins
|
||||
recompile:
|
||||
@$(DOOM) recompile
|
||||
clean:
|
||||
@$(DOOM) clean
|
||||
# compile-module
|
||||
# compile-module/submodule
|
||||
compile: | clean
|
||||
@$(DOOM) -f doom//byte-compile
|
||||
|
||||
compile-core: | clean
|
||||
@$(DOOM) -f doom//byte-compile-core
|
||||
|
||||
compile-elpa:
|
||||
@$(DOOM) -f doom//byte-recompile-plugins
|
||||
|
||||
$(patsubst %, compile-%, $(MODULES)): | .local/autoloads.el
|
||||
@$(DOOM) -f doom//byte-compile -- $(patsubst compile-%, %, $@)
|
||||
|
||||
recompile:
|
||||
@$(DOOM) -f doom//byte-compile -- -r
|
||||
|
||||
clean:
|
||||
@$(DOOM) -f doom//clean-byte-compiled-files
|
||||
@$(DOOM) $@ $(subst compile-, , $@)
|
||||
|
||||
|
||||
## Unit tests
|
||||
# test
|
||||
# test-core
|
||||
test:
|
||||
@$(DOOM) test
|
||||
test-core:
|
||||
@$(DOOM) test :core
|
||||
# test-module
|
||||
# test-module/submodule
|
||||
test: | .local/autoloads.el
|
||||
@$(DOOM) -f doom//run-tests
|
||||
|
||||
test-core $(patsubst %, test-%, $(MODULES)): | .local/autoloads.el
|
||||
@$(DOOM) -f doom//run-tests -- $(subst test-, , $@)
|
||||
|
||||
# run tests interactively
|
||||
testi: | .local/autoloads.el
|
||||
@$(DOOMI) -f doom//run-tests
|
||||
$(patsubst %, test-%, $(MODULES)):
|
||||
@$(DOOM) test $(subst test-, , $@)
|
||||
|
||||
|
||||
## Utility tasks
|
||||
# Runs Emacs from a different folder than ~/.emacs.d; only use this for testing!
|
||||
run:
|
||||
@$(DOOMI) $(ARGS) --eval "(run-hooks 'after-init-hook 'emacs-startup-hook 'window-setup-hook)"
|
||||
@$(DOOM) run $(ARGS)
|
||||
# Prints debug info about your current setup
|
||||
info:
|
||||
@$(DOOM) info
|
||||
|
||||
# Diagnoses potential OS/environment issues
|
||||
doctor:
|
||||
@$(EMACS) --script bin/doom-doctor
|
||||
|
||||
# Prints debug info about your current setup
|
||||
info:
|
||||
@$(EMACS) --batch -l core/core.el -l core/autoload/util.el -f doom/info
|
||||
|
||||
## Internal tasks
|
||||
.local/autoloads.el:
|
||||
@$(DOOM) -f doom-initialize-autoloads
|
||||
@$(DOOM) doctor
|
||||
|
||||
.PHONY: all compile test testi clean
|
||||
|
|
73
bin/doom
Executable file
73
bin/doom
Executable file
|
@ -0,0 +1,73 @@
|
|||
#!/usr/bin/env bash
|
||||
":"; command -v emacs >/dev/null || { >&2 echo "Emacs isn't installed"; exit 1; } # -*-emacs-lisp-*-
|
||||
":"; VERSION=$(emacs --version | head -n1)
|
||||
":"; [[ $VERSION == *\ 2[0-2].[0-1].[0-9] ]] && { echo "You're running $VERSION"; echo "That version is too old to run Doom. Check your PATH"; echo; exit 2; }
|
||||
":"; DOOMDIR=$(dirname "${BASH_SOURCE:-${(%):-%x}}")/..
|
||||
":"; [[ $1 == doc || $1 == doctor ]] && { cd "$DOOMDIR"; exec emacs --script bin/doom-doctor; exit 0; }
|
||||
":"; [[ $1 == run ]] && { cd "$DOOMDIR"; shift; exec emacs -Q -l bin/doom "$@"; exit 0; }
|
||||
":"; exec emacs --quick --script "$0" -- $@
|
||||
":"; exit 0
|
||||
|
||||
(defun usage ()
|
||||
(with-temp-buffer
|
||||
(insert (format! "%s %s [COMMAND] [ARGS...]\n"
|
||||
(bold "Usage:")
|
||||
(file-name-nondirectory load-file-name))
|
||||
"\n"
|
||||
"A command line interfacing for managing Doom Emacs; including\n"
|
||||
"package management, diagnostics, unit tests, and byte-compilation.\n"
|
||||
"\n"
|
||||
"This tool also makes it trivial to launch Emacs out of a different\n"
|
||||
"folder or with a different private module.\n"
|
||||
"\n"
|
||||
(format! (bold "Example:\n"))
|
||||
" doom install\n"
|
||||
" doom help update\n"
|
||||
" doom compile :core lang/php lang/python\n"
|
||||
" doom run\n"
|
||||
" doom run -nw file.txt file2.el\n"
|
||||
" doom run -p ~/.other.doom.d -e ~/.other.emacs.d -nw file.txt\n"
|
||||
"\n"
|
||||
(format! (bold "Options:\n"))
|
||||
" -d --debug\t\tTurns on doom-debug-mode (and debug-on-error)\n"
|
||||
" -e --emacsd DIR\tUse the emacs config at DIR (e.g. ~/.emacs.d)\n"
|
||||
" -p --private DIR\tUse the private module at DIR (e.g. ~/.doom.d)\n"
|
||||
" -y --yes\t\tAuto-accept all confirmation prompts\n\n")
|
||||
(princ (buffer-string)))
|
||||
(doom--dispatch-help))
|
||||
|
||||
;;
|
||||
(let ((args (cdr (cdr (cdr command-line-args))))
|
||||
(emacs-dir (expand-file-name "../" (file-name-directory load-file-name))))
|
||||
;; Parse options
|
||||
(while (ignore-errors (string-prefix-p "-" (car args)))
|
||||
(pcase (pop args)
|
||||
((or "-d" "--debug")
|
||||
(setq doom-debug-mode t))
|
||||
((or "-p" "--private")
|
||||
(setq doom-private-dir (expand-file-name (pop args)))
|
||||
(or (file-directory-p doom-private-dir)
|
||||
(error "%s does not exist" doom-private-dir)))
|
||||
((or "-e" "--emacsd")
|
||||
(setq emacs-dir (expand-file-name (pop args)))
|
||||
(or (file-directory-p emacs-dir)
|
||||
(error "%s does not exist" emacs-dir)))
|
||||
((or "-y" "--yes")
|
||||
(setq doom-auto-accept t))))
|
||||
|
||||
;; Bootstrap Doom
|
||||
(load (expand-file-name "init" emacs-dir)
|
||||
nil 'nomessage)
|
||||
|
||||
(cond ((not noninteractive)
|
||||
(doom|run-all-startup-hooks))
|
||||
((and (not (cdr args))
|
||||
(member (car args) '("help" "h")))
|
||||
(usage))
|
||||
((not args)
|
||||
(error "Expecting a command"))
|
||||
((let ((default-directory user-emacs-directory))
|
||||
(setq argv nil
|
||||
noninteractive 'doom)
|
||||
(doom-dispatch args)))))
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env bash
|
||||
":"; command -v emacs >/dev/null || { >&2 echo "Emacs isn't installed"; exit 1; } # -*-emacs-lisp-*-
|
||||
":"; [[ $(emacs --version | head -n1) == *\ 2[0-2].[0-1].[0-9] ]] && { echo "You're running $(emacs --version | head -n1)"; echo "That version is too old to run the doctor. Check your PATH"; echo; exit 2; } || exec emacs --quick --script "$0"
|
||||
":"; VERSION=$(emacs --version | head -n1)
|
||||
":"; [[ $VERSION == *\ 2[0-2].[0-1].[0-9] ]] && { echo "You're running $VERSION"; echo "That version is too old to run the doctor. Check your PATH"; echo; exit 2; }
|
||||
":"; exec emacs --quick --script "$0"; exit 0
|
||||
|
||||
;; Uses a couple simple heuristics to locate issues with your environment that
|
||||
;; could interfere with running or setting up DOOM Emacs.
|
||||
|
@ -18,6 +20,7 @@
|
|||
|
||||
;;
|
||||
(defvar doom-init-p nil)
|
||||
(defvar doom-warnings 0)
|
||||
(defvar doom-errors 0)
|
||||
(defmacro when! (cond &rest body)
|
||||
(declare (indent defun))
|
||||
|
@ -62,7 +65,7 @@
|
|||
(format (concat prefix ,msg)
|
||||
,@args))))
|
||||
(defmacro error! (&rest args) `(progn (msg! (color 31 ,@args)) (setq doom-errors (+ doom-errors 1))))
|
||||
(defmacro warn! (&rest args) `(progn (msg! (color 33 ,@args)) (setq doom-errors (+ doom-errors 1))))
|
||||
(defmacro warn! (&rest args) `(progn (msg! (color 33 ,@args)) (setq doom-warnings (+ doom-warnings 1))))
|
||||
(defmacro success! (&rest args) `(msg! (color 32 ,@args)))
|
||||
(defmacro section! (&rest args)
|
||||
`(msg! (color 1 (color 34 ,@args))))
|
||||
|
@ -112,11 +115,8 @@
|
|||
(message "Compiled with:\n%s" (indented 2 system-configuration-features)))
|
||||
(message "uname -a:\n%s\n" (indented 2 (sh "uname -a")))
|
||||
|
||||
(msg! "----\n")
|
||||
|
||||
;; --- is emacs set up properly? ------------------------------
|
||||
|
||||
(section! "test-emacs")
|
||||
(when (version< emacs-version "25.1")
|
||||
(error! "Important: Emacs %s detected [%s]" emacs-version (executable-find "emacs"))
|
||||
(explain!
|
||||
|
@ -125,7 +125,6 @@
|
|||
(concat "\nMacOS users should use homebrew (https://brew.sh) to install Emacs\n"
|
||||
" brew install emacs --with-modules --with-imagemagick --with-cocoa"))))
|
||||
|
||||
(section! "test-private-config")
|
||||
(let ((xdg-dir (concat (or (getenv "XDG_CONFIG_HOME")
|
||||
"~/.config")
|
||||
"/doom/"))
|
||||
|
@ -140,14 +139,14 @@
|
|||
|
||||
;; --- is the environment set up properly? --------------------
|
||||
|
||||
;; windows? windows
|
||||
(section! "test-windows")
|
||||
;; on windows?
|
||||
(section! "Checking your OS...")
|
||||
(when (memq system-type '(windows-nt ms-dos cygwin))
|
||||
(warn! "Warning: Windows detected")
|
||||
(explain! "DOOM was designed for MacOS and Linux. Expect a bumpy ride!"))
|
||||
|
||||
;; are all default fonts present
|
||||
(section! "test-fonts")
|
||||
;; are all default fonts present?
|
||||
(section! "Checking your fonts...")
|
||||
(if (not (fboundp 'find-font))
|
||||
(progn
|
||||
(warn! "Warning: unable to detect font")
|
||||
|
@ -170,7 +169,7 @@
|
|||
"case, ignore this warning."))))))
|
||||
|
||||
;; gnutls-cli & openssl
|
||||
(section! "test-gnutls")
|
||||
(section! "Checking gnutls/openssl...")
|
||||
(cond ((executable-find "gnutls-cli"))
|
||||
((executable-find "openssl")
|
||||
(let* ((output (sh "openssl ciphers -v"))
|
||||
|
@ -205,7 +204,8 @@
|
|||
"network, provider, government, neckbearded mother-in-laws, geeky roommates, "
|
||||
"or just about anyone who knows more about computers than you do!")))
|
||||
|
||||
(section! "test-tls")
|
||||
;; are certificates validated properly?
|
||||
(section! "Testing your root certificates...")
|
||||
(cond ((not (string-match-p "\\_<GNUTLS\\_>" system-configuration-features))
|
||||
(warn! "Warning: You didn't install Emacs with gnutls support")
|
||||
(explain!
|
||||
|
@ -227,8 +227,7 @@
|
|||
(gnutls-verify-error t))
|
||||
(dolist (url '("https://elpa.gnu.org" "https://melpa.org"))
|
||||
(when! (condition-case-unless-debug e
|
||||
(if (let ((inhibit-message t)) (url-retrieve-synchronously url))
|
||||
(ignore (success! "Validated %s" url))
|
||||
(unless (let ((inhibit-message t)) (url-retrieve-synchronously url))
|
||||
'empty)
|
||||
('timed-out 'timeout)
|
||||
('error e))
|
||||
|
@ -245,7 +244,7 @@
|
|||
t
|
||||
'empty)
|
||||
('timed-out 'timeout)
|
||||
('error (ignore (success! "Successfully rejected %s" url))))
|
||||
('error))
|
||||
(pcase it
|
||||
(`empty (error! "Couldn't reach %s" url))
|
||||
(`timeout (error! "Timed out trying to contact %s" ex))
|
||||
|
@ -254,8 +253,8 @@
|
|||
|
||||
((error! "Nope!")))
|
||||
|
||||
;; bsd vs gnu tar
|
||||
(section! "test-tar")
|
||||
;; which variant of tar is on your system? bsd or gnu tar?
|
||||
(section! "Checking for GNU/BSD tar...")
|
||||
(let ((tar-bin (or (executable-find "gtar")
|
||||
(executable-find "tar"))))
|
||||
(if tar-bin
|
||||
|
@ -276,14 +275,11 @@
|
|||
|
||||
;; --- are your modules set up properly? ----------------------
|
||||
|
||||
(message "\n----")
|
||||
(let (doom-core-packages doom-debug-mode)
|
||||
(condition-case ex
|
||||
(let ((inhibit-message t))
|
||||
(load "~/.emacs.d/core/core.el" nil t)
|
||||
(let (noninteractive)
|
||||
(doom-initialize t)
|
||||
(doom|finalize))
|
||||
(load (concat user-emacs-directory "init.el") nil t)
|
||||
(doom-initialize-modules)
|
||||
(success! "Attempt to load DOOM: success! Loaded v%s" doom-version))
|
||||
('error
|
||||
(warn! "Attempt to load DOOM: failed\n %s\n"
|
||||
|
@ -291,14 +287,14 @@
|
|||
(setq doom-modules nil))))
|
||||
|
||||
(when (bound-and-true-p doom-modules)
|
||||
(section! "test-modules")
|
||||
(section! "Checking your enabled modules...")
|
||||
(let ((indent 4))
|
||||
(advice-add #'require :around #'doom*shut-up)
|
||||
(maphash
|
||||
(lambda (key plist)
|
||||
(condition-case ex
|
||||
(let ((doctor-file (doom-module-expand-file (car key) (cdr key) "doctor.el"))
|
||||
(packages-file (doom-module-expand-file (car key) (cdr key) "packages.el"))
|
||||
(let ((doctor-file (doom-module-path (car key) (cdr key) "doctor.el"))
|
||||
(packages-file (doom-module-path (car key) (cdr key) "packages.el"))
|
||||
doom-packages)
|
||||
(when (or (file-exists-p doctor-file)
|
||||
(file-exists-p packages-file))
|
||||
|
@ -306,7 +302,8 @@
|
|||
(doom--stage 'packages))
|
||||
(when (load packages-file t t)
|
||||
(dolist (package (cl-remove-if #'package-installed-p doom-packages :key #'car))
|
||||
(error! "%s is not installed" (car package))))
|
||||
(unless (package-built-in-p (car package))
|
||||
(error! "%s is not installed" (car package)))))
|
||||
(let ((doom--stage 'doctor))
|
||||
(load doctor-file t t)))))
|
||||
('error
|
||||
|
@ -314,7 +311,13 @@
|
|||
doom-modules)))
|
||||
|
||||
;;
|
||||
(message "\n----")
|
||||
(if (> doom-errors 0)
|
||||
(warn! "There were %s issues!" doom-errors)
|
||||
(message "\n")
|
||||
(dolist (msg (list (list doom-errors "error" 31)
|
||||
(list doom-warnings "warning" 33)))
|
||||
(when (> (car msg) 0)
|
||||
(message (color (nth 2 msg) (if (= (car msg) 1) "There is %d %s!" "There are %d %ss!")
|
||||
(car msg) (nth 1 msg)))))
|
||||
|
||||
(when (and (zerop doom-errors)
|
||||
(zerop doom-warnings))
|
||||
(success! "Everything seems fine, happy Emacs'ing!"))
|
||||
|
|
14
bin/doom.cmd
Normal file
14
bin/doom.cmd
Normal file
|
@ -0,0 +1,14 @@
|
|||
:: Forward the ./doom script to Emacs
|
||||
|
||||
@ECHO OFF
|
||||
PUSHD "%~dp0" >NUL
|
||||
|
||||
IF %1=="run" (
|
||||
SHIFT
|
||||
emacs -Q $* -l init.el -f "doom|run-all-startup-hooks"
|
||||
) ELSE (
|
||||
emacs --quick --script ./doom -- $*
|
||||
)
|
||||
|
||||
POPD >NUL
|
||||
ECHO ON
|
|
@ -12,8 +12,6 @@
|
|||
;; Like persistent-soft, caches assume a 2-tier structure, where all caches are
|
||||
;; namespaced by location.
|
||||
|
||||
(require 'persistent-soft)
|
||||
|
||||
(defvar doom-cache-alists ()
|
||||
"An alist of alists, containing lists of variables for the doom cache library
|
||||
to persist across Emacs sessions.")
|
||||
|
|
303
core/autoload/debug.el
Normal file
303
core/autoload/debug.el
Normal file
|
@ -0,0 +1,303 @@
|
|||
;;; core/autoload/debug.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defun doom-template-insert (template)
|
||||
"TODO"
|
||||
(let ((file (expand-file-name (format "templates/%s" template) doom-core-dir)))
|
||||
(when (file-exists-p file)
|
||||
(insert-file-contents file))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-info ()
|
||||
"Returns diagnostic information about the current Emacs session in markdown,
|
||||
ready to be pasted in a bug report on github."
|
||||
(doom-initialize)
|
||||
(require 'vc-git)
|
||||
(let ((default-directory doom-emacs-dir)
|
||||
(doom-modules (doom-module-table)))
|
||||
(format
|
||||
(concat "- OS: %s (%s)\n"
|
||||
"- Emacs: %s (%s)\n"
|
||||
"- Doom: %s (%s %s)\n"
|
||||
"- Graphic display: %s (daemon: %s)\n"
|
||||
"- System features: %s\n"
|
||||
"- Details:\n"
|
||||
" ```elisp\n"
|
||||
" uname -a: %s\n"
|
||||
" modules: %s\n"
|
||||
" packages: %s\n"
|
||||
" elc dirs: %s\n"
|
||||
" exec-path: %s\n"
|
||||
" ```")
|
||||
system-type system-configuration
|
||||
emacs-version (format-time-string "%b %d, %Y" emacs-build-time)
|
||||
doom-version
|
||||
(if-let* ((branch (vc-git--symbolic-ref "core/core.el")))
|
||||
branch
|
||||
"n/a")
|
||||
(if-let* ((rev (vc-git-working-revision "core/core.el")))
|
||||
rev
|
||||
"n/a")
|
||||
(display-graphic-p) (daemonp)
|
||||
(bound-and-true-p system-configuration-features)
|
||||
;; details
|
||||
(with-temp-buffer
|
||||
(unless (zerop (call-process "uname" nil t nil "-a"))
|
||||
(insert (format "%s" system-type)))
|
||||
(string-trim (buffer-string)))
|
||||
(or (cl-loop with cat = nil
|
||||
for key being the hash-keys of doom-modules
|
||||
if (or (not cat) (not (eq cat (car key))))
|
||||
do (setq cat (car key)) and collect cat
|
||||
else collect
|
||||
(let ((flags (doom-module-get cat (cdr key) :flags)))
|
||||
(if flags
|
||||
`(,(cdr key) ,@flags)
|
||||
(cdr key))))
|
||||
"n/a")
|
||||
(or (let (packages)
|
||||
(ignore-errors
|
||||
(require 'async)
|
||||
;; collect these in another session to protect this
|
||||
;; session's state
|
||||
(async-get
|
||||
(async-start
|
||||
`(lambda ()
|
||||
(let ((noninteractive t)
|
||||
(load-path ',load-path)
|
||||
(package-alist ',package-alist))
|
||||
(load ,(expand-file-name "init.el" doom-emacs-dir))
|
||||
(doom-get-packages)))
|
||||
(lambda (p) (setq packages p))))
|
||||
(cl-loop for pkg in (cl-sort packages #'string-lessp
|
||||
:key (lambda (x) (symbol-name (car x))))
|
||||
collect (if (cdr pkg)
|
||||
(format "%s" pkg)
|
||||
(symbol-name (car pkg))))))
|
||||
"n/a")
|
||||
(or (ignore-errors
|
||||
(cl-delete-duplicates
|
||||
(cl-loop for file in (append (reverse (directory-files-recursively doom-core-dir "\\.elc$"))
|
||||
(cl-loop for dir in doom-modules-dirs
|
||||
nconc (directory-files-recursively dir "\\.elc$")))
|
||||
collect (file-relative-name (file-name-directory file) doom-emacs-dir))
|
||||
:test #'equal))
|
||||
"n/a")
|
||||
;; abbreviate $HOME to hide username
|
||||
(mapcar #'abbreviate-file-name exec-path))))
|
||||
|
||||
|
||||
;;
|
||||
;; Commands
|
||||
;;
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/info ()
|
||||
"Collects some debug information about your Emacs session, formats it into
|
||||
markdown and copies it to your clipboard, ready to be pasted into bug reports!"
|
||||
(declare (interactive-only t))
|
||||
(interactive)
|
||||
(message "Generating Doom info...")
|
||||
(if noninteractive
|
||||
(print! (doom-info))
|
||||
(kill-new (doom-info))
|
||||
(message "Done! Copied to clipboard.")))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/am-i-secure ()
|
||||
"Test to see if your root certificates are securely configured in emacs."
|
||||
(declare (interactive-only t))
|
||||
(interactive)
|
||||
(unless (string-match-p "\\_<GNUTLS\\_>" system-configuration-features)
|
||||
(warn "gnutls support isn't built into Emacs, there may be problems"))
|
||||
(if-let* ((bad-hosts
|
||||
(cl-loop for bad
|
||||
in '("https://wrong.host.badssl.com/"
|
||||
"https://self-signed.badssl.com/")
|
||||
if (condition-case _e
|
||||
(url-retrieve-synchronously bad)
|
||||
(error nil))
|
||||
collect bad)))
|
||||
(error "tls seems to be misconfigured (it got %s)."
|
||||
bad-hosts)
|
||||
(url-retrieve "https://badssl.com"
|
||||
(lambda (status)
|
||||
(if (or (not status) (plist-member status :error))
|
||||
(warn "Something went wrong.\n\n%s" (pp-to-string status))
|
||||
(message "Your trust roots are set up properly.\n\n%s" (pp-to-string status))
|
||||
t)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/version ()
|
||||
"Display the current version of Doom & Emacs, including the current Doom
|
||||
branch and commit."
|
||||
(interactive)
|
||||
(require 'vc-git)
|
||||
(print! "Doom v%s (Emacs v%s)\nBranch: %s\nCommit: %s."
|
||||
doom-version
|
||||
emacs-version
|
||||
(or (vc-git--symbolic-ref doom-core-dir)
|
||||
"n/a")
|
||||
(or (vc-git-working-revision doom-core-dir)
|
||||
"n/a")))
|
||||
|
||||
|
||||
;;
|
||||
;; Vanilla sandbox
|
||||
;;
|
||||
|
||||
(defun doom--run-vanilla-sandbox ()
|
||||
"TODO"
|
||||
(interactive)
|
||||
(when (equal (buffer-name) "*doom:vanilla-sandbox*")
|
||||
(let ((file (make-temp-file "doom-eval-")))
|
||||
(write-file file)
|
||||
(require 'pp)
|
||||
(require 'restart-emacs)
|
||||
(restart-emacs--launch-other-emacs
|
||||
(list "-Q"
|
||||
"--eval"
|
||||
(prin1-to-string
|
||||
`(setq user-emacs-directory ,doom-emacs-dir
|
||||
package--init-file-ensured t
|
||||
package-user-dir ,package-user-dir
|
||||
package-archives ',package-archives
|
||||
debug-on-error t))
|
||||
"-f" "package-initialize"
|
||||
"-l" file
|
||||
"--eval" (prin1-to-string `(delete-file ,file)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/open-vanilla-sandbox ()
|
||||
"Open an Emacs Lisp buffer destinated to run in a blank Emacs session.
|
||||
|
||||
This vanilla sandbox is started with emacs -Q, and provides a testbed for
|
||||
debugging code without Doom standing in the way, and without sacrificing
|
||||
access to the installed packages."
|
||||
(interactive)
|
||||
(let ((buf (get-buffer-create "*doom:vanilla-sandbox*")))
|
||||
(with-current-buffer buf
|
||||
(emacs-lisp-mode)
|
||||
(local-set-key (kbd "C-c C-c") #'doom--run-vanilla-sandbox)
|
||||
(local-set-key (kbd "C-c C-k") #'kill-this-buffer)
|
||||
(setq header-line-format "C-c C-c to run the session / C-c C-k to abort it")
|
||||
(setq-local default-directory doom-emacs-dir)
|
||||
(doom-template-insert "VANILLA_SANDBOX")
|
||||
(goto-char (point-max)))
|
||||
(pop-to-buffer buf)))
|
||||
|
||||
|
||||
;;
|
||||
;; Reporting bugs
|
||||
;;
|
||||
|
||||
(defun doom--open-bug-report ()
|
||||
"TODO"
|
||||
(interactive)
|
||||
(let ((url "https://github.com/hlissner/doom-emacs/issues/new?body="))
|
||||
;; TODO Refactor me
|
||||
(save-restriction
|
||||
(widen)
|
||||
(goto-char (point-min))
|
||||
(re-search-forward "^-------------------------------------------------------------------\n" nil t)
|
||||
(skip-chars-forward " \n\t")
|
||||
(condition-case e
|
||||
(progn
|
||||
(save-excursion
|
||||
(when (and (re-search-backward "\\+ [ ] " nil t)
|
||||
(not (y-or-n-p "You haven't checked all the boxes. Continue anyway?")))
|
||||
(error "Aborted submit")))
|
||||
(narrow-to-region (point) (point-max))
|
||||
(let ((text (buffer-string)))
|
||||
;; `url-encode-url' doesn't encode ampersands
|
||||
(setq text (replace-regexp-in-string "&" "%26" text))
|
||||
(setq url (url-encode-url (concat url text)))
|
||||
;; HACK: encode some characters according to HTML URL Encoding Reference
|
||||
;; http://www.w3schools.com/tags/ref_urlencode.asp
|
||||
(setq url (replace-regexp-in-string "#" "%23" url))
|
||||
(setq url (replace-regexp-in-string ";" "%3B" url))
|
||||
(browse-url url)))
|
||||
(error (signal (car e) (car e)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/open-bug-report ()
|
||||
"Open a markdown buffer destinated to populate the New Issue page on Doom
|
||||
Emacs' issue tracker.
|
||||
|
||||
If called when a backtrace buffer is present, it and the output of `doom-info'
|
||||
will be automatically appended to the result."
|
||||
(interactive)
|
||||
;; TODO Refactor me
|
||||
(let ((backtrace
|
||||
(when (get-buffer "*Backtrace*")
|
||||
(with-current-buffer "*Backtrace*"
|
||||
(string-trim
|
||||
(buffer-substring-no-properties
|
||||
(point-min)
|
||||
(min (point-max) 1000))))))
|
||||
(buf (get-buffer-create "*doom:vanilla-sandbox*")))
|
||||
(with-current-buffer buf
|
||||
(erase-buffer)
|
||||
(condition-case _ (gfm-mode)
|
||||
(error (text-mode)))
|
||||
(doom-template-insert "SUBMIT_BUG_REPORT")
|
||||
(goto-char (point-max))
|
||||
(let ((pos (point)))
|
||||
(save-excursion
|
||||
(insert
|
||||
"\n" (doom-info) "\n"
|
||||
(if (and backtrace (not (string-empty-p backtrace)))
|
||||
(format "\n<details>\n<summary>Backtrace</summary>\n\n```\n%s\n```\n</details>\n"
|
||||
backtrace)
|
||||
"")))
|
||||
(local-set-key (kbd "C-c C-c") #'doom--open-bug-report)
|
||||
(local-set-key (kbd "C-c C-k") #'kill-this-buffer)
|
||||
(setq header-line-format "C-c C-c to submit / C-c C-k to close")
|
||||
;;
|
||||
(narrow-to-region (point-min) pos)
|
||||
(goto-char (point-min)))
|
||||
(pop-to-buffer buf))))
|
||||
|
||||
|
||||
;;
|
||||
;; Profiling
|
||||
;;
|
||||
|
||||
(defvar doom--profiler nil)
|
||||
;;;###autoload
|
||||
(defun doom/toggle-profiler ()
|
||||
"Toggle the Emacs profiler. Run it again to see the profiling report."
|
||||
(interactive)
|
||||
(if (not doom--profiler)
|
||||
(profiler-start 'cpu+mem)
|
||||
(profiler-report)
|
||||
(profiler-stop))
|
||||
(setq doom--profiler (not doom--profiler)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/profile-emacs ()
|
||||
"Profile the startup time of Emacs in the background with ESUP.
|
||||
If INIT-FILE is non-nil, profile that instead of USER-INIT-FILE."
|
||||
(interactive)
|
||||
(require 'esup)
|
||||
(let ((init-file esup-user-init-file))
|
||||
(message "Starting esup...")
|
||||
(esup-reset)
|
||||
(setq esup-server-process (esup-server-create (esup-select-port)))
|
||||
(setq esup-server-port (process-contact esup-server-process :service))
|
||||
(message "esup process started on port %s" esup-server-port)
|
||||
(let ((process-args `("*esup-child*"
|
||||
"*esup-child*"
|
||||
,esup-emacs-path
|
||||
"-q"
|
||||
"-L" ,esup-load-path
|
||||
"-l" "esup-child"
|
||||
,(format "--eval=(esup-child-run \"%s\" \"%s\" %d)"
|
||||
init-file
|
||||
esup-server-port
|
||||
esup-depth)
|
||||
"--eval=(run-hooks 'after-init-hook 'emacs-startup-hook 'window-setup-hook)")))
|
||||
(when esup-run-as-batch-p
|
||||
(setq process-args (append process-args '("--batch"))))
|
||||
(setq esup-child-process (apply #'start-process process-args)))
|
||||
(set-process-sentinel esup-child-process 'esup-child-process-sentinel)))
|
||||
|
|
@ -215,17 +215,21 @@ possible, or just one char if that's not possible."
|
|||
(t (delete-char (- n) killflag))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/retab (&optional beg end)
|
||||
(defun doom/retab (arg &optional beg end)
|
||||
"Converts tabs-to-spaces or spaces-to-tabs within BEG and END (defaults to
|
||||
buffer start and end, to make indentation consistent. Which it does depends on
|
||||
the value of `indent-tab-mode'."
|
||||
(interactive "r")
|
||||
the value of `indent-tab-mode'.
|
||||
|
||||
If ARG (universal argument) is non-nil, retab the current buffer using the
|
||||
opposite indentation style."
|
||||
(interactive "Pr")
|
||||
(unless (and beg end)
|
||||
(setq beg (point-min)
|
||||
end (point-max)))
|
||||
(let ((indent-tabs-mode (if arg (not indent-tabs-mode) indent-tabs-mode)))
|
||||
(if indent-tabs-mode
|
||||
(tabify beg end)
|
||||
(untabify beg end)))
|
||||
(untabify beg end))))
|
||||
|
||||
(defvar-local doom--buffer-narrowed-origin nil)
|
||||
;;;###autoload
|
||||
|
|
|
@ -56,9 +56,10 @@
|
|||
(not force-p)
|
||||
(not (y-or-n-p (format "File already exists at %s, overwrite?" short-new-name))))
|
||||
(throw 'status 'aborted))
|
||||
(t
|
||||
((file-exists-p old-path)
|
||||
(copy-file old-path new-path t)
|
||||
short-new-name))))
|
||||
short-new-name)
|
||||
(short-new-name))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/delete-this-file (&optional path force-p)
|
||||
|
@ -74,8 +75,7 @@ kills the buffer. If FORCE-P, force the deletion (don't ask for confirmation)."
|
|||
((not (or force-p (y-or-n-p (format "Really delete %s?" fbase))))
|
||||
(message "Aborted")
|
||||
nil)
|
||||
(t
|
||||
(unwind-protect
|
||||
((unwind-protect
|
||||
(progn (delete-file path) t)
|
||||
(let ((short-path (file-relative-name path (doom-project-root))))
|
||||
(if (file-exists-p path)
|
||||
|
@ -107,7 +107,8 @@ file if it exists, without confirmation."
|
|||
(let ((old-path (buffer-file-name))
|
||||
(new-path (expand-file-name new-path)))
|
||||
(when-let* ((dest (doom--copy-file old-path new-path force-p)))
|
||||
(delete-file old-path)
|
||||
(when (file-exists-p old-path)
|
||||
(delete-file old-path))
|
||||
(kill-this-buffer)
|
||||
(find-file new-path)
|
||||
(doom--forget-file old-path new-path)
|
||||
|
|
|
@ -1,22 +1,5 @@
|
|||
;;; core/autoload/help.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/describe-setting (setting)
|
||||
"Open the documentation of SETTING (a keyword defined with `def-setting!').
|
||||
|
||||
Defaults to the "
|
||||
(interactive
|
||||
(let ((sym (symbol-at-point)))
|
||||
(list (completing-read "Describe setting: "
|
||||
(sort (mapcar #'car doom-settings) #'string-lessp)
|
||||
nil t (if (keywordp sym) (symbol-name sym))))))
|
||||
(let ((fn (cdr (assq (intern setting) doom-settings))))
|
||||
(unless fn
|
||||
(error "'%s' is not a valid DOOM setting" setting))
|
||||
(describe-function fn)))
|
||||
|
||||
|
||||
;;
|
||||
(defvar doom--module-mode-alist
|
||||
'((c-mode :lang cc)
|
||||
(c++-mode :lang cc)
|
||||
|
@ -58,6 +41,42 @@ Defaults to the "
|
|||
(stylus-mode :lang web))
|
||||
"TODO")
|
||||
|
||||
(defvar doom-docs-dir (concat doom-emacs-dir "docs/")
|
||||
"TODO")
|
||||
|
||||
|
||||
;;
|
||||
;; Helpers
|
||||
;;
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-active-minor-modes ()
|
||||
"Return a list of active minor-mode symbols."
|
||||
(cl-loop for mode in minor-mode-list
|
||||
if (and (boundp mode) (symbol-value mode))
|
||||
collect mode))
|
||||
|
||||
|
||||
|
||||
;;
|
||||
;; Commands
|
||||
;;
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/describe-setting (setting)
|
||||
"Open the documentation of SETTING (a keyword defined with `def-setting!').
|
||||
|
||||
Defaults to the "
|
||||
(interactive
|
||||
(let ((sym (symbol-at-point)))
|
||||
(list (completing-read "Describe setting: "
|
||||
(sort (mapcar #'car doom-settings) #'string-lessp)
|
||||
nil t (if (keywordp sym) (symbol-name sym))))))
|
||||
(let ((fn (cdr (assq (intern setting) doom-settings))))
|
||||
(unless fn
|
||||
(error "'%s' is not a valid DOOM setting" setting))
|
||||
(describe-function fn)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/describe-module (module)
|
||||
"Open the documentation of MODULE (a string that represents the category and
|
||||
|
@ -75,6 +94,7 @@ in, or d) the module associated with the current major mode (see
|
|||
"init.el")
|
||||
(thing-at-point 'sexp t)))
|
||||
((save-excursion
|
||||
(require 'smartparens)
|
||||
(ignore-errors
|
||||
(sp-beginning-of-sexp)
|
||||
(unless (eq (char-after) ?\()
|
||||
|
@ -97,22 +117,58 @@ in, or d) the module associated with the current major mode (see
|
|||
(mapcar #'intern (split-string module " "))
|
||||
(unless (doom-module-p category submodule)
|
||||
(error "'%s' isn't a valid module" module))
|
||||
(let ((doc-path (doom-module-expand-file category submodule "README.org")))
|
||||
(let ((doc-path (doom-module-path category submodule "README.org")))
|
||||
(unless (file-exists-p doc-path)
|
||||
(error "There is no documentation for this module"))
|
||||
(find-file doc-path))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/version ()
|
||||
"Display the current version of Doom & Emacs, including the current Doom
|
||||
branch and commit."
|
||||
(defun doom/describe-active-minor-mode (mode)
|
||||
"Get information on an active minor mode. Use `describe-minor-mode' for a
|
||||
selection of all minor-modes, active or not."
|
||||
(interactive
|
||||
(list (completing-read "Minor mode: "
|
||||
(doom-active-minor-modes))))
|
||||
(describe-minor-mode-from-symbol
|
||||
(cl-typecase mode
|
||||
(string (intern mode))
|
||||
(symbol mode)
|
||||
(t (error "Expected a symbol/string, got a %s" (type-of mode))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/what-face (&optional pos)
|
||||
"Shows all faces and overlay faces at point.
|
||||
|
||||
Interactively prints the list to the echo area. Noninteractively, returns a list
|
||||
whose car is the list of faces and cadr is the list of overlay faces."
|
||||
(interactive)
|
||||
(message "Doom v%s (Emacs v%s). Branch: %s. Commit: %s."
|
||||
doom-version
|
||||
emacs-version
|
||||
(if-let* ((branch (vc-git--symbolic-ref "core/core.el")))
|
||||
branch
|
||||
(let* ((pos (or pos (point)))
|
||||
(faces (let ((face (get-text-property pos 'face)))
|
||||
(if (keywordp (car-safe face))
|
||||
(list face)
|
||||
(cl-loop for f in (doom-enlist face) collect f))))
|
||||
(overlays (cl-loop for ov in (overlays-at pos (1+ pos))
|
||||
nconc (doom-enlist (overlay-get ov 'face)))))
|
||||
(cond ((called-interactively-p 'any)
|
||||
(message "%s %s\n%s %s"
|
||||
(propertize "Faces:" 'face 'font-lock-comment-face)
|
||||
(if faces
|
||||
(cl-loop for face in faces
|
||||
if (listp face)
|
||||
concat (format "'%s " face)
|
||||
else
|
||||
concat (concat (propertize (symbol-name face) 'face face) " "))
|
||||
"n/a ")
|
||||
(if-let* ((rev (vc-git-working-revision "core/core.el")))
|
||||
rev
|
||||
(propertize "Overlays:" 'face 'font-lock-comment-face)
|
||||
(if overlays
|
||||
(cl-loop for ov in overlays
|
||||
concat (concat (propertize (symbol-name ov) 'face ov) " "))
|
||||
"n/a")))
|
||||
(t
|
||||
(and (or faces overlays)
|
||||
(list faces overlays))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//open-manual ()
|
||||
(interactive)
|
||||
(find-file (expand-file-name "index.org" doom-docs-dir)))
|
||||
|
|
|
@ -1,55 +1,68 @@
|
|||
;;; core/autoload/message.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defconst doom-message-fg
|
||||
'((reset . 0)
|
||||
(black . 30)
|
||||
(red . 31)
|
||||
(green . 32)
|
||||
(yellow . 33)
|
||||
(blue . 34)
|
||||
(magenta . 35)
|
||||
(cyan . 36)
|
||||
(white . 37))
|
||||
'((black 30 term-color-black)
|
||||
(red 31 term-color-red)
|
||||
(green 32 term-color-green)
|
||||
(yellow 33 term-color-yellow)
|
||||
(blue 34 term-color-blue)
|
||||
(magenta 35 term-color-magenta)
|
||||
(cyan 36 term-color-cyan)
|
||||
(white 37 term-color-white))
|
||||
"List of text colors.")
|
||||
|
||||
(defconst doom-message-bg
|
||||
'((on-black . 40)
|
||||
(on-red . 41)
|
||||
(on-green . 42)
|
||||
(on-yellow . 43)
|
||||
(on-blue . 44)
|
||||
(on-magenta . 45)
|
||||
(on-cyan . 46)
|
||||
(on-white . 47))
|
||||
'((on-black 40 term-color-black)
|
||||
(on-red 41 term-color-red)
|
||||
(on-green 42 term-color-green)
|
||||
(on-yellow 43 term-color-yellow)
|
||||
(on-blue 44 term-color-blue)
|
||||
(on-magenta 45 term-color-magenta)
|
||||
(on-cyan 46 term-color-cyan)
|
||||
(on-white 47 term-color-white))
|
||||
"List of colors to draw text on.")
|
||||
|
||||
(defconst doom-message-fx
|
||||
'((bold . 1)
|
||||
(dark . 2)
|
||||
(italic . 3)
|
||||
(underscore . 4)
|
||||
(blink . 5)
|
||||
(rapid . 6)
|
||||
(contrary . 7)
|
||||
(concealed . 8)
|
||||
(strike . 9))
|
||||
'((bold 1 :weight bold)
|
||||
(dark 2)
|
||||
(italic 3 :slant italic)
|
||||
(underscore 4 :underline t)
|
||||
(blink 5)
|
||||
(rapid 6)
|
||||
(contrary 7)
|
||||
(concealed 8)
|
||||
(strike 9 :strike-through t))
|
||||
"List of styles.")
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-ansi-apply (code message &rest args)
|
||||
"Apply the ansi CODE to formatted MESSAGE with ARGS."
|
||||
(let ((rule (or (assq code doom-message-fg)
|
||||
(assq code doom-message-bg)
|
||||
(assq code doom-message-fx))))
|
||||
"Apply CODE to formatted MESSAGE with ARGS. CODE is derived from any of
|
||||
`doom-message-fg', `doom-message-bg' or `doom-message-fx'.
|
||||
|
||||
In a noninteractive session, this wraps the result in ansi color codes.
|
||||
Otherwise, it maps colors to a term-color-* face."
|
||||
(let ((text (apply #'format message args)))
|
||||
(if noninteractive
|
||||
(format "\e[%dm%s\e[%dm"
|
||||
(cdr rule)
|
||||
(apply #'format message args)
|
||||
0)))
|
||||
(cadr
|
||||
(or (assq code doom-message-fg)
|
||||
(assq code doom-message-bg)
|
||||
(assq code doom-message-fx)))
|
||||
text 0)
|
||||
(require 'term) ; piggyback on term's color faces
|
||||
(propertize
|
||||
text 'face
|
||||
(let (spec)
|
||||
(cond ((setq spec (caddr (assq code doom-message-fg)))
|
||||
`(:foreground ,(face-foreground spec)))
|
||||
((setq spec (caddr (assq code doom-message-bg)))
|
||||
`(:background ,(face-background spec)))
|
||||
((cddr (assq code doom-message-fx)))))))))
|
||||
|
||||
;;;###autoload
|
||||
(defmacro format! (message &rest args)
|
||||
"An alternative to `format' that strips out ANSI codes if used in an
|
||||
interactive session."
|
||||
"An alternative to `format' that understands (color ...) and converts them
|
||||
into faces or ANSI codes depending on the type of sesssion we're in."
|
||||
`(cl-flet*
|
||||
(,@(cl-loop for rule
|
||||
in (append doom-message-fg doom-message-bg doom-message-fx)
|
||||
|
@ -63,19 +76,19 @@ interactive session."
|
|||
(format ,message ,@args)))
|
||||
|
||||
;;;###autoload
|
||||
(defmacro message! (message &rest args)
|
||||
"An alternative to `message' that strips out ANSI codes if used in an
|
||||
interactive session."
|
||||
`(if noninteractive
|
||||
(defmacro print! (message &rest args)
|
||||
"Uses `message' in interactive sessions and `princ' otherwise (prints to
|
||||
standard out).
|
||||
|
||||
Can be colored using (color ...) blocks:
|
||||
|
||||
(print! \"Hello %s %s\" (bold (blue \"How are you?\")))
|
||||
(print! \"Hello %s %s\" (red \"World\"))
|
||||
(print! (green \"Great %s!\" \"success\"))
|
||||
|
||||
Uses faces in interactive sessions and ANSI codes otherwise."
|
||||
`(if (not noninteractive)
|
||||
(message (format! ,message ,@args))
|
||||
(let ((buf (get-buffer-create " *doom messages*")))
|
||||
(with-current-buffer buf
|
||||
(goto-char (point-max))
|
||||
(let ((beg (point))
|
||||
end)
|
||||
(insert (format! ,message ,@args))
|
||||
(insert "\n")
|
||||
(setq end (point))
|
||||
(ansi-color-apply-on-region beg end)))
|
||||
(pop-to-buffer buf)
|
||||
(goto-char (point-max)))))
|
||||
;; princ prints to stdout, message to stderr
|
||||
(princ (format! ,message ,@args))
|
||||
(terpri)))
|
||||
|
|
378
core/autoload/modules.el
Normal file
378
core/autoload/modules.el
Normal file
|
@ -0,0 +1,378 @@
|
|||
;;; core/autoload/modules.el -*- lexical-binding: t; -*-
|
||||
|
||||
(autoload 'print! "autoload/message" nil 'macro)
|
||||
|
||||
(defun doom--server-eval (body)
|
||||
(require 'server)
|
||||
(when (server-running-p)
|
||||
(server-eval-at server-name body)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//reload (&optional force-p)
|
||||
"Reloads your config. This is experimental!
|
||||
|
||||
If called from a noninteractive session, this will try to communicate with a
|
||||
live server (if one is found) to tell it to run this function.
|
||||
|
||||
If called from an interactive session, tries to reload autoloads files (if
|
||||
necessary), reinistalize doom (via `doom-initialize') and reloads your private
|
||||
init.el and config.el. Then runs `doom-reload-hook'."
|
||||
(interactive)
|
||||
(unless doom--inhibit-reload
|
||||
(cond ((and noninteractive (not (daemonp)))
|
||||
(require 'server)
|
||||
(if (not (server-running-p))
|
||||
(doom//reload-autoloads force-p)
|
||||
(print! "Reloading active Emacs session...")
|
||||
(print!
|
||||
(bold "%%s")
|
||||
(if (server-eval-at server-name '(doom//reload))
|
||||
(green "Done!")
|
||||
(red "There were issues!")))))
|
||||
((let ((load-prefer-newer t))
|
||||
(doom//reload-autoloads force-p)
|
||||
(doom-initialize t)
|
||||
(doom-initialize-modules t)
|
||||
(print! (green "%d packages reloaded" (length package-alist)))
|
||||
(run-hooks 'doom-reload-hook)
|
||||
t)))))
|
||||
|
||||
|
||||
;;
|
||||
;; Autoload file generation
|
||||
;;
|
||||
|
||||
(defvar doom-autoload-excluded-packages '(marshal gh)
|
||||
"Packages that have silly or destructive autoload files that try to load
|
||||
everyone in the universe and their dog, causing errors that make babies cry. No
|
||||
one wants that.")
|
||||
|
||||
(defun doom--byte-compile (file)
|
||||
(let ((short-name (file-name-nondirectory file)))
|
||||
(condition-case-unless-debug ex
|
||||
(when (byte-compile-file file)
|
||||
(load (byte-compile-dest-file file) nil t)
|
||||
(unless noninteractive
|
||||
(message "Finished compiling %s" short-name)))
|
||||
('error
|
||||
(doom-delete-autoloads-file file)
|
||||
(error "Error in %s: %s -- %s"
|
||||
short-name
|
||||
(car ex) (error-message-string ex))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-delete-autoloads-file (file)
|
||||
"Delete FILE (an autoloads file), and delete the accompanying *.elc file, if
|
||||
it exists."
|
||||
(or (stringp file)
|
||||
(signal 'wrong-type-argument (list 'stringp file)))
|
||||
(when (file-exists-p file)
|
||||
(delete-file file)
|
||||
(ignore-errors (delete-file (byte-compile-dest-file file)))
|
||||
(print! "Deleted old %s" (file-name-nondirectory file))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//reload-autoloads (&optional file force-p)
|
||||
"Reloads FILE (an autoload file), if it needs reloading.
|
||||
|
||||
FILE should be one of `doom-autoload-file' or `doom-package-autoload-file'. If
|
||||
it is nil, it will try to reload both. If FORCE-P (universal argument) do it
|
||||
even if it doesn't need reloading!"
|
||||
(interactive
|
||||
(list nil current-prefix-arg))
|
||||
(or (null file)
|
||||
(stringp file)
|
||||
(signal 'wrong-type-argument (list 'stringp file)))
|
||||
(cond ((equal file doom-autoload-file)
|
||||
(doom//reload-doom-autoloads force-p))
|
||||
((equal file doom-package-autoload-file)
|
||||
(doom//reload-package-autoloads force-p))
|
||||
((progn
|
||||
(doom//reload-doom-autoloads force-p)
|
||||
(doom//reload-package-autoloads force-p)))))
|
||||
|
||||
(defvar generated-autoload-load-name)
|
||||
;;;###autoload
|
||||
(defun doom//reload-doom-autoloads (&optional force-p)
|
||||
"Refreshes the autoloads.el file, specified by `doom-autoload-file', if
|
||||
necessary (or if FORCE-P is non-nil).
|
||||
|
||||
It scans and reads core/autoload/*.el, modules/*/*/autoload.el and
|
||||
modules/*/*/autoload/*.el, and generates `doom-autoload-file'. This file tells
|
||||
Emacs where to find lazy-loaded functions.
|
||||
|
||||
This should be run whenever your `doom!' block, or a module autoload file, is
|
||||
modified."
|
||||
(interactive)
|
||||
(let ((doom-modules (doom-module-table))
|
||||
(default-directory doom-emacs-dir)
|
||||
(targets
|
||||
(file-expand-wildcards
|
||||
(expand-file-name "autoload/*.el" doom-core-dir))))
|
||||
(dolist (path (doom-module-load-path))
|
||||
(let ((auto-dir (expand-file-name "autoload" path))
|
||||
(auto-file (expand-file-name "autoload.el" path)))
|
||||
(when (file-exists-p auto-file)
|
||||
(push auto-file targets))
|
||||
(when (file-directory-p auto-dir)
|
||||
(dolist (file (doom-files-in auto-dir :match "\\.el$" :full t))
|
||||
(push file targets)))))
|
||||
(if (and (not force-p)
|
||||
(file-exists-p doom-autoload-file)
|
||||
(not (cl-loop for file in targets
|
||||
if (file-newer-than-file-p file doom-autoload-file)
|
||||
return t)))
|
||||
(ignore (print! (green "Doom core autoloads is up-to-date"))
|
||||
(doom-initialize-autoloads doom-autoload-file))
|
||||
(doom-delete-autoloads-file doom-autoload-file)
|
||||
;; in case the buffer is open somewhere and modified
|
||||
(when-let* ((buf (find-buffer-visiting doom-autoload-file)))
|
||||
(with-current-buffer buf
|
||||
(set-buffer-modified-p nil))
|
||||
(kill-buffer buf))
|
||||
(message "Generating new autoloads.el")
|
||||
(dolist (file (nreverse targets))
|
||||
(let* ((file (file-truename file))
|
||||
(generated-autoload-load-name (file-name-sans-extension file))
|
||||
(noninteractive (not doom-debug-mode)))
|
||||
(print!
|
||||
(cond ((not (doom-file-cookie-p file))
|
||||
"⚠ Ignoring %s")
|
||||
((update-file-autoloads file nil doom-autoload-file)
|
||||
(yellow "✕ Nothing in %%s"))
|
||||
((green "✓ Scanned %%s")))
|
||||
(if (file-in-directory-p file default-directory)
|
||||
(file-relative-name file)
|
||||
(abbreviate-file-name file)))))
|
||||
(make-directory (file-name-directory doom-autoload-file) t)
|
||||
(let ((buf (find-file-noselect doom-autoload-file t))
|
||||
case-fold-search)
|
||||
(unwind-protect
|
||||
(with-current-buffer buf
|
||||
(goto-char (point-min))
|
||||
(insert ";;; -*- lexical-binding:t -*-\n"
|
||||
";; This file is autogenerated by `doom//reload-doom-autoloads', DO NOT EDIT !!\n\n")
|
||||
(save-excursion
|
||||
;; Replace autoload paths (only for module autoloads) with
|
||||
;; absolute paths for faster resolution during load and
|
||||
;; simpler `load-path'
|
||||
(let ((load-path (append doom-psuedo-module-dirs
|
||||
doom-modules-dirs
|
||||
load-path))
|
||||
cache)
|
||||
(save-excursion
|
||||
(while (re-search-forward "^\\s-*(autoload\\s-+'[^ ]+\\s-+\"\\([^\"]*\\)\"" nil t)
|
||||
(let ((path (match-string 1)))
|
||||
(replace-match
|
||||
(or (cdr (assoc path cache))
|
||||
(when-let* ((libpath (locate-library path))
|
||||
(libpath (file-name-sans-extension libpath)))
|
||||
(push (cons path (abbreviate-file-name libpath)) cache)
|
||||
libpath)
|
||||
path)
|
||||
t t nil 1)))
|
||||
(print! (green "✓ Autoload paths expanded")))))
|
||||
;; Remove byte-compile inhibiting file variables so we can
|
||||
;; byte-compile the file.
|
||||
(when (re-search-forward "^;; no-byte-compile: t\n" nil t)
|
||||
(replace-match "" t t))
|
||||
;; Byte compile it to give the file a chance to reveal errors.
|
||||
(save-buffer)
|
||||
(doom--byte-compile doom-autoload-file)
|
||||
(when (and noninteractive (not (daemonp)))
|
||||
(doom--server-eval `(load-file ,doom-autoload-file)))
|
||||
t)
|
||||
(kill-buffer buf))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//reload-package-autoloads (&optional force-p)
|
||||
"Compiles `doom-package-autoload-file' from the autoloads files of all
|
||||
installed packages. It also caches `load-path', `Info-directory-list',
|
||||
`doom-disabled-packages', `package-activated-list' and `auto-mode-alist'.
|
||||
|
||||
Will do nothing if none of your installed packages have been modified. If
|
||||
FORCE-P (universal argument) is non-nil, regenerate it anyway.
|
||||
|
||||
This should be run whenever your `doom!' block or update your packages."
|
||||
(interactive)
|
||||
(if (and (not force-p)
|
||||
(file-exists-p doom-package-autoload-file)
|
||||
(not (cl-loop initially do (doom-ensure-packages-initialized t)
|
||||
for (_pkg desc) in package-alist
|
||||
for autoload-file = (concat (package--autoloads-file-name desc) ".el")
|
||||
if (file-newer-than-file-p autoload-file doom-package-autoload-file)
|
||||
return t)))
|
||||
(ignore (print! (green "Doom package autoloads is up-to-date"))
|
||||
(doom-initialize-autoloads doom-package-autoload-file))
|
||||
(doom-delete-autoloads-file doom-package-autoload-file)
|
||||
(with-temp-file doom-package-autoload-file
|
||||
(insert ";;; -*- lexical-binding:t -*-\n"
|
||||
";; This file is autogenerated by `doom//reload-package-autoloads', DO NOT EDIT !!\n\n")
|
||||
(save-excursion
|
||||
;; Cache the important and expensive-to-initialize state here.
|
||||
(doom-initialize-packages 'internal)
|
||||
(prin1 `(setq load-path ',load-path
|
||||
auto-mode-alist ',auto-mode-alist
|
||||
Info-directory-list ',Info-directory-list
|
||||
doom-disabled-packages ',doom-disabled-packages
|
||||
package-activated-list ',package-activated-list)
|
||||
(current-buffer))
|
||||
(print! (green "✓ Cached package state"))
|
||||
|
||||
;; insert package autoloads
|
||||
(dolist (spec package-alist)
|
||||
(cl-destructuring-bind (pkg desc) spec
|
||||
(unless (memq pkg doom-autoload-excluded-packages)
|
||||
(let ((file
|
||||
(abbreviate-file-name
|
||||
(concat (package--autoloads-file-name desc) ".el"))))
|
||||
(when (file-exists-p file)
|
||||
(insert "(let ((load-file-name " (prin1-to-string file) "))\n")
|
||||
(insert-file-contents file)
|
||||
(while (re-search-forward "^\\(?:;;\\(.*\n\\)\\|\n\\)" nil t)
|
||||
(unless (nth 8 (syntax-ppss))
|
||||
(replace-match "" t t)))
|
||||
(unless (bolp) (insert "\n"))
|
||||
(insert ")\n")))))))
|
||||
(print! (green "✓ Package autoloads included"))
|
||||
;; Remove `load-path' and `auto-mode-alist' modifications (most of them,
|
||||
;; at least); they are cached later, so all those membership checks are
|
||||
;; unnecessary overhead.
|
||||
(while (re-search-forward "^\\s-*\\((\\(?:add-to-list\\|when (boundp \\)\\s-+'\\(?:load-path\\|auto-mode-alist\\)\\)" nil t)
|
||||
(goto-char (match-beginning 1))
|
||||
(kill-sexp))
|
||||
(print! (green "✓ Removed load-path/auto-mode-alist entries")))
|
||||
(doom--byte-compile doom-package-autoload-file)
|
||||
(when (and noninteractive (not (daemonp)))
|
||||
(doom--server-eval `(load-file ,doom-package-autoload-file)))
|
||||
t))
|
||||
|
||||
|
||||
;;
|
||||
;; Byte compilation
|
||||
;;
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//byte-compile (&optional modules recompile-p)
|
||||
"Byte compiles your emacs configuration.
|
||||
|
||||
init.el is always byte-compiled by this.
|
||||
|
||||
If MODULES is specified (a list of module strings, e.g. \"lang/php\"), those are
|
||||
byte-compiled. Otherwise, all enabled modules are byte-compiled, including Doom
|
||||
core. It always ignores unit tests and files with `no-byte-compile' enabled.
|
||||
|
||||
Doom was designed to benefit from byte-compilation, but the process may take a
|
||||
while. Also, while your config files are byte-compiled, changes to them will not
|
||||
take effect! Use `doom//clean-byte-compiled-files' or `make clean' to remove
|
||||
these files.
|
||||
|
||||
If RECOMPILE-P is non-nil, only recompile out-of-date files."
|
||||
(interactive
|
||||
(list nil current-prefix-arg))
|
||||
(let ((default-directory doom-emacs-dir))
|
||||
(unless recompile-p
|
||||
(doom//clean-byte-compiled-files))
|
||||
(let ((total-ok 0)
|
||||
(total-fail 0)
|
||||
(total-noop 0)
|
||||
compile-plugins-p
|
||||
targets)
|
||||
(dolist (module (delete-dups modules) (nreverse targets))
|
||||
(pcase module
|
||||
(":core" (push doom-core-dir targets))
|
||||
(":private" (push doom-private-dir targets))
|
||||
(":plugins"
|
||||
(byte-recompile-directory package-user-dir 0 t)
|
||||
(setq compile-plugins-p t))
|
||||
((pred file-directory-p)
|
||||
(push module targets))
|
||||
((pred (string-match "^\\([^/]+\\)/\\([^/]+\\)$"))
|
||||
(push (doom-module-locate-path
|
||||
(intern (format ":%s" (match-string 1 module)))
|
||||
(intern (match-string 2 module)))
|
||||
targets))))
|
||||
(unless (equal modules (list ":plugins"))
|
||||
(let ((inhibit-message t)
|
||||
noninteractive)
|
||||
;; But first we must be sure that Doom and your private config have been
|
||||
;; fully loaded. Which usually aren't so in an noninteractive session.
|
||||
(doom//reload-autoloads)
|
||||
(doom-initialize t)
|
||||
(unless (equal modules (list ":core"))
|
||||
(doom-initialize-modules t))))
|
||||
;; If no targets were supplied, then we use your module list.
|
||||
(unless targets
|
||||
(setq targets (append (list doom-core-dir)
|
||||
(doom-module-load-path))))
|
||||
;; Assemble el files we want to compile; taking into account that MODULES
|
||||
;; may be a list of MODULE/SUBMODULE strings from the command line.
|
||||
(let ((target-files (doom-files-in targets :depth 2 :match "\\.el$")))
|
||||
(if (not target-files)
|
||||
(unless compile-plugins-p
|
||||
(message "No targets to %scompile" (if recompile-p "re" "")))
|
||||
(condition-case ex
|
||||
(let ((use-package-expand-minimally t))
|
||||
;; Always compile private init file
|
||||
(cl-pushnew (expand-file-name "init.el" doom-private-dir)
|
||||
target-files :test #'equal)
|
||||
(cl-pushnew (expand-file-name "init.el" doom-emacs-dir)
|
||||
target-files :test #'equal)
|
||||
(dolist (target (cl-delete-duplicates (mapcar #'file-truename target-files) :test #'equal))
|
||||
(if (or (not recompile-p)
|
||||
(let ((elc-file (byte-compile-dest-file target)))
|
||||
(and (file-exists-p elc-file)
|
||||
(file-newer-than-file-p target elc-file))))
|
||||
(let ((result (if (or (string-match-p "/\\(?:packages\\|doctor\\)\\.el$" target)
|
||||
(not (doom-file-cookie-p target)))
|
||||
'no-byte-compile
|
||||
(byte-compile-file target)))
|
||||
(short-name (if (file-in-directory-p target doom-emacs-dir)
|
||||
(file-relative-name target doom-emacs-dir)
|
||||
(abbreviate-file-name target))))
|
||||
(cl-incf
|
||||
(cond ((eq result 'no-byte-compile)
|
||||
(print! (dark (white "⚠ Ignored %s" short-name)))
|
||||
total-noop)
|
||||
((null result)
|
||||
(print! (red "✕ Failed to compile %s" short-name))
|
||||
total-fail)
|
||||
(t
|
||||
(print! (green "✓ Compiled %s" short-name))
|
||||
(quiet! (load target t t))
|
||||
total-ok))))
|
||||
(cl-incf total-noop)))
|
||||
(print!
|
||||
(bold
|
||||
(color (if (= total-fail 0) 'green 'red)
|
||||
"%s %d/%d file(s) (%d ignored)"
|
||||
(if recompile-p "Recompiled" "Compiled")
|
||||
total-ok (- (length target-files) total-noop)
|
||||
total-noop))))
|
||||
(error
|
||||
(print! (red "\n%%s\n\n%%s\n\n%%s")
|
||||
"There were breaking errors."
|
||||
(error-message-string ex)
|
||||
"Reverting changes...")
|
||||
(quiet! (doom//clean-byte-compiled-files))
|
||||
(print! (yellow "Finished (nothing was byte-compiled)")))))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//clean-byte-compiled-files ()
|
||||
"Delete all the compiled elc files in your Emacs configuration and private
|
||||
module. This does not include your byte-compiled, third party packages.'"
|
||||
(interactive)
|
||||
(cl-loop with default-directory = doom-emacs-dir
|
||||
for path in (append (doom-files-in doom-emacs-dir :match "\\.elc$" :depth 1)
|
||||
(doom-files-in doom-psuedo-module-dirs :match "\\.elc$" :depth 1)
|
||||
(doom-files-in doom-core-dir :match "\\.elc$")
|
||||
(doom-files-in doom-modules-dirs :match "\\.elc$" :depth 4))
|
||||
for truepath = (file-truename path)
|
||||
if (file-exists-p path)
|
||||
do (delete-file path)
|
||||
and do
|
||||
(print! (green "✓ Deleted %%s")
|
||||
(if (file-in-directory-p truepath default-directory)
|
||||
(file-relative-name truepath)
|
||||
(abbreviate-file-name truepath)))
|
||||
finally do (print! (bold (green "Everything is clean")))))
|
|
@ -1,15 +1,8 @@
|
|||
;;; core/autoload/packages.el -*- lexical-binding: t; -*-
|
||||
|
||||
(load! cache)
|
||||
(require 'use-package)
|
||||
(require 'quelpa)
|
||||
(require 'package)
|
||||
(require 'async)
|
||||
|
||||
;;; Private functions
|
||||
(defsubst doom--sort-alpha (it other)
|
||||
(string-lessp (symbol-name (car it))
|
||||
(symbol-name (car other))))
|
||||
|
||||
(defun doom--packages-choose (prompt)
|
||||
(let ((table (cl-loop for pkg in package-alist
|
||||
|
@ -26,15 +19,15 @@
|
|||
(condition-case ex2
|
||||
(progn ,@body)
|
||||
('file-error
|
||||
(message! (bold (red " FILE ERROR: %s" (error-message-string ex2))))
|
||||
(message! " Trying again...")
|
||||
(print! (bold (red " FILE ERROR: %s" (error-message-string ex2))))
|
||||
(print! " Trying again...")
|
||||
(quiet! (doom-refresh-packages-maybe t))
|
||||
,@body))
|
||||
('user-error
|
||||
(message! (bold (red " ERROR: %s" ex))))
|
||||
(print! (bold (red " ERROR: %s" ex))))
|
||||
('error
|
||||
(doom--refresh-pkg-cache)
|
||||
(message! (bold (red " FATAL ERROR: %s" ex))))))
|
||||
(print! (bold (red " FATAL ERROR: %s" ex))))))
|
||||
|
||||
(defun doom--refresh-pkg-cache ()
|
||||
"Clear the cache for `doom-refresh-packages-maybe'."
|
||||
|
@ -57,7 +50,7 @@
|
|||
(progn
|
||||
(message "Refreshing package archives")
|
||||
(package-refresh-contents)
|
||||
(doom-cache-set 'last-pkg-refresh t 900))
|
||||
(doom-cache-set 'last-pkg-refresh t 1200))
|
||||
('error
|
||||
(doom--refresh-pkg-cache)
|
||||
(message "Failed to refresh packages: (%s) %s"
|
||||
|
@ -147,7 +140,7 @@ Warning: this function is expensive; it re-evaluates all of doom's config files.
|
|||
Be careful not to use it in a loop.
|
||||
|
||||
If INSTALLED-ONLY-P, only return packages that are installed."
|
||||
(doom-initialize-packages (not noninteractive))
|
||||
(doom-initialize-packages t)
|
||||
(cl-loop with packages = (append doom-core-packages (mapcar #'car doom-packages))
|
||||
for sym in (cl-delete-duplicates packages)
|
||||
if (and (or (not installed-only-p)
|
||||
|
@ -180,7 +173,8 @@ containing (PACKAGE-SYMBOL OLD-VERSION-LIST NEW-VERSION-LIST).
|
|||
If INCLUDE-FROZEN-P is non-nil, check frozen packages as well.
|
||||
|
||||
Used by `doom//packages-update'."
|
||||
(doom-initialize-packages (not noninteractive))
|
||||
(doom-initialize-packages t)
|
||||
(doom-refresh-packages-maybe doom-debug-mode)
|
||||
(require 'async)
|
||||
(let (quelpa-pkgs elpa-pkgs)
|
||||
;; Separate quelpa from elpa packages
|
||||
|
@ -201,9 +195,12 @@ Used by `doom//packages-update'."
|
|||
(message "New thread for: %s" pkg))
|
||||
(push (async-start
|
||||
`(lambda ()
|
||||
(let ((doom-init-p 'internal)
|
||||
(let ((doom-init-p t)
|
||||
(noninteractive t)
|
||||
(load-path ',load-path)
|
||||
(package-alist ',package-alist)
|
||||
(package-archive-contents ',package-archive-contents)
|
||||
(package-selected-packages ',package-selected-packages)
|
||||
(doom-packages ',doom-packages)
|
||||
(doom-modules ',doom-modules)
|
||||
(quelpa-cache ',quelpa-cache)
|
||||
|
@ -211,6 +208,8 @@ Used by `doom//packages-update'."
|
|||
doom-private-dir)
|
||||
(load ,(expand-file-name "core.el" doom-core-dir))
|
||||
(load ,(expand-file-name "autoload/packages.el" doom-core-dir))
|
||||
(require 'package)
|
||||
(require 'quelpa)
|
||||
(doom-package-outdated-p ',pkg))))
|
||||
futures))
|
||||
(delq nil
|
||||
|
@ -223,7 +222,7 @@ Used by `doom//packages-update'."
|
|||
depended on.
|
||||
|
||||
Used by `doom//packages-autoremove'."
|
||||
(doom-initialize-packages (not noninteractive))
|
||||
(doom-initialize-packages t)
|
||||
(let ((package-selected-packages
|
||||
(append (mapcar #'car doom-packages) doom-core-packages)))
|
||||
(append (package--removable-packages)
|
||||
|
@ -243,7 +242,6 @@ If INCLUDE-IGNORED-P is non-nil, includes missing packages that are ignored,
|
|||
i.e. they have an :ignore property.
|
||||
|
||||
Used by `doom//packages-install'."
|
||||
(doom-initialize-packages (not noninteractive))
|
||||
(cl-loop for desc in (doom-get-packages)
|
||||
for (name . plist) = desc
|
||||
if (and (or include-ignored-p
|
||||
|
@ -260,6 +258,7 @@ Used by `doom//packages-install'."
|
|||
;; Main functions
|
||||
;;
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-install-package (name &optional plist)
|
||||
"Installs package NAME with optional quelpa RECIPE (see `quelpa-recipe' for an
|
||||
example; the package name can be omitted)."
|
||||
|
@ -283,6 +282,7 @@ example; the package name can be omitted)."
|
|||
(map-put doom-packages name plist)
|
||||
name)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-update-package (name &optional force-p)
|
||||
"Updates package NAME (a symbol) if it is out of date, using quelpa or
|
||||
package.el as appropriate."
|
||||
|
@ -310,6 +310,7 @@ package.el as appropriate."
|
|||
(delete-directory old-dir t)))
|
||||
t))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-delete-package (name &optional force-p)
|
||||
"Uninstalls package NAME if it exists, and clears it from `quelpa-cache'."
|
||||
(unless (package-installed-p name)
|
||||
|
@ -328,162 +329,6 @@ package.el as appropriate."
|
|||
t)))
|
||||
|
||||
|
||||
;;
|
||||
;; Batch/interactive commands
|
||||
;;
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//packages-install ()
|
||||
"Interactive command for installing missing packages."
|
||||
(interactive)
|
||||
(if (not noninteractive)
|
||||
(doom-packages--async-run 'doom//packages-install)
|
||||
(message! "Looking for packages to install...")
|
||||
(let ((packages (reverse (doom-get-missing-packages))))
|
||||
(cond ((not packages)
|
||||
(message! (green "No packages to install!"))
|
||||
nil)
|
||||
|
||||
((not (or (getenv "YES")
|
||||
(y-or-n-p
|
||||
(format "%s packages will be installed:\n\n%s\n\nProceed?"
|
||||
(length packages)
|
||||
(mapconcat
|
||||
(lambda (pkg)
|
||||
(format "+ %s (%s)"
|
||||
(car pkg)
|
||||
(cond ((doom-package-different-recipe-p (car pkg))
|
||||
"new recipe")
|
||||
((doom-package-different-backend-p (car pkg))
|
||||
(if (plist-get (cdr pkg) :recipe)
|
||||
"ELPA -> QUELPA"
|
||||
"QUELPA -> ELPA"))
|
||||
((plist-get (cdr pkg) :recipe)
|
||||
"QUELPA")
|
||||
(t
|
||||
"ELPA"))))
|
||||
(sort (cl-copy-list packages) #'doom--sort-alpha)
|
||||
"\n")))))
|
||||
(message! (yellow "Aborted!"))
|
||||
nil)
|
||||
|
||||
(t
|
||||
(doom-refresh-packages-maybe doom-debug-mode)
|
||||
(dolist (pkg packages)
|
||||
(message! "Installing %s" (car pkg))
|
||||
(doom--condition-case!
|
||||
(message! "%s%s"
|
||||
(if (and (package-installed-p (car pkg))
|
||||
(not (doom-package-different-backend-p (car pkg)))
|
||||
(not (doom-package-different-recipe-p (car pkg))))
|
||||
(dark (white "⚠ ALREADY INSTALLED"))
|
||||
(condition-case e
|
||||
(if (doom-install-package (car pkg) (cdr pkg))
|
||||
(green "✓ DONE")
|
||||
(red "✕ FAILED"))
|
||||
(error
|
||||
(red "✕ ERROR (%s)" e))))
|
||||
(if (plist-member (cdr pkg) :pin)
|
||||
(format " [pinned: %s]" (plist-get (cdr pkg) :pin))
|
||||
""))))
|
||||
|
||||
(message! (bold (green "Finished!")))
|
||||
(doom//reload-load-path)
|
||||
t)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//packages-update ()
|
||||
"Interactive command for updating packages."
|
||||
(interactive)
|
||||
(if (not noninteractive)
|
||||
(doom-packages--async-run 'doom//packages-update)
|
||||
(message! "Looking for outdated packages...")
|
||||
(doom-refresh-packages-maybe doom-debug-mode)
|
||||
(let ((packages (sort (doom-get-outdated-packages) #'doom--sort-alpha)))
|
||||
(cond ((not packages)
|
||||
(message! (green "Everything is up-to-date"))
|
||||
nil)
|
||||
|
||||
((not (or (getenv "YES")
|
||||
(y-or-n-p
|
||||
(format "%s packages will be updated:\n\n%s\n\nProceed?"
|
||||
(length packages)
|
||||
(let ((max-len
|
||||
(or (car (sort (mapcar (lambda (it) (length (symbol-name (car it)))) packages)
|
||||
(lambda (it other) (> it other))))
|
||||
10)))
|
||||
(mapconcat
|
||||
(lambda (pkg)
|
||||
(format (format "+ %%-%ds %%-%ds -> %%s" (+ max-len 2) 14)
|
||||
(symbol-name (car pkg))
|
||||
(package-version-join (cadr pkg))
|
||||
(package-version-join (cl-caddr pkg))))
|
||||
packages
|
||||
"\n"))))))
|
||||
(message! (yellow "Aborted!"))
|
||||
nil)
|
||||
|
||||
(t
|
||||
(dolist (pkg packages)
|
||||
(message! "Updating %s" (car pkg))
|
||||
(doom--condition-case!
|
||||
(message!
|
||||
(let ((result (doom-update-package (car pkg) t)))
|
||||
(color (if result 'green 'red)
|
||||
(if result "✓ DONE" "✕ FAILED"))))))
|
||||
|
||||
(message! (bold (green "Finished!")))
|
||||
(doom//reload-load-path)
|
||||
t)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//packages-autoremove ()
|
||||
"Interactive command for auto-removing orphaned packages."
|
||||
(interactive)
|
||||
(if (not noninteractive)
|
||||
(doom-packages--async-run 'doom//packages-autoremove)
|
||||
(message! "Looking for orphaned packages...")
|
||||
(let ((packages (doom-get-orphaned-packages)))
|
||||
(cond ((not packages)
|
||||
(message! (green "No unused packages to remove"))
|
||||
nil)
|
||||
|
||||
((not
|
||||
(or (getenv "YES")
|
||||
(y-or-n-p
|
||||
(format
|
||||
"%s packages will be deleted:\n\n%s\n\nProceed?"
|
||||
(length packages)
|
||||
(mapconcat
|
||||
(lambda (sym)
|
||||
(format "+ %s (%s)" sym
|
||||
(let ((backend (doom-package-backend sym)))
|
||||
(if (doom-package-different-backend-p sym)
|
||||
(pcase backend
|
||||
(`quelpa "QUELPA->ELPA")
|
||||
(`elpa "ELPA->QUELPA")
|
||||
(_ "removed"))
|
||||
(upcase (symbol-name backend))))))
|
||||
(sort (cl-copy-list packages) #'string-lessp)
|
||||
"\n")))))
|
||||
(message! (yellow "Aborted!"))
|
||||
nil)
|
||||
|
||||
(t
|
||||
(dolist (pkg packages)
|
||||
(doom--condition-case!
|
||||
(message!
|
||||
(let ((result (doom-delete-package pkg t)))
|
||||
(color (if result 'green 'red)
|
||||
"%s %s"
|
||||
(if result "✓ Removed" "✕ Failed to remove")
|
||||
pkg)))))
|
||||
|
||||
(message! (bold (green "Finished!")))
|
||||
(doom//reload-load-path)
|
||||
t)))))
|
||||
|
||||
|
||||
;;
|
||||
;; Interactive commands
|
||||
;;
|
||||
|
@ -533,3 +378,148 @@ calls."
|
|||
(when (file-exists-p path)
|
||||
(delete-directory path t))))))
|
||||
|
||||
|
||||
;;
|
||||
;; Package Management
|
||||
;;
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//packages-install (&optional auto-accept-p)
|
||||
"Interactive command for installing missing packages."
|
||||
(interactive "P")
|
||||
(print! "Looking for packages to install...")
|
||||
(let ((packages (reverse (doom-get-missing-packages))))
|
||||
(cond ((not packages)
|
||||
(print! (green "No packages to install!"))
|
||||
nil)
|
||||
|
||||
((not (or auto-accept-p
|
||||
(y-or-n-p
|
||||
(format "%s packages will be installed:\n\n%s\n\nProceed?"
|
||||
(length packages)
|
||||
(mapconcat
|
||||
(lambda (pkg)
|
||||
(format "+ %s (%s)"
|
||||
(car pkg)
|
||||
(cond ((doom-package-different-recipe-p (car pkg))
|
||||
"new recipe")
|
||||
((doom-package-different-backend-p (car pkg))
|
||||
(if (plist-get (cdr pkg) :recipe)
|
||||
"ELPA -> QUELPA"
|
||||
"QUELPA -> ELPA"))
|
||||
((plist-get (cdr pkg) :recipe)
|
||||
"QUELPA")
|
||||
(t
|
||||
"ELPA"))))
|
||||
(cl-sort (cl-copy-list packages) #'string-lessp
|
||||
:key #'car)
|
||||
"\n")))))
|
||||
(error "Aborted!"))
|
||||
|
||||
((let (success)
|
||||
(doom-refresh-packages-maybe doom-debug-mode)
|
||||
(dolist (pkg packages)
|
||||
(print! "Installing %s" (car pkg))
|
||||
(doom--condition-case!
|
||||
(print! "%s%s"
|
||||
(cond ((and (package-installed-p (car pkg))
|
||||
(not (doom-package-different-backend-p (car pkg)))
|
||||
(not (doom-package-different-recipe-p (car pkg))))
|
||||
(dark (white "⚠ ALREADY INSTALLED")))
|
||||
((doom-install-package (car pkg) (cdr pkg))
|
||||
(setq success t)
|
||||
(green "✓ DONE"))
|
||||
((red "✕ FAILED")))
|
||||
(if (plist-member (cdr pkg) :pin)
|
||||
(format " [pinned: %s]" (plist-get (cdr pkg) :pin))
|
||||
""))))
|
||||
(print! (bold (green "Finished!")))
|
||||
(if success (doom-delete-autoloads-file doom-package-autoload-file))
|
||||
success)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//packages-update (&optional auto-accept-p)
|
||||
"Interactive command for updating packages."
|
||||
(interactive "P")
|
||||
(print! "Looking for outdated packages...")
|
||||
(let ((packages (cl-sort (cl-copy-list (doom-get-outdated-packages)) #'string-lessp
|
||||
:key #'car)))
|
||||
(cond ((not packages)
|
||||
(print! (green "Everything is up-to-date"))
|
||||
nil)
|
||||
|
||||
((not (or auto-accept-p
|
||||
(y-or-n-p
|
||||
(format "%s packages will be updated:\n\n%s\n\nProceed?"
|
||||
(length packages)
|
||||
(let ((max-len
|
||||
(or (car (sort (mapcar (lambda (it) (length (symbol-name (car it)))) packages)
|
||||
#'>))
|
||||
10)))
|
||||
(mapconcat
|
||||
(lambda (pkg)
|
||||
(format (format "+ %%-%ds %%-%ds -> %%s" (+ max-len 2) 14)
|
||||
(symbol-name (car pkg))
|
||||
(package-version-join (cadr pkg))
|
||||
(package-version-join (cl-caddr pkg))))
|
||||
packages
|
||||
"\n"))))))
|
||||
(error "Aborted!"))
|
||||
|
||||
((let (success)
|
||||
(dolist (pkg packages)
|
||||
(print! "Updating %s" (car pkg))
|
||||
(doom--condition-case!
|
||||
(print!
|
||||
(let ((result (doom-update-package (car pkg) t)))
|
||||
(when result (setq success t))
|
||||
(color (if result 'green 'red)
|
||||
(if result "✓ DONE" "✕ FAILED"))))))
|
||||
(print! (bold (green "Finished!")))
|
||||
(if success (doom-delete-autoloads-file doom-package-autoload-file))
|
||||
success)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//packages-autoremove (&optional auto-accept-p)
|
||||
"Interactive command for auto-removing orphaned packages."
|
||||
(interactive "P")
|
||||
(print! "Looking for orphaned packages...")
|
||||
(let ((packages (doom-get-orphaned-packages)))
|
||||
(cond ((not packages)
|
||||
(print! (green "No unused packages to remove"))
|
||||
nil)
|
||||
|
||||
((not
|
||||
(or auto-accept-p
|
||||
(y-or-n-p
|
||||
(format
|
||||
"%s packages will be deleted:\n\n%s\n\nProceed?"
|
||||
(length packages)
|
||||
(mapconcat
|
||||
(lambda (sym)
|
||||
(format "+ %s (%s)" sym
|
||||
(let ((backend (doom-package-backend sym)))
|
||||
(if (doom-package-different-backend-p sym)
|
||||
(pcase backend
|
||||
(`quelpa "QUELPA->ELPA")
|
||||
(`elpa "ELPA->QUELPA")
|
||||
(_ "removed"))
|
||||
(upcase (symbol-name backend))))))
|
||||
(sort (cl-copy-list packages) #'string-lessp)
|
||||
"\n")))))
|
||||
(error "Aborted!"))
|
||||
|
||||
((let (success)
|
||||
(dolist (pkg packages)
|
||||
(doom--condition-case!
|
||||
(print!
|
||||
(let ((result (doom-delete-package pkg t)))
|
||||
(when result (setq success t))
|
||||
(color (if result 'green 'red)
|
||||
"%s %s"
|
||||
(if result "✓ Removed" "✕ Failed to remove")
|
||||
pkg)))))
|
||||
|
||||
(print! (bold (green "Finished!")))
|
||||
(if success (doom-delete-autoloads-file doom-package-autoload-file))
|
||||
success)))))
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
;;; core/autoload/test.el -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//run-tests (&optional modules)
|
||||
"Run all loaded tests, specified by MODULES (a list of module cons cells) or
|
||||
command line args following a double dash (each arg should be in the
|
||||
|
@ -8,21 +7,21 @@ command line args following a double dash (each arg should be in the
|
|||
|
||||
If neither is available, run all tests in all enabled modules."
|
||||
(interactive)
|
||||
(let ((doom-modules (make-hash-table :test #'equal)))
|
||||
;; ensure DOOM is initialized
|
||||
(doom//reload-autoloads)
|
||||
(let (noninteractive)
|
||||
;; Core libraries aren't fully loaded in a noninteractive session, so we
|
||||
;; reload it with `noninteractive' set to nil to force them to.
|
||||
(doom-initialize t)
|
||||
(run-hooks 'doom-init-hook 'pre-command-hook 'doom-after-switch-buffer-hook))
|
||||
(doom-initialize-modules t))
|
||||
(condition-case-unless-debug ex
|
||||
(let ((target-paths
|
||||
(let* ((doom-modules (doom-module-table))
|
||||
(target-paths
|
||||
;; Convert targets (either from MODULES or `argv') into a list of
|
||||
;; string paths, pointing to the root directory of modules
|
||||
(cond ((string= (car argv) "--") ; command line
|
||||
(cond ((stringp (car modules)) ; command line
|
||||
(save-match-data
|
||||
(cl-loop for arg in (cdr argv)
|
||||
if (string= arg "core") collect doom-core-dir
|
||||
(cl-loop for arg in modules
|
||||
if (string= arg ":core") collect doom-core-dir
|
||||
else if (string-match-p "/" arg)
|
||||
nconc (cl-loop for dir in doom-modules-dirs
|
||||
collect (expand-file-name arg dir))
|
||||
|
@ -38,26 +37,26 @@ If neither is available, run all tests in all enabled modules."
|
|||
|
||||
(modules ; cons-cells given to MODULES
|
||||
(cl-loop for (module . submodule) in modules
|
||||
if (doom-module-find-path module submodule)
|
||||
if (doom-module-locate-path module submodule)
|
||||
collect it))
|
||||
|
||||
((let (noninteractive)
|
||||
(load (expand-file-name "init.test.el" user-emacs-directory) nil t)
|
||||
(append (list doom-core-dir) (doom-module-load-path)))))))
|
||||
((append (list doom-core-dir)
|
||||
(doom-module-load-path))))))
|
||||
;; Load all the unit test files...
|
||||
(dolist (path target-paths)
|
||||
(let ((test-path (expand-file-name "test/" path)))
|
||||
(when (file-directory-p test-path)
|
||||
(dolist (test-file (reverse (doom-packages--files test-path "\\.el$")))
|
||||
(dolist (test-file (reverse (doom-files-in test-path :match "\\.el$" :full t)))
|
||||
(load test-file nil :noerror)))))
|
||||
;; ... then run them
|
||||
(switch-to-buffer (get-buffer-create "*blank*"))
|
||||
(if noninteractive
|
||||
(ert-run-tests-batch-and-exit)
|
||||
(call-interactively #'ert-run-tests-interactively)))
|
||||
('error
|
||||
(lwarn 'doom-test :error
|
||||
"%s -> %s"
|
||||
(car ex) (error-message-string ex))))))
|
||||
(car ex) (error-message-string ex)))))
|
||||
|
||||
|
||||
;; --- Test helpers -----------------------
|
||||
|
|
|
@ -1,212 +0,0 @@
|
|||
;;; core/autoload/util.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/what-face (&optional pos)
|
||||
"Shows all faces and overlay faces at point.
|
||||
|
||||
Interactively prints the list to the echo area. Noninteractively, returns a list
|
||||
whose car is the list of faces and cadr is the list of overlay faces."
|
||||
(interactive)
|
||||
(let* ((pos (or pos (point)))
|
||||
(faces (let ((face (get-text-property pos 'face)))
|
||||
(if (keywordp (car-safe face))
|
||||
(list face)
|
||||
(cl-loop for f in (doom-enlist face) collect f))))
|
||||
(overlays (cl-loop for ov in (overlays-at pos (1+ pos))
|
||||
nconc (doom-enlist (overlay-get ov 'face)))))
|
||||
(cond ((called-interactively-p 'any)
|
||||
(message "%s %s\n%s %s"
|
||||
(propertize "Faces:" 'face 'font-lock-comment-face)
|
||||
(if faces
|
||||
(cl-loop for face in faces
|
||||
if (listp face)
|
||||
concat (format "'%s " face)
|
||||
else
|
||||
concat (concat (propertize (symbol-name face) 'face face) " "))
|
||||
"n/a ")
|
||||
(propertize "Overlays:" 'face 'font-lock-comment-face)
|
||||
(if overlays
|
||||
(cl-loop for ov in overlays
|
||||
concat (concat (propertize (symbol-name ov) 'face ov) " "))
|
||||
"n/a")))
|
||||
(t
|
||||
(and (or faces overlays)
|
||||
(list faces overlays))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-active-minor-modes ()
|
||||
"Get a list of active minor-mode symbols."
|
||||
(cl-loop for mode in minor-mode-list
|
||||
if (and (boundp mode) (symbol-value mode))
|
||||
collect mode))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/what-minor-mode (mode)
|
||||
"Get information on an active minor mode. Use `describe-minor-mode' for a
|
||||
selection of all minor-modes, active or not."
|
||||
(interactive
|
||||
(list (completing-read "Minor mode: "
|
||||
(doom-active-minor-modes))))
|
||||
(describe-minor-mode-from-symbol
|
||||
(cl-typecase mode
|
||||
(string (intern mode))
|
||||
(symbol mode)
|
||||
(t (error "Expected a symbol/string, got a %s" (type-of mode))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/am-i-secure ()
|
||||
"Test to see if your root certificates are securely configured in emacs."
|
||||
(declare (interactive-only t))
|
||||
(interactive)
|
||||
(unless (string-match-p "\\_<GNUTLS\\_>" system-configuration-features)
|
||||
(warn "gnutls support isn't built into Emacs, there may be problems"))
|
||||
(if-let* ((bad-hosts
|
||||
(cl-loop for bad
|
||||
in '("https://wrong.host.badssl.com/"
|
||||
"https://self-signed.badssl.com/")
|
||||
if (condition-case _e
|
||||
(url-retrieve-synchronously bad)
|
||||
(error nil))
|
||||
collect bad)))
|
||||
(error (format "tls seems to be misconfigured (it got %s)."
|
||||
bad-hosts))
|
||||
(url-retrieve "https://badssl.com"
|
||||
(lambda (status)
|
||||
(if (or (not status) (plist-member status :error))
|
||||
(warn "Something went wrong.\n\n%s" (pp-to-string status))
|
||||
(message "Your trust roots are set up properly.\n\n%s" (pp-to-string status))
|
||||
t)))))
|
||||
|
||||
(defvar doom--profiler nil)
|
||||
;;;###autoload
|
||||
(defun doom/toggle-profiler ()
|
||||
"Toggle the Emacs profiler. Starts it if isn't running. Stops it and pops up
|
||||
the profiling report otherwise."
|
||||
(interactive)
|
||||
(if (not doom--profiler)
|
||||
(profiler-start 'cpu+mem)
|
||||
(profiler-report)
|
||||
(profiler-stop))
|
||||
(setq doom--profiler (not doom--profiler)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/profile-emacs ()
|
||||
"Profile the startup time of Emacs in the background.
|
||||
If INIT-FILE is non-nil, profile that instead of USER-INIT-FILE."
|
||||
(interactive)
|
||||
(require 'esup)
|
||||
(let ((init-file esup-user-init-file))
|
||||
(message "Starting esup...")
|
||||
(esup-reset)
|
||||
(setq esup-server-process (esup-server-create (esup-select-port)))
|
||||
(setq esup-server-port (process-contact esup-server-process :service))
|
||||
(message "esup process started on port %s" esup-server-port)
|
||||
(let ((process-args `("*esup-child*"
|
||||
"*esup-child*"
|
||||
,esup-emacs-path
|
||||
"-q"
|
||||
"-L" ,esup-load-path
|
||||
"-l" "esup-child"
|
||||
,(format "--eval=(esup-child-run \"%s\" \"%s\" %d)"
|
||||
init-file
|
||||
esup-server-port
|
||||
esup-depth)
|
||||
"--eval=(run-hooks 'after-init-hook 'emacs-startup-hook 'window-setup-hook)")))
|
||||
(when esup-run-as-batch-p
|
||||
(setq process-args (append process-args '("--batch"))))
|
||||
(setq esup-child-process (apply #'start-process process-args)))
|
||||
(set-process-sentinel esup-child-process 'esup-child-process-sentinel)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-info ()
|
||||
"Returns diagnostic information about the current Emacs session in markdown,
|
||||
ready to be pasted in a bug report on github."
|
||||
(require 'vc-git)
|
||||
(let ((default-directory doom-emacs-dir))
|
||||
(format
|
||||
(concat "- OS: %s (%s)\n"
|
||||
"- Emacs: %s (%s)\n"
|
||||
"- Doom: %s (%s %s)\n"
|
||||
"- Graphic display: %s (daemon: %s)\n"
|
||||
"- System features: %s\n"
|
||||
"- Details:\n"
|
||||
" ```elisp\n"
|
||||
" uname -a: %s\n"
|
||||
" modules: %s\n"
|
||||
" packages: %s\n"
|
||||
" elc dirs: %s\n"
|
||||
" exec-path: %s\n"
|
||||
" ```\n")
|
||||
system-type system-configuration
|
||||
emacs-version (format-time-string "%b %d, %Y" emacs-build-time)
|
||||
doom-version
|
||||
(if-let* ((branch (vc-git--symbolic-ref "core/core.el")))
|
||||
branch
|
||||
"n/a")
|
||||
(if-let* ((rev (vc-git-working-revision "core/core.el")))
|
||||
(format "https://github.com/hlissner/doom-emacs/commit/%s" rev)
|
||||
"n/a")
|
||||
(display-graphic-p) (daemonp)
|
||||
(bound-and-true-p system-configuration-features)
|
||||
;; details
|
||||
(with-temp-buffer
|
||||
(unless (zerop (call-process "uname" nil t nil "-a"))
|
||||
(insert (format "%s" system-type)))
|
||||
(string-trim (buffer-string)))
|
||||
(or (cl-loop with cat = nil
|
||||
for key being the hash-keys of doom-modules
|
||||
if (or (not cat) (not (eq cat (car key))))
|
||||
do (setq cat (car key)) and collect cat
|
||||
else collect
|
||||
(let ((flags (doom-module-get cat (cdr key) :flags)))
|
||||
(if flags
|
||||
`(,(cdr key) ,@flags)
|
||||
(cdr key))))
|
||||
"n/a")
|
||||
(or (let (packages)
|
||||
(ignore-errors
|
||||
(require 'async)
|
||||
;; collect these in another session to protect this
|
||||
;; session's state
|
||||
(async-get
|
||||
(async-start
|
||||
`(lambda ()
|
||||
(setq load-path ',load-path)
|
||||
(load ,(expand-file-name "core/core.el" doom-emacs-dir))
|
||||
(load ,(expand-file-name "init.el" doom-emacs-dir))
|
||||
(load ,(expand-file-name "core/autoload/packages.el" doom-emacs-dir))
|
||||
(doom-get-packages))
|
||||
(lambda (p) (setq packages p))))
|
||||
(mapcar (lambda (x)
|
||||
(if (cdr x)
|
||||
(format "%s" x)
|
||||
(symbol-name (car x))))
|
||||
(cl-sort packages #'string-lessp :key (lambda (x) (symbol-name (car x)))))))
|
||||
"n/a")
|
||||
(or (ignore-errors
|
||||
(cl-delete-duplicates
|
||||
(cl-loop for file in (append (reverse (directory-files-recursively doom-core-dir "\\.elc$"))
|
||||
(cl-loop for dir in doom-modules-dirs
|
||||
nconc (directory-files-recursively dir "\\.elc$")))
|
||||
collect (file-relative-name (file-name-directory file) doom-emacs-dir))
|
||||
:test #'equal))
|
||||
"n/a")
|
||||
exec-path)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/info ()
|
||||
"Collects some debug information about your Emacs session, formats it into
|
||||
markdown and copies it to your clipboard, ready to be pasted into bug reports!"
|
||||
(declare (interactive-only t))
|
||||
(interactive)
|
||||
(if noninteractive
|
||||
(message "%s" (doom-info))
|
||||
(message "Generating Doom info...")
|
||||
(kill-new (doom-info))
|
||||
(message "Done! Copied to clipboard.")))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/toggle-debug-mode ()
|
||||
(interactive)
|
||||
(setq doom-debug-mode (not doom-debug-mode))
|
||||
(toggle-debug-on-error))
|
286
core/core-dispatcher.el
Normal file
286
core/core-dispatcher.el
Normal file
|
@ -0,0 +1,286 @@
|
|||
;;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
|
||||
;; Eagerly load these libraries because this module may be loaded in a session
|
||||
;; that hasn't been fully initialized (where autoloads files haven't been
|
||||
;; generated or `load-path' populated).
|
||||
(load! autoload/packages)
|
||||
(load! autoload/modules)
|
||||
(load! autoload/debug)
|
||||
(load! autoload/message)
|
||||
|
||||
|
||||
;;
|
||||
;; Dispatcher API
|
||||
;;
|
||||
|
||||
(defvar doom-auto-accept (getenv "YES")
|
||||
"If non-nil, Doom will auto-accept any confirmation prompts during batch
|
||||
commands like `doom//packages-install', `doom//packages-update' and
|
||||
`doom//packages-autoremove'.")
|
||||
|
||||
(defconst doom--dispatch-command-alist ())
|
||||
(defconst doom--dispatch-alias-alist ())
|
||||
|
||||
(defun doom--dispatch-format (desc &optional short)
|
||||
(if (equal desc "TODO")
|
||||
(format! (yellow "TODO"))
|
||||
(with-temp-buffer
|
||||
(let ((fill-column 72))
|
||||
(insert desc)
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "\n\n[^ \n]" nil t)
|
||||
(fill-paragraph)))
|
||||
(if (not short)
|
||||
(buffer-string)
|
||||
(goto-char (point-min))
|
||||
(buffer-substring-no-properties
|
||||
(line-beginning-position)
|
||||
(line-end-position))))))
|
||||
|
||||
(defun doom--dispatch-help (&optional command desc &rest args)
|
||||
"Display help documentation for a dispatcher command. If COMMAND and DESC are
|
||||
omitted, show all available commands, their aliases and brief descriptions."
|
||||
(if command
|
||||
(princ (doom--dispatch-format desc))
|
||||
(print! (bold "%-10s\t%s\t%s" "Command:" "Alias" "Description"))
|
||||
(dolist (spec (sort doom--dispatch-command-alist
|
||||
(lambda (x y) (string-lessp (car x) (car y)))))
|
||||
(cl-destructuring-bind (command &key desc _body) spec
|
||||
(let ((aliases (cl-loop for (alias . cmd) in doom--dispatch-alias-alist
|
||||
if (eq cmd command)
|
||||
collect (symbol-name alias))))
|
||||
(print! " %-10s\t%s\t%s"
|
||||
command (if aliases (string-join aliases ",") "")
|
||||
(doom--dispatch-format desc t)))))))
|
||||
|
||||
(defun doom-dispatch (args)
|
||||
"Invoke a dispatcher command and pass ARGS to it."
|
||||
(let ((help (equal (car args) "help")))
|
||||
(if help (pop args))
|
||||
(cl-destructuring-bind (command &key desc body)
|
||||
(let ((sym (intern (car args))))
|
||||
(or (assq sym doom--dispatch-command-alist)
|
||||
(assq (cdr (assq sym doom--dispatch-alias-alist)) doom--dispatch-command-alist)
|
||||
(error "Invalid command: %s" (car args))))
|
||||
(if help
|
||||
(apply #'doom--dispatch-help command desc (cdr args))
|
||||
(funcall body (cdr args))))))
|
||||
|
||||
;; FIXME Clumsy way of registering commands, refactor!
|
||||
(defmacro def-dispatcher! (command desc &rest body)
|
||||
"Define a dispatcher command. COMMAND is a symbol or a list of symbols
|
||||
representing the aliases for this command. DESC is a string description. The
|
||||
first line should be short (under 60 letters), as it will be displayed for
|
||||
bin/doom help.
|
||||
|
||||
BODY will be run when this dispatcher is called."
|
||||
(declare (doc-string 2))
|
||||
(let* ((command (doom-enlist command))
|
||||
(cmd (car command))
|
||||
(aliases (cdr command)))
|
||||
`(progn
|
||||
,(when aliases
|
||||
`(dolist (alias ',aliases)
|
||||
(map-put doom--dispatch-alias-alist alias ',cmd)))
|
||||
(map-put doom--dispatch-command-alist
|
||||
',cmd (list :desc ,desc
|
||||
;; FIXME Implicit args var; ew
|
||||
:body (lambda (args) ,@body))))))
|
||||
|
||||
|
||||
;;
|
||||
;; Dispatch commands
|
||||
;;
|
||||
|
||||
;; Dummy dispatchers (no-op because they're handled especially)
|
||||
(def-dispatcher! run
|
||||
"Run Doom Emacs from bin/doom's parent directory.
|
||||
|
||||
All arguments are passed on to Emacs (except for -p and -e).
|
||||
|
||||
doom run
|
||||
doom run -nw init.el
|
||||
|
||||
WARNING: this command exists for convenience and testing. Doom will suffer
|
||||
additional overhead for be started this way. For the best performance, it
|
||||
is best to run Doom out of ~/.emacs.d and ~/.doom.d.")
|
||||
|
||||
(def-dispatcher! (doctor doc)
|
||||
"Checks for issues with your current Doom config.")
|
||||
|
||||
(def-dispatcher! (help h)
|
||||
"Look up additional information about a command.")
|
||||
|
||||
;; Real dispatchers
|
||||
(def-dispatcher! (quickstart qs)
|
||||
"Quickly deploy a private module and Doom.
|
||||
|
||||
This deploys a barebones config to ~/.doom.d. The destination can be changed
|
||||
with the -p option, e.g.
|
||||
|
||||
doom -p ~/.config/doom quickstart
|
||||
|
||||
This command will refuse to overwrite the private directory if it already
|
||||
exists."
|
||||
(doom//quickstart))
|
||||
|
||||
(def-dispatcher! (install i)
|
||||
"Installs requested plugins that aren't installed."
|
||||
(doom//reload-doom-autoloads)
|
||||
(when (doom//packages-install doom-auto-accept)
|
||||
(doom//reload-package-autoloads)))
|
||||
|
||||
(def-dispatcher! (update u)
|
||||
"Checks for and updates outdated plugins."
|
||||
(doom//reload-doom-autoloads)
|
||||
(when (doom//packages-update doom-auto-accept)
|
||||
(doom//reload-package-autoloads)))
|
||||
|
||||
(def-dispatcher! (autoremove r)
|
||||
"Removes orphaned plugins."
|
||||
(doom//reload-doom-autoloads)
|
||||
(when (doom//packages-autoremove doom-auto-accept)
|
||||
(doom//reload-package-autoloads)))
|
||||
|
||||
(def-dispatcher! (autoloads a)
|
||||
"Regenerates Doom's autoloads file.
|
||||
|
||||
This file tells Emacs where to find your module's autoloaded functions and
|
||||
plugins."
|
||||
(doom//reload-autoloads nil 'force))
|
||||
|
||||
(def-dispatcher! (upgrade up)
|
||||
"Checks out the latest Doom on this branch."
|
||||
(doom//upgrade))
|
||||
|
||||
(def-dispatcher! (compile c)
|
||||
"Byte-compiles your config or selected modules.
|
||||
|
||||
compile [TARGETS...]
|
||||
compile :core :private lang/python
|
||||
compile feature lang
|
||||
|
||||
Accepts :core, :private and :plugins as special arguments, indicating you want
|
||||
to byte-compile Doom's core files, your private config or your ELPA plugins,
|
||||
respectively."
|
||||
(doom//byte-compile args))
|
||||
|
||||
(def-dispatcher! (recompile rc)
|
||||
"Re-byte-compiles outdated *.elc files."
|
||||
(doom//byte-compile args 'recompile))
|
||||
|
||||
(def-dispatcher! clean
|
||||
"Delete all *.elc files."
|
||||
(doom//clean-byte-compiled-files))
|
||||
|
||||
(def-dispatcher! test
|
||||
"Run Doom unit tests."
|
||||
(load! autoload/test)
|
||||
(doom//run-tests args))
|
||||
|
||||
(def-dispatcher! info
|
||||
"Output system info in markdown for bug reports."
|
||||
(doom/info))
|
||||
|
||||
(def-dispatcher! (version v)
|
||||
"Reports the version of Doom and Emacs."
|
||||
(doom/version))
|
||||
|
||||
(def-dispatcher! (refresh re)
|
||||
"Refresh Doom. Same as autoremove+install+autoloads.
|
||||
|
||||
This is the equivalent of running autoremove, install, autoloads, then
|
||||
recompile. Run this whenever you:
|
||||
|
||||
1. Modify your `doom!' block,
|
||||
2. Add or remove `package!' blocks to your config,
|
||||
3. Add or remove autoloaded functions in module autoloaded files.
|
||||
4. Update Doom outside of Doom (e.g. with git)"
|
||||
(let ((doom--inhibit-reload t))
|
||||
(with-demoted-errors "%s" (doom//packages-autoremove))
|
||||
(with-demoted-errors "%s" (doom//packages-install)))
|
||||
(doom//reload-autoloads)
|
||||
(doom//byte-compile nil 'recompile))
|
||||
|
||||
|
||||
;;
|
||||
;; Quality of Life Commands
|
||||
;;
|
||||
|
||||
;; FIXME Detect & enforce remote
|
||||
(defvar doom-remote "origin"
|
||||
"TODO")
|
||||
|
||||
(defun doom//upgrade ()
|
||||
"Upgrade Doom to the latest version."
|
||||
(interactive)
|
||||
(require 'vc-git)
|
||||
(let ((core-file (expand-file-name "init.el" doom-core-dir))
|
||||
(branch (vc-git--symbolic-ref core-file))
|
||||
(default-directory doom-emacs-dir))
|
||||
(unless (file-exists-p core-file)
|
||||
(error "Couldn't find %s, was Doom cloned properly?"
|
||||
(abbreviate-file-name core-file)))
|
||||
(unless branch
|
||||
(error "Couldn't detect what branch you're using. Is %s a repo?"
|
||||
(abbreviate-file-name doom-emacs-dir)))
|
||||
(unless (eq (vc-state core-file 'Git) 'up-to-date)
|
||||
(user-error "Doom has been modified; refusing to upgrade. Stash or undo your changes"))
|
||||
(with-temp-buffer
|
||||
(let ((buf (current-buffer)))
|
||||
(when (zerop (process-file "git" nil buf nil
|
||||
"fetch" "--tags" doom-remote branch))
|
||||
(let ((current-rev (vc-git-working-revision core-file))
|
||||
(rev (shell-command-to-string (format "git rev-parse %s/%s" doom-remote branch))))
|
||||
(unless rev
|
||||
(error "Couldn't detect Doom's version. Is %s a repo?"
|
||||
(abbreviate-file-name doom-emacs-dir)))
|
||||
(if (equal current-rev rev)
|
||||
(message "Doom is up to date!")
|
||||
(when (or doom-auto-accept
|
||||
(y-or-n-p "Doom is out of date, update?"))
|
||||
(unless (zerop (process-file "git" nil buf nil
|
||||
"checkout" (format "%s/%s" doom-remote branch)))
|
||||
(error "An error occurred while checking out the latest commit"))
|
||||
(when (file-exists-p (byte-compile-dest-file core-file))
|
||||
(message "Your config is byte-compiled, removing byte-compiled files")
|
||||
(doom//clean-byte-compiled-files))
|
||||
(doom//reload)
|
||||
(message "Done! Please restart Emacs for changes to take effect")))))))))
|
||||
|
||||
(defun doom//quickstart ()
|
||||
"Quickly deploy a private module and Doom.
|
||||
|
||||
This deploys a barebones config to `doom-private-dir', installs all missing
|
||||
packages and regenerates the autoloads file."
|
||||
(interactive)
|
||||
(let ((short-private-dir (abbreviate-file-name doom-private-dir)))
|
||||
(if (file-directory-p doom-private-dir)
|
||||
(print! (yellow "%s directory already exists. Skipping." short-private-dir))
|
||||
(print! "Creating %s" short-private-dir)
|
||||
(make-directory doom-private-dir t)
|
||||
(print! (green "Done!")))
|
||||
(let ((init-file (expand-file-name "init.el" doom-private-dir)))
|
||||
(if (file-exists-p init-file)
|
||||
(print! (yellow "%sinit.el already exists. Skipping." short-private-dir))
|
||||
(print! "Copying init.example.el to %s" short-private-dir)
|
||||
(copy-file (expand-file-name "init.example.el" doom-emacs-dir)
|
||||
init-file)
|
||||
(print! (green "Done!"))))
|
||||
(let ((config-file (expand-file-name "config.el" doom-private-dir)))
|
||||
(if (file-exists-p config-file)
|
||||
(print! "%sconfig.el already exists. Skipping." short-private-dir)
|
||||
(print! "Deploying empty config.el file in %s" short-private-dir)
|
||||
(with-temp-file config-file (insert ""))
|
||||
(print! (green "Done!")))))
|
||||
(print! "Installing plugins")
|
||||
(doom//packages-install)
|
||||
(print! "Regenerating autoloads files")
|
||||
(doom//reload-autoloads nil 'force-p)
|
||||
(print! (bold (green "\nFinished! Doom is ready to go!\n")))
|
||||
(with-temp-buffer
|
||||
(doom-template-insert "QUICKSTART_INTRO")
|
||||
(print! (buffer-string))))
|
||||
|
||||
(provide 'core-dispatcher)
|
||||
;;; core-dispatcher.el ends here
|
|
@ -70,7 +70,7 @@ fundamental-mode) for performance sake."
|
|||
;; Built-in plugins
|
||||
;;
|
||||
|
||||
(push '("/[A-Z]+$" . text-mode) auto-mode-alist)
|
||||
(push '("/LICENSE\\'" . text-mode) auto-mode-alist)
|
||||
|
||||
(electric-indent-mode -1) ; enabled by default in Emacs 25+. No thanks.
|
||||
|
||||
|
@ -83,14 +83,15 @@ fundamental-mode) for performance sake."
|
|||
|
||||
;; revert buffers for changed files
|
||||
(def-package! autorevert
|
||||
:defer doom-before-switch-buffer-hook
|
||||
:after-call doom-before-switch-buffer-hook
|
||||
:config
|
||||
(setq auto-revert-verbose nil)
|
||||
(global-auto-revert-mode +1))
|
||||
|
||||
;; persist variables across sessions
|
||||
(def-package! savehist
|
||||
:defer (pre-command-hook . 1)
|
||||
:defer 1
|
||||
:after-call post-command-hook
|
||||
:config
|
||||
(setq savehist-file (concat doom-cache-dir "savehist")
|
||||
savehist-save-minibuffer-history t
|
||||
|
@ -100,7 +101,7 @@ fundamental-mode) for performance sake."
|
|||
|
||||
;; persistent point location in buffers
|
||||
(def-package! saveplace
|
||||
:defer doom-before-switch-buffer-hook
|
||||
:after-call doom-before-switch-buffer-hook
|
||||
:config
|
||||
(setq save-place-file (concat doom-cache-dir "saveplace"))
|
||||
(defun doom*recenter-on-load-saveplace (&rest _)
|
||||
|
@ -112,20 +113,21 @@ fundamental-mode) for performance sake."
|
|||
|
||||
;; Keep track of recently opened files
|
||||
(def-package! recentf
|
||||
:defer (pre-command-hook . 1)
|
||||
:defer 1
|
||||
:after-call find-file-hook
|
||||
:commands recentf-open-files
|
||||
:config
|
||||
(setq recentf-save-file (concat doom-cache-dir "recentf")
|
||||
recentf-auto-cleanup 60
|
||||
recentf-auto-cleanup 120
|
||||
recentf-max-menu-items 0
|
||||
recentf-max-saved-items 300
|
||||
recentf-filename-handlers '(file-truename)
|
||||
recentf-exclude
|
||||
(list #'file-remote-p "\\.\\(gz\\|gif\\|svg\\|png\\|jpe?g\\)$"
|
||||
(list #'file-remote-p "\\.\\(?:gz\\|gif\\|svg\\|png\\|jpe?g\\)$"
|
||||
"^/tmp/" "^/ssh:" "\\.?ido\\.last$" "\\.revive$" "/TAGS$"
|
||||
"^/var/folders/.+$"
|
||||
;; ignore private DOOM temp files (but not all of them)
|
||||
(concat "^" (file-truename doom-local-dir))))
|
||||
(lambda (file) (file-in-directory-p file doom-local-dir))))
|
||||
(recentf-mode +1))
|
||||
|
||||
|
||||
|
@ -135,7 +137,7 @@ fundamental-mode) for performance sake."
|
|||
|
||||
;; Auto-close delimiters and blocks as you type
|
||||
(def-package! smartparens
|
||||
:defer doom-before-switch-buffer-hook
|
||||
:after-call doom-before-switch-buffer-hook
|
||||
:commands (sp-pair sp-local-pair sp-with-modes)
|
||||
:config
|
||||
(require 'smartparens-config)
|
||||
|
@ -155,7 +157,7 @@ fundamental-mode) for performance sake."
|
|||
|
||||
;; Branching undo
|
||||
(def-package! undo-tree
|
||||
:defer doom-before-switch-buffer-hook
|
||||
:after-call doom-before-switch-buffer-hook
|
||||
:config
|
||||
;; persistent undo history is known to cause undo history corruption, which
|
||||
;; can be very destructive! So disable it!
|
||||
|
@ -176,13 +178,15 @@ fundamental-mode) for performance sake."
|
|||
command-log-mode-open-log-turns-on-mode t))
|
||||
|
||||
(def-package! dtrt-indent
|
||||
:after-call doom-before-switch-buffer-hook
|
||||
:config
|
||||
(setq dtrt-indent-verbosity (if doom-debug-mode 2 0))
|
||||
|
||||
(defun doom|detect-indentation ()
|
||||
(unless (or doom-inhibit-indent-detection (eq major-mode 'fundamental-mode))
|
||||
(dtrt-indent-mode +1)))
|
||||
(add-hook 'after-change-major-mode-hook #'doom|detect-indentation))
|
||||
(unless noninteractive
|
||||
(add-hook 'after-change-major-mode-hook #'doom|detect-indentation)))
|
||||
|
||||
(def-package! expand-region
|
||||
:commands (er/expand-region er/contract-region er/mark-symbol er/mark-word)
|
||||
|
|
|
@ -56,19 +56,15 @@ If any hook returns non-nil, all hooks after it are ignored.")
|
|||
;; embolden local bindings
|
||||
(set-face-attribute 'which-key-local-map-description-face nil :weight 'bold)
|
||||
(which-key-setup-side-window-bottom)
|
||||
(add-hook 'doom-init-hook #'which-key-mode))
|
||||
(add-hook 'doom-post-init-hook #'which-key-mode))
|
||||
|
||||
|
||||
(def-package! hydra
|
||||
:commands (defhydra defhydradio)
|
||||
:init
|
||||
;; In case I later need to wrap defhydra in any special functionality.
|
||||
(defalias 'def-hydra! 'defhydra)
|
||||
(defalias 'def-hydra-radio! 'defhydradio)
|
||||
:defer t
|
||||
:config
|
||||
(setq lv-use-seperator t)
|
||||
|
||||
(def-hydra! doom@text-zoom (:hint t :color red)
|
||||
(defhydra doom@text-zoom (:hint t :color red)
|
||||
"
|
||||
Text zoom: _j_:zoom in, _k_:zoom out, _0_:reset
|
||||
"
|
||||
|
@ -76,7 +72,7 @@ If any hook returns non-nil, all hooks after it are ignored.")
|
|||
("k" text-scale-decrease "out")
|
||||
("0" (text-scale-set 0) "reset"))
|
||||
|
||||
(def-hydra! doom@window-nav (:hint nil)
|
||||
(defhydra doom@window-nav (:hint nil)
|
||||
"
|
||||
Split: _v_ert _s_:horz
|
||||
Delete: _c_lose _o_nly
|
||||
|
|
185
core/core-lib.el
185
core/core-lib.el
|
@ -1,8 +1,15 @@
|
|||
;;; core-lib.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; Built in packages we use a lot of
|
||||
(require 'subr-x)
|
||||
(require 'cl-lib)
|
||||
(require 'map)
|
||||
|
||||
(eval-and-compile
|
||||
(unless EMACS26+
|
||||
(with-no-warnings
|
||||
;; if-let and when-let are deprecated in Emacs 26+ in favor of their
|
||||
;; if-let* variants, so we alias them for 25 users.
|
||||
(defalias 'if-let* #'if-let)
|
||||
(defalias 'when-let* #'when-let))))
|
||||
|
||||
|
@ -11,18 +18,40 @@
|
|||
;; Helpers
|
||||
;;
|
||||
|
||||
(defun doom--resolve-path-forms (paths &optional root)
|
||||
(cond ((stringp paths)
|
||||
(defun doom--resolve-path-forms (spec &optional directory)
|
||||
"Converts a simple nested series of or/and forms into a series of
|
||||
`file-exists-p' checks.
|
||||
|
||||
For example
|
||||
|
||||
(doom--resolve-path-forms
|
||||
'(or \"some-file\" (and path-var \"/an/absolute/path\"))
|
||||
\"~\")
|
||||
|
||||
Returns
|
||||
|
||||
'(or (file-exists-p (expand-file-name \"some-file\" \"~\"))
|
||||
(and (file-exists-p (expand-file-name path-var \"~\"))
|
||||
(file-exists-p \"/an/absolute/path\")))
|
||||
|
||||
This is used by `associate!', `file-exists-p!' and `project-file-exists-p!'."
|
||||
(cond ((stringp spec)
|
||||
`(file-exists-p
|
||||
(expand-file-name
|
||||
,paths ,(if (or (string-prefix-p "./" paths)
|
||||
(string-prefix-p "../" paths))
|
||||
'default-directory
|
||||
(or root `(doom-project-root))))))
|
||||
((listp paths)
|
||||
(cl-loop for i in paths
|
||||
collect (doom--resolve-path-forms i root)))
|
||||
(t paths)))
|
||||
,(if (file-name-absolute-p spec)
|
||||
spec
|
||||
`(expand-file-name ,spec ,directory))))
|
||||
((symbolp spec)
|
||||
`(file-exists-p ,(if directory
|
||||
`(expand-file-name ,spec ,directory)
|
||||
path)))
|
||||
((and (listp spec)
|
||||
(memq (car spec) '(or and)))
|
||||
`(,(car spec)
|
||||
,@(cl-loop for i in (cdr spec)
|
||||
collect (doom--resolve-path-forms i directory))))
|
||||
((listp spec)
|
||||
(doom--resolve-path-forms (eval spec t) directory))
|
||||
(t spec)))
|
||||
|
||||
(defun doom--resolve-hook-forms (hooks)
|
||||
(cl-loop with quoted-p = (eq (car-safe hooks) 'quote)
|
||||
|
@ -33,6 +62,11 @@
|
|||
collect hook
|
||||
else collect (intern (format "%s-hook" (symbol-name hook)))))
|
||||
|
||||
|
||||
;;
|
||||
;; Functions
|
||||
;;
|
||||
|
||||
(defun doom-unquote (exp)
|
||||
"Return EXP unquoted."
|
||||
(while (memq (car-safe exp) '(quote function))
|
||||
|
@ -43,6 +77,94 @@
|
|||
"Return EXP wrapped in a list, or as-is if already a list."
|
||||
(if (listp exp) exp (list exp)))
|
||||
|
||||
(defun doom-file-cookie-p (file)
|
||||
"Returns the return value of the ;;;###if predicate form in FILE."
|
||||
(with-temp-buffer
|
||||
(insert-file-contents-literally file nil 0 256)
|
||||
(if (and (re-search-forward "^;;;###if " nil t)
|
||||
(<= (line-number-at-pos) 3))
|
||||
(let ((load-file-name file))
|
||||
(eval (sexp-at-point)))
|
||||
t)))
|
||||
|
||||
(defun doom-keyword-intern (str)
|
||||
"Converts STR (a string) into a keyword (`keywordp')."
|
||||
(or (stringp str)
|
||||
(signal 'wrong-type-argument (list 'stringp str)))
|
||||
(intern (concat ":" str)))
|
||||
|
||||
(defun doom-keyword-name (keyword)
|
||||
"Returns the string name of KEYWORD (`keywordp') minus the leading colon."
|
||||
(or (keywordp keyword)
|
||||
(signal 'wrong-type-argument (list 'keywordp keyword)))
|
||||
(substring (symbol-name keyword) 1))
|
||||
|
||||
(cl-defun doom-files-in
|
||||
(path-or-paths &rest rest
|
||||
&key
|
||||
filter
|
||||
map
|
||||
full
|
||||
(follow-symlinks t)
|
||||
(type 'files)
|
||||
(relative-to (unless full default-directory))
|
||||
(depth 99999)
|
||||
(match "^[^.]"))
|
||||
"Returns a list of files/directories in PATH-OR-PATHS (one string path or a
|
||||
list of them).
|
||||
|
||||
FILTER is a function or symbol that takes one argument (the path). If it returns
|
||||
non-nil, the entry will be excluded.
|
||||
|
||||
MAP is a function or symbol which will be used to transform each entry in the
|
||||
results.
|
||||
|
||||
TYPE determines what kind of path will be included in the results. This can be t
|
||||
(files and folders), 'files or 'dirs.
|
||||
|
||||
By default, this function returns paths relative to PATH-OR-PATHS if it is a
|
||||
single path. If it a list of paths, this function returns absolute paths.
|
||||
Otherwise, by setting RELATIVE-TO to a path, the results will be transformed to
|
||||
be relative to it.
|
||||
|
||||
The search recurses up to DEPTH and no further. DEPTH is an integer.
|
||||
|
||||
MATCH is a string regexp. Only entries that match it will be included."
|
||||
(cond
|
||||
((listp path-or-paths)
|
||||
(cl-loop for path in path-or-paths
|
||||
if (file-directory-p path)
|
||||
nconc (apply #'doom-files-in path (plist-put rest :relative-to relative-to))))
|
||||
((let ((path path-or-paths)
|
||||
result)
|
||||
(dolist (file (file-name-all-completions "" path))
|
||||
(unless (member file '("./" "../"))
|
||||
(let ((fullpath (expand-file-name file path)))
|
||||
(cond ((directory-name-p fullpath)
|
||||
(when (and (memq type '(t dirs))
|
||||
(string-match-p match file)
|
||||
(not (and filter (funcall filter fullpath)))
|
||||
(not (and (file-symlink-p fullpath)
|
||||
(not follow-symlinks))))
|
||||
(setq result
|
||||
(nconc result
|
||||
(list (cond (map (funcall map fullpath))
|
||||
(relative-to (file-relative-name fullpath relative-to))
|
||||
(fullpath))))))
|
||||
(unless (<= depth 1)
|
||||
(setq result
|
||||
(nconc result (apply #'doom-files-in fullpath
|
||||
(append `(:depth ,(1- depth) :relative-to ,relative-to)
|
||||
rest))))))
|
||||
((and (memq type '(t files))
|
||||
(string-match-p match file)
|
||||
(not (and filter (funcall filter fullpath))))
|
||||
(push (if relative-to
|
||||
(file-relative-name fullpath relative-to)
|
||||
fullpath)
|
||||
result))))))
|
||||
result))))
|
||||
|
||||
(defun doom*shut-up (orig-fn &rest args)
|
||||
"Generic advisor for silencing noisy functions."
|
||||
(quiet! (apply orig-fn args)))
|
||||
|
@ -61,8 +183,10 @@
|
|||
|
||||
(defmacro after! (targets &rest body)
|
||||
"A smart wrapper around `with-eval-after-load'. Supresses warnings during
|
||||
compilation."
|
||||
compilation. This will no-op on features that have been disabled by the user."
|
||||
(declare (indent defun) (debug t))
|
||||
(unless (and (symbolp targets)
|
||||
(memq targets doom-disabled-packages))
|
||||
(list (if (or (not (bound-and-true-p byte-compile-current-file))
|
||||
(dolist (next (doom-enlist targets))
|
||||
(if (symbolp next)
|
||||
|
@ -83,7 +207,7 @@ compilation."
|
|||
(setq body `(after! ,next ,@body)))
|
||||
body)
|
||||
((listp targets)
|
||||
`(after! (:all ,@targets) ,@body)))))
|
||||
`(after! (:all ,@targets) ,@body))))))
|
||||
|
||||
(defmacro quiet! (&rest forms)
|
||||
"Run FORMS without making any output."
|
||||
|
@ -121,10 +245,11 @@ HOOK can be a quoted hook or a sharp-quoted function (which will be advised)."
|
|||
,@forms
|
||||
(cond ((functionp ,hook) (advice-remove ,hook #',fn))
|
||||
((symbolp ,hook) (remove-hook ,hook #',fn)))
|
||||
(unintern ',fn nil)))
|
||||
(fmakunbound ',fn)))
|
||||
(cond ((functionp ,hook)
|
||||
(advice-add ,hook ,(if append :after :before) #',fn))
|
||||
((symbolp ,hook)
|
||||
(put ',fn 'permanent-local-hook t)
|
||||
(add-hook ,hook #',fn ,append))))))
|
||||
|
||||
(defmacro add-hook! (&rest args)
|
||||
|
@ -138,7 +263,7 @@ HOOK can be a quoted hook or a sharp-quoted function (which will be advised)."
|
|||
3. A function, list of functions, or body forms to be wrapped in a lambda.
|
||||
|
||||
Examples:
|
||||
(add-hook! 'some-mode-hook 'enable-something)
|
||||
(add-hook! 'some-mode-hook 'enable-something) (same as `add-hook')
|
||||
(add-hook! some-mode '(enable-something and-another))
|
||||
(add-hook! '(one-mode-hook second-mode-hook) 'enable-something)
|
||||
(add-hook! (one-mode second-mode) 'enable-something)
|
||||
|
@ -201,7 +326,19 @@ Body forms can access the hook's arguments through the let-bound variable
|
|||
(nreverse forms))))
|
||||
|
||||
(defmacro associate! (mode &rest plist)
|
||||
"Associate a minor mode to certain patterns and project files."
|
||||
"Enables a minor mode if certain conditions are met.
|
||||
|
||||
The available conditions are:
|
||||
|
||||
:modes SYMBOL_LIST
|
||||
A list of major/minor modes in which this minor mode may apply.
|
||||
:match REGEXP
|
||||
A regexp to be tested against the current file path.
|
||||
:files SPEC
|
||||
Accepts what `project-file-exists-p!' accepts. Checks if certain files exist
|
||||
relative to the project root.
|
||||
:when FORM
|
||||
Whenever FORM returns non-nil."
|
||||
(declare (indent 1))
|
||||
(unless noninteractive
|
||||
(let ((modes (plist-get plist :modes))
|
||||
|
@ -220,7 +357,7 @@ Body forms can access the hook's arguments through the let-bound variable
|
|||
(not ,mode)
|
||||
(and buffer-file-name (not (file-remote-p buffer-file-name)))
|
||||
,(if match `(if buffer-file-name (string-match-p ,match buffer-file-name)) t)
|
||||
,(if files (doom--resolve-path-forms files) t)
|
||||
,(if files (doom--resolve-path-forms files '(doom-project-root)) t)
|
||||
,(or pred-form t))
|
||||
(,mode 1)))
|
||||
,@(if (and modes (listp modes))
|
||||
|
@ -232,5 +369,19 @@ Body forms can access the hook's arguments through the let-bound variable
|
|||
(t (user-error "associate! invalid rules for mode [%s] (modes %s) (match %s) (files %s)"
|
||||
mode modes match files))))))
|
||||
|
||||
(defmacro file-exists-p! (spec &optional directory)
|
||||
"Returns t if the files in SPEC all exist.
|
||||
|
||||
SPEC can be a single file or a list of forms/files. It understands nested (and
|
||||
...) and (or ...), as well.
|
||||
|
||||
DIRECTORY is where to look for the files in SPEC if they aren't absolute. This
|
||||
doesn't apply to variables, however.
|
||||
|
||||
For example:
|
||||
|
||||
(file-exists-p (or doom-core-dir \"~/.config\" \"some-file\") \"~\")"
|
||||
(doom--resolve-path-forms spec directory))
|
||||
|
||||
(provide 'core-lib)
|
||||
;;; core-lib.el ends here
|
||||
|
|
|
@ -30,10 +30,12 @@
|
|||
;; Don't open files from the workspace in a new frame
|
||||
ns-pop-up-frames nil)
|
||||
|
||||
(cond ((display-graphic-p)
|
||||
(if (not (display-graphic-p))
|
||||
(add-hook 'doom-post-init-hook #'osx-clipboard-mode)
|
||||
;; A known problem with GUI Emacs on MacOS: it runs in an isolated
|
||||
;; environment, so envvars will be wrong. That includes the PATH
|
||||
;; Emacs picks up. `exec-path-from-shell' fixes this.
|
||||
;; environment, so envvars will be wrong. That includes the PATH Emacs
|
||||
;; picks up. `exec-path-from-shell' fixes this.
|
||||
(defun doom|init-exec-path ()
|
||||
(when (require 'exec-path-from-shell nil t)
|
||||
(def-setting! :env (&rest vars)
|
||||
"Inject VARS from your shell environment into Emacs."
|
||||
|
@ -42,8 +44,7 @@
|
|||
exec-path-from-shell-arguments (delete "-i" exec-path-from-shell-arguments))
|
||||
(defvaralias 'exec-path-from-shell-debug 'doom-debug-mode)
|
||||
(exec-path-from-shell-initialize)))
|
||||
((require 'osx-clipboard nil t)
|
||||
(osx-clipboard-mode +1))))
|
||||
(add-hook 'doom-pre-init-hook #'doom|init-exec-path)))
|
||||
|
||||
(IS-LINUX
|
||||
(setq x-gtk-use-system-tooltips nil ; native tooltips are ugly!
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -13,7 +13,7 @@
|
|||
|
||||
:config
|
||||
(add-hook 'dired-before-readin-hook #'projectile-track-known-projects-find-file-hook)
|
||||
(add-hook 'find-file-hook #'doom|autoload-project-mode)
|
||||
(add-hook 'find-file-hook #'doom|init-project-mode)
|
||||
(projectile-mode +1)
|
||||
|
||||
;; a more generic project root file
|
||||
|
@ -94,12 +94,12 @@ If NOCACHE, don't fetch a cached answer."
|
|||
|
||||
(defalias 'doom-project-expand #'projectile-expand-root)
|
||||
|
||||
(defmacro doom-project-has! (files)
|
||||
(defmacro project-file-exists-p! (files)
|
||||
"Checks if the project has the specified FILES.
|
||||
Paths are relative to the project root, unless they start with ./ or ../ (in
|
||||
which case they're relative to `default-directory'). If they start with a slash,
|
||||
they are absolute."
|
||||
(doom--resolve-path-forms files (doom-project-root)))
|
||||
(doom--resolve-path-forms files '(doom-project-root)))
|
||||
|
||||
(defun doom-project-find-file (dir)
|
||||
"Fuzzy-find a file under DIR."
|
||||
|
@ -131,7 +131,7 @@ for .dir-locals.el.")
|
|||
"Hook run when a project is enabled. The name of the project's mode and its
|
||||
state are passed in.")
|
||||
|
||||
(defun doom|autoload-project-mode ()
|
||||
(defun doom|init-project-mode ()
|
||||
"Auto-enable the project(s) listed in `doom-project'."
|
||||
(when doom-project
|
||||
(if (symbolp doom-project)
|
||||
|
|
100
core/core-ui.el
100
core/core-ui.el
|
@ -24,6 +24,7 @@ Expects a `font-spec'.")
|
|||
return a string). This changes the 'long' name of a major-mode, allowing for
|
||||
shorter major mode name in the mode-line. See `doom|set-mode-name'.")
|
||||
|
||||
;;
|
||||
(defvar doom-init-ui-hook nil
|
||||
"List of hooks to run when the UI has been initialized.")
|
||||
|
||||
|
@ -57,7 +58,7 @@ with `doom//reload-theme').")
|
|||
compilation-scroll-output 'first-error
|
||||
confirm-nonexistent-file-or-buffer t
|
||||
cursor-in-non-selected-windows nil ; hide cursors in other windows
|
||||
custom-theme-directory (concat doom-private-dir "themes/")
|
||||
custom-theme-directory (expand-file-name "themes/" doom-private-dir)
|
||||
display-line-numbers-width 3
|
||||
enable-recursive-minibuffers nil
|
||||
frame-inhibit-implied-resize t
|
||||
|
@ -177,15 +178,11 @@ DEFAULT is non-nil, set the default mode-line for all buffers."
|
|||
;; Plugins
|
||||
;;
|
||||
|
||||
(def-package! ace-link
|
||||
:commands (ace-link-help ace-link-org ace-link-addr ace-link-mu4e))
|
||||
|
||||
(def-package! avy
|
||||
:commands (avy-goto-char-2 avy-goto-line)
|
||||
:config
|
||||
;; `avy'
|
||||
(setq avy-all-windows nil
|
||||
avy-background t))
|
||||
avy-background t)
|
||||
|
||||
;; `all-the-icons'
|
||||
(def-package! all-the-icons
|
||||
:commands (all-the-icons-octicon all-the-icons-faicon all-the-icons-fileicon
|
||||
all-the-icons-wicon all-the-icons-material all-the-icons-alltheicon
|
||||
|
@ -200,19 +197,41 @@ DEFAULT is non-nil, set the default mode-line for all buffers."
|
|||
all-the-icons-wicon all-the-icons-alltheicon))
|
||||
(advice-add fn :around #'doom*disable-all-the-icons-in-tty)))
|
||||
|
||||
(def-package! hideshow ; built-in
|
||||
:commands (hs-minor-mode hs-toggle-hiding hs-already-hidden-p)
|
||||
:config (setq hs-hide-comments-when-hiding-all nil))
|
||||
;; `hide-mode-line-mode'
|
||||
(add-hook 'completion-list-mode-hook #'hide-mode-line-mode)
|
||||
|
||||
(def-package! hide-mode-line
|
||||
:commands hide-mode-line-mode
|
||||
:init (add-hook 'completion-list-mode-hook #'hide-mode-line-mode))
|
||||
;; `rainbow-delimiters' Helps us distinguish stacked delimiter pairs. Especially
|
||||
;; in parentheses-drunk languages like Lisp.
|
||||
(def-package! rainbow-delimiters
|
||||
:hook (lisp-mode . rainbow-delimiters-mode)
|
||||
:config (setq rainbow-delimiters-max-face-count 3))
|
||||
|
||||
(def-package! highlight-indentation
|
||||
:commands (highlight-indentation-mode highlight-indentation-current-column-mode))
|
||||
;; `restart-emacs'
|
||||
(setq restart-emacs--args (list "--restore"))
|
||||
|
||||
;; For modes with sub-par number fontification
|
||||
(def-package! highlight-numbers :commands highlight-numbers-mode)
|
||||
;; `visual-fill-column' For a distractions-free-like UI, that dynamically
|
||||
;; resizes margins and can center a buffer.
|
||||
(setq visual-fill-column-center-text t
|
||||
visual-fill-column-width
|
||||
;; take Emacs 26 line numbers into account
|
||||
(+ (if (boundp 'display-line-numbers) 6 0)
|
||||
fill-column))
|
||||
|
||||
|
||||
;;
|
||||
;; Built-in packages
|
||||
;;
|
||||
|
||||
;; `hideshow'
|
||||
(setq hs-hide-comments-when-hiding-all nil)
|
||||
|
||||
;; show typed keystrokes in minibuffer
|
||||
(defun doom|enable-ui-keystrokes () (setq echo-keystrokes 0.02))
|
||||
(defun doom|disable-ui-keystrokes () (setq echo-keystrokes 0))
|
||||
(doom|enable-ui-keystrokes)
|
||||
;; ...but hide them while isearch is active
|
||||
(add-hook 'isearch-mode-hook #'doom|disable-ui-keystrokes)
|
||||
(add-hook 'isearch-mode-end-hook #'doom|enable-ui-keystrokes)
|
||||
|
||||
;; Highlights the current line
|
||||
(def-package! hl-line ; built-in
|
||||
|
@ -253,50 +272,15 @@ DEFAULT is non-nil, set the default mode-line for all buffers."
|
|||
(add-hook 'evil-visual-state-entry-hook #'doom|disable-hl-line)
|
||||
(add-hook 'evil-visual-state-exit-hook #'doom|enable-hl-line-maybe)))
|
||||
|
||||
;; Helps us distinguish stacked delimiter pairs. Especially in parentheses-drunk
|
||||
;; languages like Lisp.
|
||||
(def-package! rainbow-delimiters
|
||||
:hook (lisp-mode . rainbow-delimiters-mode)
|
||||
:config (setq rainbow-delimiters-max-face-count 3))
|
||||
|
||||
(def-package! restart-emacs
|
||||
:commands restart-emacs
|
||||
:config (setq restart-emacs--args (list "--restore")))
|
||||
|
||||
;; For a distractions-free-like UI, that dynamically resizes margins and can
|
||||
;; center a buffer.
|
||||
(def-package! visual-fill-column
|
||||
:commands visual-fill-column-mode
|
||||
:config
|
||||
(setq-default
|
||||
visual-fill-column-center-text t
|
||||
visual-fill-column-width
|
||||
;; take Emacs 26 line numbers into account
|
||||
(+ (if (boundp 'display-line-numbers) 6 0)
|
||||
fill-column)))
|
||||
|
||||
|
||||
;;
|
||||
;; Built-in packages
|
||||
;;
|
||||
|
||||
;; show typed keystrokes in minibuffer
|
||||
(defun doom|enable-ui-keystrokes () (setq echo-keystrokes 0.02))
|
||||
(defun doom|disable-ui-keystrokes () (setq echo-keystrokes 0))
|
||||
(doom|enable-ui-keystrokes)
|
||||
;; ...but hide them while isearch is active
|
||||
(add-hook 'isearch-mode-hook #'doom|disable-ui-keystrokes)
|
||||
(add-hook 'isearch-mode-end-hook #'doom|enable-ui-keystrokes)
|
||||
|
||||
;; undo/redo changes to Emacs' window layout
|
||||
(def-package! winner
|
||||
:defer doom-before-switch-window-hook
|
||||
:after-call doom-before-switch-window-hook
|
||||
:preface (defvar winner-dont-bind-my-keys t) ; I'll bind keys myself
|
||||
:config (winner-mode +1))
|
||||
|
||||
;; highlight matching delimiters
|
||||
(def-package! paren
|
||||
:defer doom-before-switch-buffer-hook
|
||||
:after-call doom-before-switch-buffer-hook
|
||||
:config
|
||||
(setq show-paren-delay 0.1
|
||||
show-paren-highlight-openparen t
|
||||
|
@ -316,7 +300,7 @@ DEFAULT is non-nil, set the default mode-line for all buffers."
|
|||
(remove-hook 'kill-buffer-query-functions #'server-kill-buffer-query-function))
|
||||
(add-hook 'server-visit-hook #'server-remove-kill-buffer-hook)
|
||||
|
||||
;; whitespace-mode settings
|
||||
;; `whitespace-mode'
|
||||
(setq whitespace-line-column nil
|
||||
whitespace-style
|
||||
'(face indentation tabs tab-mark spaces space-mark newline newline-mark
|
||||
|
@ -371,7 +355,7 @@ from the default."
|
|||
(advice-add #'switch-to-buffer :around #'doom*switch-buffer-hooks)
|
||||
(advice-add #'display-buffer :around #'doom*switch-buffer-hooks)
|
||||
(advice-add #'pop-to-buffer :around #'doom*switch-buffer-hooks))
|
||||
(add-hook 'doom-init-hook #'doom|init-custom-hooks)
|
||||
(add-hook 'doom-post-init-hook #'doom|init-custom-hooks)
|
||||
|
||||
(defun doom*load-theme-hooks (theme &rest _)
|
||||
(setq doom-theme theme)
|
||||
|
@ -704,7 +688,7 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
|||
;;
|
||||
(run-hooks 'doom-init-ui-hook))
|
||||
|
||||
(add-hook 'doom-init-hook #'doom|init-ui)
|
||||
(add-hook 'doom-post-init-hook #'doom|init-ui)
|
||||
|
||||
(provide 'core-ui)
|
||||
;;; core-ui.el ends here
|
||||
|
|
82
core/core.el
82
core/core.el
|
@ -1,5 +1,10 @@
|
|||
;;; core.el --- the heart of the beast -*- lexical-binding: t; -*-
|
||||
|
||||
(eval-when-compile
|
||||
(when (version< emacs-version "25")
|
||||
(error "Doom only supports Emacs 25.1 and higher!")))
|
||||
|
||||
;;
|
||||
(defvar doom-version "2.0.9"
|
||||
"Current version of DOOM emacs.")
|
||||
|
||||
|
@ -15,7 +20,7 @@ line or use --debug-init to enable this.")
|
|||
;;
|
||||
(defvar doom-emacs-dir
|
||||
(eval-when-compile (file-truename user-emacs-directory))
|
||||
"The path to this emacs.d directory.")
|
||||
"The path to this emacs.d directory. Must end in a slash.")
|
||||
|
||||
(defvar doom-core-dir (concat doom-emacs-dir "core/")
|
||||
"Where essential files are stored.")
|
||||
|
@ -44,14 +49,29 @@ Use this for files that change often, like cache files.")
|
|||
|
||||
(defvar doom-private-dir
|
||||
(eval-when-compile
|
||||
(or (let ((xdg-path (concat (or (getenv "XDG_CONFIG_HOME")
|
||||
"~/.config")
|
||||
"/doom/")))
|
||||
(or (let ((xdg-path
|
||||
(expand-file-name "doom/"
|
||||
(or (getenv "XDG_CONFIG_HOME")
|
||||
"~/.config"))))
|
||||
(if (file-directory-p xdg-path) xdg-path))
|
||||
"~/.doom.d/"))
|
||||
"Where your private customizations are placed. Must end in a slash. Respects
|
||||
XDG directory conventions if ~/.config/doom exists.")
|
||||
|
||||
;; Doom hooks
|
||||
(defvar doom-pre-init-hook nil
|
||||
"Hooks run after Doom is first initialized; after Doom's core files are
|
||||
loaded, but before your private init.el file or anything else is loaded.")
|
||||
|
||||
(defvar doom-init-hook nil
|
||||
"Hooks run after all init.el files are loaded, including your private and all
|
||||
module init.el files, but before their config.el files are loaded.")
|
||||
|
||||
(defvar doom-post-init-hook nil
|
||||
"A list of hooks run when Doom is fully initialized. Fires at the end of
|
||||
`emacs-startup-hook', as late as possible. Guaranteed to run after everything
|
||||
else (except for `window-setup-hook').")
|
||||
|
||||
|
||||
;;;
|
||||
;; UTF-8 as the default coding system
|
||||
|
@ -70,6 +90,13 @@ XDG directory conventions if ~/.config/doom exists.")
|
|||
debug-on-error doom-debug-mode
|
||||
ffap-machine-p-known 'reject ; don't ping things that look like domain names
|
||||
idle-update-delay 2 ; update ui less often
|
||||
auto-mode-case-fold nil
|
||||
;; be quiet at startup; don't load or display anything unnecessary
|
||||
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
|
||||
;; keep the point out of the minibuffer
|
||||
minibuffer-prompt-properties '(read-only t point-entered minibuffer-avoid-prompt face minibuffer-prompt)
|
||||
;; History & backup settings (save nothing, that's what git is for)
|
||||
|
@ -93,20 +120,6 @@ XDG directory conventions if ~/.config/doom exists.")
|
|||
url-cache-directory (concat doom-cache-dir "url/")
|
||||
url-configuration-directory (concat doom-etc-dir "url/"))
|
||||
|
||||
;; be quiet at startup; don't load or display anything unnecessary
|
||||
(unless noninteractive
|
||||
(advice-add #'display-startup-echo-area-message :override #'ignore)
|
||||
(setq 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))
|
||||
|
||||
;; Custom init hooks; clearer than `after-init-hook', `emacs-startup-hook', and
|
||||
;; `window-setup-hook'.
|
||||
(defvar doom-init-hook nil
|
||||
"A list of hooks run when DOOM is initialized.")
|
||||
|
||||
|
||||
;;
|
||||
;; Emacs fixes/hacks
|
||||
|
@ -148,9 +161,12 @@ with functions that require it (like modeline segments)."
|
|||
buffer))
|
||||
(advice-add #'make-indirect-buffer :around #'doom*set-indirect-buffer-filename)
|
||||
|
||||
;; Truly silence startup message
|
||||
(fset #'display-startup-echo-area-message #'ignore)
|
||||
|
||||
|
||||
;;
|
||||
;; Bootstrap
|
||||
;; Optimize startup
|
||||
;;
|
||||
|
||||
(defvar doom--file-name-handler-alist file-name-handler-alist)
|
||||
|
@ -167,20 +183,28 @@ with functions that require it (like modeline segments)."
|
|||
"Resets garbage collection settings to reasonable defaults (if you don't do
|
||||
this, you'll get stuttering and random freezes) and resets
|
||||
`file-name-handler-alist'."
|
||||
(unless noninteractive
|
||||
(run-hooks 'doom-init-hook))
|
||||
(setq file-name-handler-alist doom--file-name-handler-alist
|
||||
gc-cons-threshold 16777216
|
||||
gc-cons-percentage 0.15))
|
||||
gc-cons-threshold 8388608
|
||||
gc-cons-percentage 0.1))
|
||||
|
||||
(add-hook 'emacs-startup-hook #'doom|finalize)
|
||||
(add-hook 'doom-reload-hook #'doom|finalize)
|
||||
|
||||
|
||||
;;
|
||||
(require 'core-packages (concat doom-core-dir "core-packages"))
|
||||
(doom-initialize noninteractive)
|
||||
;; Bootstrap Doom
|
||||
;;
|
||||
|
||||
(add-hook! '(emacs-startup-hook doom-reload-hook)
|
||||
#'doom|finalize)
|
||||
(when doom-private-dir
|
||||
(load (concat doom-private-dir "init") t t))
|
||||
(add-to-list 'load-path doom-core-dir)
|
||||
|
||||
(require 'core-lib)
|
||||
(require 'core-packages)
|
||||
(require 'core-os)
|
||||
|
||||
(doom-initialize noninteractive)
|
||||
(if noninteractive
|
||||
(require 'core-dispatcher)
|
||||
(doom-initialize-modules))
|
||||
|
||||
(provide 'core)
|
||||
;;; core.el ends here
|
||||
|
|
|
@ -36,3 +36,6 @@
|
|||
;; core-keybinds.el
|
||||
(package! which-key)
|
||||
(package! hydra)
|
||||
|
||||
;; autoload/debug.el
|
||||
(package! esup)
|
||||
|
|
29
core/templates/BUG_REPORT
Normal file
29
core/templates/BUG_REPORT
Normal file
|
@ -0,0 +1,29 @@
|
|||
Please read through the following before you submit your issue.
|
||||
|
||||
+ [ ] Running `make` (then restarting Emacs) did not fix my issue
|
||||
+ [ ] If I have byte-compiled, I've tried recompiling with `make compile`
|
||||
+ [ ] If I changed the version of Emacs installed, I've recompiled by plugins
|
||||
with `make compile-elpa`
|
||||
+ [ ] I ran `make doctor` and it produced no leads
|
||||
+ [ ] My issue cannot be found [on the wiki](/docs/troubleshoot.org)
|
||||
+ [ ] I filled out the four fields in the template below
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
### Observed behavior
|
||||
|
||||
<!-- What happened -->
|
||||
|
||||
### Expected behavior
|
||||
|
||||
<!-- What *should* have happened -->
|
||||
|
||||
### Steps to reproduce
|
||||
|
||||
<!-- Tell us how to reproduce the issue in steps -->
|
||||
|
||||
### Extra details
|
||||
|
||||
<!-- Include backtraces & screenshots if possible -->
|
||||
|
||||
-------------------------------------------------------------------
|
30
core/templates/QUICKSTART_INTRO
Normal file
30
core/templates/QUICKSTART_INTRO
Normal file
|
@ -0,0 +1,30 @@
|
|||
Before you doom yourself, there are a few things you should know:
|
||||
|
||||
1. If you use GUI Emacs, run `M-x all-the-icons-install-fonts` so you don't get
|
||||
weird symbols all over the place.
|
||||
|
||||
2. When you edit ~/.doom.d/init.el or modify modules, run:
|
||||
|
||||
bin/doom refresh
|
||||
|
||||
This will ensure all needed packages are installed, all orphaned packages are
|
||||
removed, and your autoloads files are up to date. This is important! If you
|
||||
forget to do this you will get errors!
|
||||
|
||||
3. If something inexplicably goes wrong, it's a good idea to try:
|
||||
|
||||
bin/doom doctor
|
||||
|
||||
It will diagnose common issues with your environment and setup, and may give
|
||||
you clues about what is wrong.
|
||||
|
||||
4. To update doom, run
|
||||
|
||||
bin/doom upgrade
|
||||
|
||||
Doing it any other way will require you run `bin/doom refresh` otherwise,
|
||||
|
||||
5. Check out `bin/doom help` to see what else it can do (it is also safe to add
|
||||
~/.emacs.d/bin to your PATH).
|
||||
|
||||
Have fun!
|
7
core/templates/VANILLA_SANDBOX
Normal file
7
core/templates/VANILLA_SANDBOX
Normal file
|
@ -0,0 +1,7 @@
|
|||
;; Welcome to the vanilla sanbox!
|
||||
;;
|
||||
;; This is a test bed for Emacs Lisp to be run in a blank instance of Emacs
|
||||
;; (free of Doom's clutches). This is equivalent to using emacs -Q with
|
||||
;; package.el initialized and nothing else (so you have access to installed
|
||||
;; plugins).
|
||||
|
|
@ -7,7 +7,8 @@
|
|||
(dolist (bsym buffer-args)
|
||||
(push `(,bsym (get-buffer-create ,(symbol-name bsym)))
|
||||
buffers))
|
||||
`(cl-flet ((buffer-list
|
||||
`(save-window-excursion
|
||||
(cl-flet ((buffer-list
|
||||
(lambda ()
|
||||
(cl-remove-if-not #'buffer-live-p (list ,@(reverse (mapcar #'car buffers)))))))
|
||||
(let* ((split-width-threshold 0)
|
||||
|
@ -17,7 +18,7 @@
|
|||
(delete-other-windows)
|
||||
,@body
|
||||
(let (kill-buffer-query-functions kill-buffer-hook)
|
||||
(mapc #'kill-buffer (buffer-list)))))))
|
||||
(mapc #'kill-buffer (buffer-list))))))))
|
||||
|
||||
;;
|
||||
(def-test! get-buffers
|
||||
|
@ -93,7 +94,7 @@
|
|||
(with-temp-buffers!! (a b c d e)
|
||||
(dolist (buf (list a b))
|
||||
(with-current-buffer buf
|
||||
(emacs-lisp-mode)))
|
||||
(delay-mode-hooks (emacs-lisp-mode))))
|
||||
(dolist (buf (list c d e))
|
||||
(with-current-buffer buf
|
||||
(text-mode)))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; core/test/autoload-debug.el
|
||||
;;; core/test/autoload-help.el
|
||||
|
||||
(def-test! what-face
|
||||
(insert (propertize "Hello " 'face 'font-lock-keyword-face))
|
|
@ -10,15 +10,15 @@
|
|||
"[31mHello World[0m"))
|
||||
(should (equal (format! (green "Hello %s" "World"))
|
||||
(format "\e[%dm%s\e[0m"
|
||||
(cdr (assq 'green doom-message-fg))
|
||||
(cadr (assq 'green doom-message-fg))
|
||||
"Hello World")))
|
||||
(should (equal (format! (on-red "Hello %s" "World"))
|
||||
(format "\e[%dm%s\e[0m"
|
||||
(cdr (assq 'on-red doom-message-bg))
|
||||
(cadr (assq 'on-red doom-message-bg))
|
||||
"Hello World")))
|
||||
(should (equal (format! (bold "Hello %s" "World"))
|
||||
(format "\e[%dm%s\e[0m"
|
||||
(cdr (assq 'bold doom-message-fx))
|
||||
(cadr (assq 'bold doom-message-fx))
|
||||
"Hello World")))))
|
||||
|
||||
(def-test! ansi-format-nested
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; core/test/autoload-package.el
|
||||
|
||||
(require 'package)
|
||||
(require 'quelpa)
|
||||
|
||||
(defun -pkg (name version &optional reqs)
|
||||
(package-desc-create :name name :version version :reqs reqs))
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
(def-test! resolve-path-forms
|
||||
(should
|
||||
(equal (doom--resolve-path-forms '(and "fileA" "fileB"))
|
||||
'(and (file-exists-p (expand-file-name "fileA" (doom-project-root)))
|
||||
(file-exists-p (expand-file-name "fileB" (doom-project-root)))))))
|
||||
'(and (file-exists-p (expand-file-name "fileA" nil))
|
||||
(file-exists-p (expand-file-name "fileB" nil))))))
|
||||
|
||||
;; `doom--resolve-hook-forms'
|
||||
(def-test! resolve-hook-forms
|
||||
|
|
|
@ -33,15 +33,15 @@
|
|||
(should (equal (doom-project-expand "init.el")
|
||||
(expand-file-name "init.el" (doom-project-root))))))
|
||||
|
||||
;; `doom-project-has!'
|
||||
;; `project-file-exists-p!'
|
||||
(def-test! project-has!
|
||||
:minor-mode projectile-mode
|
||||
(let ((default-directory doom-core-dir))
|
||||
;; Resolve from project root
|
||||
(should (doom-project-has! "init.el"))
|
||||
(should (project-file-exists-p! "init.el"))
|
||||
;; Chained file checks
|
||||
(should (doom-project-has! (and "init.el" "LICENSE")))
|
||||
(should (doom-project-has! (or "init.el" "does-not-exist")))
|
||||
(should (doom-project-has! (and "init.el" (or "LICENSE" "does-not-exist"))))
|
||||
(should (project-file-exists-p! (and "init.el" "LICENSE")))
|
||||
(should (project-file-exists-p! (or "init.el" "does-not-exist")))
|
||||
(should (project-file-exists-p! (and "init.el" (or "LICENSE" "does-not-exist"))))
|
||||
;; Should resolve relative paths from `default-directory'
|
||||
(should (doom-project-has! (and "./core.el" "../init.el")))))
|
||||
(should (project-file-exists-p! (and "core/core.el" "./init.el")))))
|
||||
|
|
16
debug.el
16
debug.el
|
@ -1,16 +0,0 @@
|
|||
;;; debug.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; To test something in a blank, vanilla Emacs session (Emacs -Q) load me:
|
||||
;;
|
||||
;; emacs -Q -l debug.el
|
||||
|
||||
(setq user-emacs-directory (file-name-directory load-file-name)
|
||||
package--init-file-ensured t
|
||||
package-user-dir (expand-file-name ".local/packages/elpa" user-emacs-directory)
|
||||
package-archives
|
||||
'(("gnu" . "https://elpa.gnu.org/packages/")
|
||||
("melpa" . "https://melpa.org/packages/")
|
||||
("org" . "https://orgmode.org/elpa/")))
|
||||
(package-initialize)
|
||||
|
||||
;; Then you can test packages in isolation here...
|
|
@ -11,7 +11,8 @@
|
|||
|
||||
;; Faster to disable these here (before they've been initialized)
|
||||
(setq tool-bar-mode nil
|
||||
menu-bar-mode nil)
|
||||
(set-scroll-bar-mode nil)
|
||||
menu-bar-mode nil
|
||||
scroll-bar-mode nil)
|
||||
(modify-all-frames-parameters '((vertical-scroll-bars)))
|
||||
|
||||
;; TODO Once Emacs 27 hits stable, perhaps replace init.el with early-init.el
|
||||
|
|
3
init.el
3
init.el
|
@ -27,4 +27,7 @@
|
|||
;;
|
||||
;;; License: MIT
|
||||
|
||||
(setq user-emacs-directory (file-name-directory load-file-name)
|
||||
load-prefer-newer noninteractive)
|
||||
|
||||
(require 'core (concat user-emacs-directory "core/core"))
|
||||
|
|
|
@ -26,9 +26,6 @@
|
|||
+childframe) ; uses childframes for popups (Emacs 26+ only)
|
||||
|
||||
:ui
|
||||
(popup ; tame sudden yet inevitable temporary windows
|
||||
+all ; catch all popups that start with an asterix
|
||||
+defaults) ; default popup rules
|
||||
doom ; what makes DOOM look the way it does
|
||||
doom-dashboard ; a nifty splash screen for Emacs
|
||||
doom-modeline ; a snazzy Atom-inspired mode-line
|
||||
|
@ -37,6 +34,9 @@
|
|||
hl-todo ; highlight TODO/FIXME/NOTE tags
|
||||
nav-flash ; blink the current line after jumping
|
||||
neotree ; a project drawer, like NERDTree for vim
|
||||
(popup ; tame sudden yet inevitable temporary windows
|
||||
+all ; catch all popups that start with an asterix
|
||||
+defaults) ; default popup rules
|
||||
;tabbar ; FIXME an (incomplete) tab bar for Emacs
|
||||
;unicode ; extended unicode support for various languages
|
||||
vi-tilde-fringe ; fringe tildes to mark beyond EOB
|
||||
|
@ -45,69 +45,67 @@
|
|||
:tools
|
||||
dired ; making dired pretty [functional]
|
||||
editorconfig ; let someone else argue about tabs vs spaces
|
||||
ein ; tame Jupyter notebooks with emacs
|
||||
electric-indent ; smarter, keyword-based electric-indent
|
||||
;ein ; tame Jupyter notebooks with emacs
|
||||
eshell ; a consistent, cross-platform shell (WIP)
|
||||
gist ; interacting with github gists
|
||||
;gist ; interacting with github gists
|
||||
imenu ; an imenu sidebar and searchable code index
|
||||
;macos ; MacOS-specific commands
|
||||
make ; run make tasks from Emacs
|
||||
;make ; run make tasks from Emacs
|
||||
;magit ;
|
||||
password-store ; password manager for nerds
|
||||
;password-store ; password manager for nerds
|
||||
pdf ; pdf enhancements
|
||||
prodigy ; Managing external services
|
||||
;prodigy ; FIXME managing external services & code builders
|
||||
;rgb ; creating color strings
|
||||
rotate-text ; cycle region at point between text candidates
|
||||
term ; terminals in Emacs
|
||||
;term ; terminals in Emacs
|
||||
tmux ; an API for interacting with tmux
|
||||
upload ; map local to remote projects via ssh/ftp
|
||||
|
||||
:lang
|
||||
assembly ; assembly for fun or debugging
|
||||
cc ; C/C++/Obj-C madness
|
||||
crystal ; ruby at the speed of c
|
||||
clojure ; java with a lisp
|
||||
csharp ; unity, .NET, and mono shenanigans
|
||||
;assembly ; assembly for fun or debugging
|
||||
;cc ; C/C++/Obj-C madness
|
||||
;crystal ; ruby at the speed of c
|
||||
;clojure ; java with a lisp
|
||||
;csharp ; unity, .NET, and mono shenanigans
|
||||
data ; config/data formats
|
||||
;erlang ; an elegant language for a more civilized age
|
||||
elixir ; erlang done right
|
||||
elm ; care for a cup of TEA?
|
||||
;elixir ; erlang done right
|
||||
;elm ; care for a cup of TEA?
|
||||
emacs-lisp ; drown in parentheses
|
||||
ess ; emacs speaks statistics
|
||||
go ; the hipster dialect
|
||||
(haskell +intero) ; a language that's lazier than I am
|
||||
hy ; readability of scheme w/ speed of python
|
||||
(java +meghanada) ; the poster child for carpal tunnel syndrome
|
||||
javascript ; all(hope(abandon(ye(who(enter(here))))))
|
||||
julia ; a better, faster MATLAB
|
||||
latex ; writing papers in Emacs has never been so fun
|
||||
ledger ; an accounting system in Emacs
|
||||
lua ; one-based indices? one-based indices
|
||||
;ess ; emacs speaks statistics
|
||||
;go ; the hipster dialect
|
||||
;(haskell +intero) ; a language that's lazier than I am
|
||||
;hy ; readability of scheme w/ speed of python
|
||||
;(java +meghanada) ; the poster child for carpal tunnel syndrome
|
||||
;javascript ; all(hope(abandon(ye(who(enter(here))))))
|
||||
;julia ; a better, faster MATLAB
|
||||
;latex ; writing papers in Emacs has never been so fun
|
||||
;ledger ; an accounting system in Emacs
|
||||
;lua ; one-based indices? one-based indices
|
||||
markdown ; writing docs for people to ignore
|
||||
nim ; python + lisp at the speed of c
|
||||
nix ; I hereby declare "nix geht mehr!"
|
||||
ocaml ; an objective camel
|
||||
;nim ; python + lisp at the speed of c
|
||||
;nix ; I hereby declare "nix geht mehr!"
|
||||
;ocaml ; an objective camel
|
||||
(org ; organize your plain life in plain text
|
||||
+attach ; custom attachment system
|
||||
+babel ; running code in org
|
||||
+capture ; org-capture in and outside of Emacs
|
||||
+export ; Exporting org to whatever you want
|
||||
+present ; Emacs for presentations
|
||||
+publish) ; Emacs+Org as a static site generator
|
||||
perl ; write code no one else can comprehend
|
||||
php ; perl's insecure younger brother
|
||||
plantuml ; diagrams for confusing people more
|
||||
purescript ; javascript, but functional
|
||||
python ; beautiful is better than ugly
|
||||
rest ; Emacs as a REST client
|
||||
ruby ; 1.step do {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"}
|
||||
rust ; Fe2O3.unwrap().unwrap().unwrap().unwrap()
|
||||
scala ; java, but good
|
||||
+present) ; Emacs for presentations
|
||||
;perl ; write code no one else can comprehend
|
||||
;php ; perl's insecure younger brother
|
||||
;plantuml ; diagrams for confusing people more
|
||||
;purescript ; javascript, but functional
|
||||
;python ; beautiful is better than ugly
|
||||
;rest ; Emacs as a REST client
|
||||
;ruby ; 1.step do {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"}
|
||||
;rust ; Fe2O3.unwrap().unwrap().unwrap().unwrap()
|
||||
;scala ; java, but good
|
||||
sh ; she sells (ba|z)sh shells on the C xor
|
||||
solidity ; do you need a blockchain? No.
|
||||
swift ; who asked for emoji variables?
|
||||
typescript ; javascript, but better
|
||||
web ; the tubes
|
||||
;solidity ; do you need a blockchain? No.
|
||||
;swift ; who asked for emoji variables?
|
||||
;web ; the tubes
|
||||
|
||||
;; Applications are complex and opinionated modules that transform Emacs
|
||||
;; toward a specific purpose. They may have additional dependencies and
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
|
||||
;;;###autoload
|
||||
(defun +impatient-mode/toggle ()
|
||||
"TODO"
|
||||
"Toggle `impatient-mode' in the current buffer."
|
||||
(interactive)
|
||||
(require 'simple-httpd)
|
||||
(unless (process-status "httpd")
|
||||
(httpd-start))
|
||||
(impatient-mode)
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
;;; collab/impatient-mode/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; Show off code as you write it
|
||||
|
||||
(def-package! impatient-mode
|
||||
:commands impatient-mode)
|
|
@ -24,8 +24,7 @@ MODES should be one major-mode symbol or a list of them."
|
|||
;;
|
||||
|
||||
(def-package! company
|
||||
:commands (company-mode global-company-mode company-complete
|
||||
company-complete-common company-manual-begin company-grab-line)
|
||||
:commands (company-complete-common company-manual-begin company-grab-line)
|
||||
:init
|
||||
(setq company-idle-delay nil
|
||||
company-tooltip-limit 14
|
||||
|
@ -48,7 +47,8 @@ MODES should be one major-mode symbol or a list of them."
|
|||
|
||||
(def-package! company
|
||||
:when (featurep! +auto)
|
||||
:defer pre-command-hook
|
||||
:defer 2
|
||||
:after-call pre-command-hook
|
||||
:config (setq company-idle-delay 0.2))
|
||||
|
||||
|
||||
|
@ -73,27 +73,12 @@ MODES should be one major-mode symbol or a list of them."
|
|||
|
||||
|
||||
(def-package! company-dict
|
||||
:commands company-dict
|
||||
:defer t
|
||||
:config
|
||||
(defun +company|enable-project-dicts (mode &rest _)
|
||||
"Enable per-project dictionaries."
|
||||
(if (symbol-value mode)
|
||||
(cl-pushnew mode company-dict-minor-mode-list :test #'eq)
|
||||
(add-to-list 'company-dict-minor-mode-list mode #'eq)
|
||||
(setq company-dict-minor-mode-list (delq mode company-dict-minor-mode-list))))
|
||||
(add-hook 'doom-project-hook #'+company|enable-project-dicts))
|
||||
|
||||
|
||||
;;
|
||||
;; Included with company.el
|
||||
;;
|
||||
|
||||
(autoload 'company-capf "company-capf")
|
||||
(autoload 'company-dabbrev "company-dabbrev")
|
||||
(autoload 'company-dabbrev-code "company-dabbrev-code")
|
||||
(autoload 'company-elisp "company-elisp")
|
||||
(autoload 'company-etags "company-etags")
|
||||
(autoload 'company-files "company-files")
|
||||
(autoload 'company-gtags "company-gtags")
|
||||
(autoload 'company-ispell "company-ispell")
|
||||
(autoload 'company-yasnippet "company-yasnippet")
|
||||
|
||||
|
|
|
@ -11,7 +11,24 @@
|
|||
;;
|
||||
|
||||
(def-package! helm-mode
|
||||
:defer (pre-command-hook . 1)
|
||||
:defer 1
|
||||
:after-call pre-command-hook
|
||||
:init
|
||||
(map! :map global-map
|
||||
[remap apropos] #'helm-apropos
|
||||
[remap bookmark-jump] #'helm-bookmarks
|
||||
[remap bookmark-jump] #'helm-bookmarks
|
||||
[remap execute-extended-command] #'helm-M-x
|
||||
[remap find-file] #'helm-find-files
|
||||
[remap imenu-anywhere] #'helm-imenu-anywhere
|
||||
[remap imenu-anywhere] #'helm-imenu-anywhere
|
||||
[remap imenu] #'helm-semantic-or-imenu
|
||||
[remap noop-show-kill-ring] #'helm-show-kill-ring
|
||||
[remap projectile-find-file] #'helm-projectile-find-file
|
||||
[remap projectile-recentf] #'helm-projectile-recentf
|
||||
[remap projectile-switch-project] #'helm-projectile-switch-project
|
||||
[remap projectile-switch-to-buffer] #'helm-projectile-switch-to-buffer
|
||||
[remap recentf-open-files] #'helm-recentf)
|
||||
:config
|
||||
(helm-mode +1)
|
||||
;; helm is too heavy for find-file-at-point
|
||||
|
@ -40,7 +57,6 @@
|
|||
helm-move-to-line-cycle-in-source t)
|
||||
|
||||
:config
|
||||
(load "helm-autoloads" nil t)
|
||||
(setq projectile-completion-system 'helm)
|
||||
|
||||
(defvar helm-projectile-find-file-map (make-sparse-keymap))
|
||||
|
@ -72,20 +88,7 @@
|
|||
(setq-local cursor-type nil))))
|
||||
(add-hook 'helm-minibuffer-set-up-hook #'+helm*hide-minibuffer-maybe)
|
||||
|
||||
(map! :map global-map
|
||||
[remap apropos] #'helm-apropos
|
||||
[remap find-file] #'helm-find-files
|
||||
[remap recentf-open-files] #'helm-recentf
|
||||
[remap projectile-switch-to-buffer] #'helm-projectile-switch-to-buffer
|
||||
[remap projectile-recentf] #'helm-projectile-recentf
|
||||
[remap projectile-find-file] #'helm-projectile-find-file
|
||||
[remap imenu] #'helm-semantic-or-imenu
|
||||
[remap bookmark-jump] #'helm-bookmarks
|
||||
[remap noop-show-kill-ring] #'helm-show-kill-ring
|
||||
[remap projectile-switch-project] #'helm-projectile-switch-project
|
||||
[remap projectile-find-file] #'helm-projectile-find-file
|
||||
[remap imenu-anywhere] #'helm-imenu-anywhere
|
||||
[remap execute-extended-command] #'helm-M-x))
|
||||
)
|
||||
|
||||
|
||||
(def-package! helm-locate
|
||||
|
@ -94,40 +97,28 @@
|
|||
:config (set-keymap-parent helm-generic-files-map helm-map))
|
||||
|
||||
|
||||
(def-package! helm-bookmark
|
||||
:commands helm-bookmark
|
||||
:config (setq-default helm-bookmark-show-location t))
|
||||
(after! helm-bookmark
|
||||
(setq-default helm-bookmark-show-location t))
|
||||
|
||||
|
||||
(def-package! helm-files
|
||||
:defer t
|
||||
:config
|
||||
(after! helm-files
|
||||
(setq helm-boring-file-regexp-list
|
||||
(append (list "\\.projects$" "\\.DS_Store$")
|
||||
helm-boring-file-regexp-list)))
|
||||
|
||||
|
||||
(def-package! helm-ag
|
||||
:defer t
|
||||
:config
|
||||
(map! :map helm-ag-edit-map [remap quit-window] #'helm-ag--edit-abort))
|
||||
;; `helm-ag'
|
||||
(map! :after helm-ag
|
||||
:map helm-ag-edit-map [remap quit-window] #'helm-ag--edit-abort)
|
||||
|
||||
|
||||
(def-package! helm-css-scss ; https://github.com/ShingoFukuyama/helm-css-scss
|
||||
:commands (helm-css-scss
|
||||
helm-css-scss-multi
|
||||
helm-css-scss-insert-close-comment)
|
||||
:config
|
||||
(after! helm-css-scss ; https://github.com/ShingoFukuyama/helm-css-scss
|
||||
(setq helm-css-scss-split-direction #'split-window-vertically
|
||||
helm-css-scss-split-with-multiple-windows t))
|
||||
|
||||
|
||||
(def-package! helm-for-files
|
||||
:commands (helm-for-files helm-recentf helm-multi-files))
|
||||
|
||||
|
||||
(def-package! helm-swoop ; https://github.com/ShingoFukuyama/helm-swoop
|
||||
:commands (helm-swoop helm-multi-swoop helm-multi-swoop-all)
|
||||
:commands helm-multi-swoop-all
|
||||
:config
|
||||
(setq helm-swoop-use-line-number-face t
|
||||
helm-swoop-candidate-number-limit 200
|
||||
|
@ -135,9 +126,6 @@
|
|||
helm-swoop-pre-input-function (lambda () "")))
|
||||
|
||||
|
||||
(def-package! helm-describe-modes :commands helm-describe-modes)
|
||||
|
||||
|
||||
(def-package! wgrep
|
||||
:commands (wgrep-setup wgrep-change-to-wgrep-mode)
|
||||
:commands wgrep-change-to-wgrep-mode
|
||||
:config (setq wgrep-auto-save-buffer t))
|
||||
|
|
|
@ -116,7 +116,7 @@ If ARG (universal argument), open selection in other-window."
|
|||
"\\):?\\s-*\\(.+\\)")
|
||||
x)
|
||||
(error
|
||||
(message! (red "Error matching task in file: (%s) %s"
|
||||
(print! (red "Error matching task in file: (%s) %s"
|
||||
(error-message-string ex)
|
||||
(car (split-string x ":"))))
|
||||
nil))
|
||||
|
@ -202,7 +202,6 @@ search current file. See `+ivy-task-tags' to customize what this searches for."
|
|||
;; File searching
|
||||
;;
|
||||
|
||||
(defvar +ivy--file-last-search nil)
|
||||
(defvar +ivy--file-search-recursion-p t)
|
||||
(defvar +ivy--file-search-all-files-p nil)
|
||||
|
||||
|
@ -220,8 +219,7 @@ search current file. See `+ivy-task-tags' to customize what this searches for."
|
|||
(let ((beg (or (bound-and-true-p evil-visual-beginning) (region-beginning)))
|
||||
(end (or (bound-and-true-p evil-visual-end) (region-end))))
|
||||
(when (> (abs (- end beg)) 1)
|
||||
(rxt-quote-pcre (buffer-substring-no-properties beg end)))))
|
||||
+ivy--file-last-search))
|
||||
(rxt-quote-pcre (buffer-substring-no-properties beg end)))))))
|
||||
(prompt
|
||||
(format "%s%%s %s"
|
||||
(symbol-name engine)
|
||||
|
@ -232,7 +230,6 @@ search current file. See `+ivy-task-tags' to customize what this searches for."
|
|||
(t
|
||||
(file-relative-name directory project-root)))))
|
||||
(default-directory directory))
|
||||
(setq +ivy--file-last-search query)
|
||||
(require 'counsel)
|
||||
(cl-letf (((symbol-function 'counsel-ag-function)
|
||||
(symbol-function '+ivy*counsel-ag-function))
|
||||
|
|
|
@ -24,9 +24,10 @@ immediately runs it on the current candidate (ending the ivy session)."
|
|||
;;
|
||||
|
||||
(def-package! ivy
|
||||
:defer (pre-command-hook . 1)
|
||||
:defer 1
|
||||
:after-call pre-command-hook
|
||||
:config
|
||||
(setq ivy-height 12
|
||||
(setq ivy-height 15
|
||||
ivy-do-completion-in-region nil
|
||||
ivy-wrap t
|
||||
ivy-fixed-height-minibuffer t
|
||||
|
@ -141,7 +142,7 @@ immediately runs it on the current candidate (ending the ivy session)."
|
|||
"C-o" #'+ivy@coo/body
|
||||
"M-o" #'ivy-dispatching-done-hydra)
|
||||
:config
|
||||
(def-hydra! +ivy@coo (:hint nil :color pink)
|
||||
(defhydra +ivy@coo (:hint nil :color pink)
|
||||
"
|
||||
Move ^^^^^^^^^^ | Call ^^^^ | Cancel^^ | Options^^ | Action _w_/_s_/_a_: %s(ivy-action-name)
|
||||
----------^^^^^^^^^^-+--------------^^^^-+-------^^-+--------^^-+---------------------------------
|
||||
|
@ -184,7 +185,7 @@ immediately runs it on the current candidate (ending the ivy session)."
|
|||
|
||||
|
||||
(def-package! wgrep
|
||||
:commands (wgrep-setup wgrep-change-to-wgrep-mode)
|
||||
:commands wgrep-change-to-wgrep-mode
|
||||
:config (setq wgrep-auto-save-buffer t))
|
||||
|
||||
|
||||
|
|
|
@ -197,8 +197,10 @@
|
|||
:desc "Magit status" :n "g" #'magit-status
|
||||
:desc "List gists" :n "G" #'+gist:list
|
||||
:desc "Initialize repo" :n "i" #'magit-init
|
||||
:desc "Browse issues tracker" :n "I" #'+vcs/git-browse-issues
|
||||
:desc "Magit buffer log" :n "l" #'magit-log-buffer-file
|
||||
:desc "List repositories" :n "L" #'magit-list-repositories
|
||||
:desc "Browse remote" :n "o" #'+vcs/git-browse
|
||||
:desc "Magit push popup" :n "p" #'magit-push-popup
|
||||
:desc "Magit pull popup" :n "P" #'magit-pull-popup
|
||||
:desc "Git revert hunk" :n "r" #'git-gutter:revert-hunk
|
||||
|
@ -213,9 +215,11 @@
|
|||
(:desc "help" :prefix "h"
|
||||
:n "h" help-map
|
||||
:desc "Apropos" :n "a" #'apropos
|
||||
:desc "Open Bug Report" :n "b" #'doom/open-bug-report
|
||||
:desc "Describe char" :n "c" #'describe-char
|
||||
:desc "Describe DOOM module" :n "d" #'doom/describe-module
|
||||
:desc "Open Doom manual" :n "D" #'doom/help
|
||||
:desc "Open Doom manual" :n "D" #'doom//open-manual
|
||||
:desc "Open vanilla sandbox" :n "E" #'doom/open-vanilla-sandbox
|
||||
:desc "Describe function" :n "f" #'describe-function
|
||||
:desc "Describe face" :n "F" #'describe-face
|
||||
:desc "Info" :n "i" #'info-lookup-symbol
|
||||
|
@ -233,7 +237,7 @@
|
|||
:desc "Print Doom version" :n "V" #'doom/version
|
||||
:desc "Describe at point" :n "." #'helpful-at-point
|
||||
:desc "What face" :n "'" #'doom/what-face
|
||||
:desc "What minor modes" :n ";" #'doom/what-minor-mode)
|
||||
:desc "What minor modes" :n ";" #'doom/describe-active-minor-mode)
|
||||
|
||||
(:desc "insert" :prefix "i"
|
||||
:desc "From kill-ring" :nv "y" #'counsel-yank-pop
|
||||
|
@ -251,7 +255,7 @@
|
|||
:desc "REPL" :n "r" #'+eval/open-repl
|
||||
:v "r" #'+eval:repl
|
||||
:desc "Neotree" :n "n" #'+neotree/open
|
||||
:desc "Neotree: on this file" :n "N" #'+neotree/find-this-file
|
||||
:desc "Neotree: find file" :n "N" #'+neotree/find-this-file
|
||||
:desc "Imenu sidebar" :nv "i" #'imenu-list-smart-toggle
|
||||
:desc "Terminal" :n "t" #'+term/open-popup-in-project
|
||||
|
||||
|
@ -295,11 +299,13 @@
|
|||
:desc "Browse remote files" :n "." #'ssh-deploy-browse-remote-handler
|
||||
:desc "Detect remote changes" :n ">" #'ssh-deploy-remote-changes-handler))
|
||||
|
||||
(:when (featurep! :feature snippets)
|
||||
(:desc "snippets" :prefix "s"
|
||||
:desc "New snippet" :n "n" #'yas-new-snippet
|
||||
:desc "Insert snippet" :nv "i" #'yas-insert-snippet
|
||||
:desc "Find snippet for mode" :n "s" #'yas-visit-snippet-file
|
||||
:desc "Find snippet" :n "S" #'+default/find-in-snippets)
|
||||
:desc "Find snippet" :n "s" #'+default/find-in-snippets
|
||||
:desc "Find snippet for mode" :n "S" #'+default/browse-snippets
|
||||
:desc "Find global snippet" :n "/" #'yas-visit-snippet-file))
|
||||
|
||||
(:desc "toggle" :prefix "t"
|
||||
:desc "Flyspell" :n "s" #'flyspell-mode
|
||||
|
@ -387,11 +393,12 @@
|
|||
[escape] #'company-search-abort))
|
||||
|
||||
;; counsel
|
||||
(:when (featurep! :completion ivy)
|
||||
(:after counsel
|
||||
(:map counsel-ag-map
|
||||
[backtab] #'+ivy/wgrep-occur ; search/replace on results
|
||||
"C-SPC" #'ivy-call-and-recenter ; preview
|
||||
"M-RET" (+ivy-do-action! #'+ivy-git-grep-other-window-action)))
|
||||
"M-RET" (+ivy-do-action! #'+ivy-git-grep-other-window-action))))
|
||||
|
||||
;; easymotion
|
||||
:m "gs" #'+default/easymotion ; lazy-load `evil-easymotion'
|
||||
|
@ -766,14 +773,16 @@
|
|||
;; Evil-collection fixes
|
||||
;;
|
||||
|
||||
(when (featurep 'evil-collection)
|
||||
(defun +config|deal-with-evil-collections-bs (_feature keymaps)
|
||||
"Unmap keys that conflict with Doom's defaults."
|
||||
(dolist (map keymaps)
|
||||
(evil-define-key '(normal visual motion) map
|
||||
doom-leader-key nil
|
||||
"C-j" nil "C-k" nil
|
||||
"gd" nil "gf" nil
|
||||
"K" nil
|
||||
"]" nil "[" nil)))
|
||||
(add-hook 'evil-collection-setup-hook #'+config|deal-with-evil-collections-bs))
|
||||
(evil-delay `(and (boundp ',map) (keymapp ,map))
|
||||
`(evil-define-key* '(normal visual motion) ,map
|
||||
(kbd doom-leader-key) nil
|
||||
(kbd "C-j") nil (kbd "C-k") nil
|
||||
"gd" nil "gf" nil "K" nil
|
||||
"]" nil "[" nil)
|
||||
'after-load-functions t nil
|
||||
(format "+default-redefine-key-in-%s" map))))
|
||||
|
||||
(add-hook 'evil-collection-setup-hook #'+config|deal-with-evil-collections-bs)
|
||||
|
|
|
@ -36,8 +36,10 @@
|
|||
|
||||
;;;###autoload
|
||||
(defun +default/browse-snippets ()
|
||||
(interactive) (doom-project-browse emacs-snippets-dir))
|
||||
;; NOTE No need for a browse-snippets variant, use `yas-visit-snippet-file'
|
||||
(interactive) (doom-project-browse +snippets-dir))
|
||||
;;;###autoload
|
||||
(defun +default/find-in-snippets ()
|
||||
(interactive) (doom-project-find-file +snippets-dir))
|
||||
|
||||
;;;###autoload
|
||||
(defun +default/find-in-config ()
|
||||
|
|
|
@ -35,6 +35,15 @@
|
|||
(sp-pair "'" nil :unless unless-list)
|
||||
(sp-pair "\"" nil :unless unless-list))
|
||||
|
||||
;; Major-mode specific fixes
|
||||
(sp-local-pair 'ruby-mode "{" "}"
|
||||
:pre-handlers '(:rem sp-ruby-prehandler)
|
||||
:post-handlers '(:rem sp-ruby-posthandler))
|
||||
;; sp's default rules for these modes are obnoxious, so disable them
|
||||
(provide 'smartparens-latex)
|
||||
(provide 'smartparens-elixir)
|
||||
(provide 'smartparens-lua)
|
||||
|
||||
;; Expand {|} => { | }
|
||||
;; Expand {|} => {
|
||||
;; |
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
(def-package! realgud
|
||||
:commands (realgud:gdb realgud:trepanjs realgud:bashdb realgud:zshdb)
|
||||
:config
|
||||
(set! :popup "^\\*\\(?trepanjs:\\(?:g\\|zsh\\|bash\\)db\\)" '((size . 20)))
|
||||
(set! :popup "^\\*\\(?trepanjs:\\(?:g\\|zsh\\|bash\\)db\\)"
|
||||
'((size . 20)))
|
||||
|
||||
;; TODO Temporary Ex commands for the debugger
|
||||
;; (def-tmp-excmd! doom:def-debug-on doom:def-debug-off
|
||||
|
|
|
@ -10,12 +10,7 @@
|
|||
;;
|
||||
|
||||
(def-package! quickrun
|
||||
:commands (quickrun
|
||||
quickrun-region
|
||||
quickrun-with-arg
|
||||
quickrun-shell
|
||||
quickrun-compile-only
|
||||
quickrun-replace-region)
|
||||
:defer t
|
||||
:init
|
||||
(unless (boundp 'display-line-numbers)
|
||||
(add-hook 'quickrun--mode-hook #'nlinum-mode))
|
||||
|
|
|
@ -1,6 +1,21 @@
|
|||
;; feature/evil/autoload/evil.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! :feature evil)
|
||||
|
||||
;;;###autoload
|
||||
(def-setting! :evil-state (modes state)
|
||||
"Set the initialize STATE of MODE using `evil-set-initial-state'."
|
||||
(let ((unquoted-modes (doom-unquote modes)))
|
||||
(if (listp unquoted-modes)
|
||||
`(progn
|
||||
,@(cl-loop for mode in unquoted-modes
|
||||
collect `(evil-set-initial-state ',mode ,state)))
|
||||
`(evil-set-initial-state ,modes ,state))))
|
||||
|
||||
|
||||
;;
|
||||
;; Commands
|
||||
;;
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil/visual-indent ()
|
||||
"vnoremap < <gv"
|
||||
|
@ -80,6 +95,11 @@ evil-window-move-* (e.g. `evil-window-move-far-left')"
|
|||
;;;###autoload
|
||||
(defun +evil/window-move-down () "See `+evil--window-swap'" (interactive) (+evil--window-swap 'down))
|
||||
|
||||
|
||||
;;
|
||||
;; Evil commands/operators
|
||||
;;
|
||||
|
||||
;;;###autoload (autoload '+evil:apply-macro "feature/evil/autoload/evil" nil t)
|
||||
(evil-define-operator +evil:apply-macro (beg end)
|
||||
"Apply macro to each line."
|
||||
|
|
|
@ -3,27 +3,10 @@
|
|||
;; I'm a vimmer at heart. Its modal philosophy suits me better, and this module
|
||||
;; strives to make Emacs a much better vim than vim was.
|
||||
|
||||
(def-setting! :evil-state (modes state)
|
||||
"Set the initialize STATE of MODE using `evil-set-initial-state'."
|
||||
(let ((unquoted-modes (doom-unquote modes)))
|
||||
(if (listp unquoted-modes)
|
||||
`(progn
|
||||
,@(cl-loop for mode in unquoted-modes
|
||||
collect `(evil-set-initial-state ',mode ,state)))
|
||||
`(evil-set-initial-state ,modes ,state))))
|
||||
|
||||
|
||||
;;
|
||||
;; evil-mode
|
||||
;;
|
||||
|
||||
(autoload 'goto-last-change "goto-chg")
|
||||
(autoload 'goto-last-change-reverse "goto-chg")
|
||||
|
||||
|
||||
(def-package! evil-collection
|
||||
:when (featurep! +everywhere)
|
||||
:defer pre-command-hook
|
||||
:defer 1
|
||||
:after-call post-command-hook
|
||||
:preface
|
||||
;; must be set before evil/evil-collcetion is loaded
|
||||
(setq evil-want-integration nil
|
||||
|
@ -61,7 +44,7 @@
|
|||
evil-visual-state-cursor 'hollow)
|
||||
|
||||
:config
|
||||
(add-hook 'doom-init-hook #'evil-mode)
|
||||
(add-hook 'doom-post-init-hook #'evil-mode)
|
||||
(evil-select-search-module 'evil-search-module 'evil-search)
|
||||
|
||||
(set! :popup "^\\*evil-registers" '((size . 0.3)))
|
||||
|
@ -235,7 +218,7 @@
|
|||
evil-escape-excluded-major-modes '(neotree-mode)
|
||||
evil-escape-key-sequence "jk"
|
||||
evil-escape-delay 0.25)
|
||||
(add-hook 'pre-command-hook 'evil-escape-pre-command-hook)
|
||||
(add-hook 'pre-command-hook #'evil-escape-pre-command-hook)
|
||||
(map! :irvo "C-g" #'evil-escape)
|
||||
:config
|
||||
;; no `evil-escape' in minibuffer
|
||||
|
@ -325,7 +308,7 @@ the new algorithm is confusing, like in python or ruby."
|
|||
(def-package! evil-snipe
|
||||
:commands (evil-snipe-mode evil-snipe-override-mode
|
||||
evil-snipe-local-mode evil-snipe-override-local-mode)
|
||||
:defer pre-command-hook
|
||||
:after-call pre-command-hook
|
||||
:init
|
||||
(setq evil-snipe-smart-case t
|
||||
evil-snipe-scope 'line
|
||||
|
@ -385,19 +368,6 @@ the new algorithm is confusing, like in python or ruby."
|
|||
(push ">" evil-args-closers)))
|
||||
|
||||
|
||||
(def-package! evil-indent-plus
|
||||
:commands (evil-indent-plus-i-indent
|
||||
evil-indent-plus-a-indent
|
||||
evil-indent-plus-i-indent-up
|
||||
evil-indent-plus-a-indent-up
|
||||
evil-indent-plus-i-indent-up-down
|
||||
evil-indent-plus-a-indent-up-down))
|
||||
|
||||
|
||||
(def-package! evil-textobj-anyblock
|
||||
:commands (evil-textobj-anyblock-inner-block evil-textobj-anyblock-a-block))
|
||||
|
||||
|
||||
;;
|
||||
;; Multiple cursors compatibility (for the plugins that use it)
|
||||
;;
|
||||
|
|
|
@ -66,8 +66,12 @@ evil is loaded and enabled)."
|
|||
;;;###autoload
|
||||
(defun +file-templates-get-short-path ()
|
||||
"Fetches a short file path for the header in Doom module templates."
|
||||
(when (string-match "/modules/\\(.+\\)$" buffer-file-truename)
|
||||
(match-string 1 buffer-file-truename)))
|
||||
(let ((path (file-truename (or buffer-file-name default-directory))))
|
||||
(cond ((string-match "/modules/\\(.+\\)$" path)
|
||||
(match-string 1 path))
|
||||
((file-in-directory-p path doom-emacs-dir)
|
||||
(file-relative-name path doom-emacs-dir))
|
||||
((abbreviate-file-name path)))))
|
||||
|
||||
|
||||
;;
|
||||
|
|
|
@ -6,55 +6,11 @@
|
|||
(expand-file-name "templates/" (file-name-directory load-file-name))
|
||||
"The path to a directory of yasnippet folders to use for file templates.")
|
||||
|
||||
(defvar +file-templates-alist ()
|
||||
"An alist of file template rules. The CAR of each rule is either a major mode
|
||||
symbol or regexp string. The CDR is a plist. See `doom--set:file-template' for
|
||||
more information.")
|
||||
|
||||
(defvar +file-templates-default-trigger "__"
|
||||
"The default yasnippet trigger key (a string) for file template rules that
|
||||
don't have a :trigger property in `+file-templates-alist'.")
|
||||
|
||||
|
||||
;;
|
||||
;; Bootstrap
|
||||
;;
|
||||
|
||||
(after! yasnippet
|
||||
(add-to-list 'yas-snippet-dirs '+file-templates-dir 'append #'eq))
|
||||
|
||||
(defun +file-template-p (rule)
|
||||
"Return t if RULE applies to the current buffer."
|
||||
(let ((pred (car rule))
|
||||
(plist (cdr rule)))
|
||||
(and (cond ((stringp pred) (string-match-p pred))
|
||||
((symbolp pred) (eq major-mode pred)))
|
||||
(or (not (plist-member plist :when))
|
||||
(funcall (plist-get plist :when) buffer-file-name))
|
||||
rule)))
|
||||
|
||||
(defun +file-templates|init ()
|
||||
"Check if the current buffer is a candidate for file template expansion. It
|
||||
must be non-read-only, empty, and there must be a rule in
|
||||
`+file-templates-alist' that applies to it."
|
||||
(when (and (not buffer-read-only)
|
||||
(bobp) (eobp))
|
||||
(when-let* ((rule (cl-find-if #'+file-template-p +file-templates-alist)))
|
||||
(apply #'+file-templates--expand rule))))
|
||||
|
||||
(add-hook 'find-file-hook #'+file-templates|init)
|
||||
|
||||
|
||||
;;
|
||||
;; File templates
|
||||
;;
|
||||
|
||||
(defun +file-templates-in-emacs-dirs-p (file)
|
||||
"Returns t if FILE is in Doom or your private directory."
|
||||
(or (file-in-directory-p file doom-private-dir)
|
||||
(file-in-directory-p file doom-emacs-dir)))
|
||||
|
||||
(setq +file-templates-alist
|
||||
(defvar +file-templates-alist
|
||||
`(;; General
|
||||
(gitignore-mode)
|
||||
(dockerfile-mode)
|
||||
|
@ -137,11 +93,50 @@ must be non-read-only, empty, and there must be a rule in
|
|||
;; Shell scripts
|
||||
("\\.zunit$" :trigger "__zunit" :mode sh-mode)
|
||||
(fish-mode)
|
||||
(sh-mode)
|
||||
))
|
||||
(sh-mode))
|
||||
"An alist of file template rules. The CAR of each rule is either a major mode
|
||||
symbol or regexp string. The CDR is a plist. See `doom--set:file-template' for
|
||||
more information.")
|
||||
|
||||
|
||||
;;
|
||||
;; Plugins
|
||||
;; Library
|
||||
;;
|
||||
|
||||
(defun +file-template-p (rule)
|
||||
"Return t if RULE applies to the current buffer."
|
||||
(let ((pred (car rule))
|
||||
(plist (cdr rule)))
|
||||
(and (cond ((and (stringp pred) buffer-file-name) (string-match-p pred buffer-file-name))
|
||||
((symbolp pred) (eq major-mode pred)))
|
||||
(or (not (plist-member plist :when))
|
||||
(funcall (plist-get plist :when) buffer-file-name))
|
||||
rule)))
|
||||
|
||||
(defun +file-templates-in-emacs-dirs-p (file)
|
||||
"Returns t if FILE is in Doom or your private directory."
|
||||
(or (file-in-directory-p file doom-private-dir)
|
||||
(file-in-directory-p file doom-emacs-dir)))
|
||||
|
||||
(defun +file-templates|check ()
|
||||
"Check if the current buffer is a candidate for file template expansion. It
|
||||
must be non-read-only, empty, and there must be a rule in
|
||||
`+file-templates-alist' that applies to it."
|
||||
(when (and (not buffer-read-only)
|
||||
(bobp) (eobp)
|
||||
(not (string-match-p "^ *\\*" (buffer-name))))
|
||||
(when-let* ((rule (cl-find-if #'+file-template-p +file-templates-alist)))
|
||||
(apply #'+file-templates--expand rule))))
|
||||
|
||||
|
||||
;;
|
||||
;; Bootstrap
|
||||
;;
|
||||
|
||||
(defun +file-templates|init ()
|
||||
(after! yasnippet
|
||||
(add-to-list 'yas-snippet-dirs '+file-templates-dir 'append #'eq))
|
||||
(add-hook 'find-file-hook #'+file-templates|check))
|
||||
|
||||
(add-hook 'doom-post-init-hook #'+file-templates|init)
|
||||
|
||||
|
|
|
@ -11,10 +11,9 @@ ${2:A short summary about what this module does.}
|
|||
|
||||
${3:If necessary, include a longer description below it that goes into more detail. This may be as long as you like.
|
||||
|
||||
+ If possible, include a list of features
|
||||
+ Include links to major plugins that the module uses, if applicable
|
||||
+ Use links whenever you can
|
||||
+ Mention dependencies on other modules here}
|
||||
+ If possible, include a brief list of feature highlights here
|
||||
+ Like code completion, syntax checking or available snippets
|
||||
+ Include links to packages & external things where possible
|
||||
|
||||
* Table of Contents :TOC:
|
||||
|
||||
|
@ -25,11 +24,15 @@ This module provides no flags.
|
|||
This module has no prereqisites.
|
||||
|
||||
* Features
|
||||
A list of features, how to use them, and their dependencies.
|
||||
An in-depth list of features, how to use them, and their dependencies.
|
||||
|
||||
* Configuration
|
||||
How to configure this module, including common problems and how to address them.
|
||||
|
||||
* Appendix
|
||||
** Commands
|
||||
+ A list or table of public commands (and their keybinds) and functions that this module exposes.
|
||||
+ A brief description of how to use them
|
||||
** Hacks
|
||||
+ Include a list of ways this module changes default behavior
|
||||
$0
|
11
modules/feature/lookup/autoload/devdocs.el
Normal file
11
modules/feature/lookup/autoload/devdocs.el
Normal file
|
@ -0,0 +1,11 @@
|
|||
;;; feature/lookup/autoload/devdocs.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! +devdocs)
|
||||
|
||||
;;;###autoload
|
||||
(def-setting! :devdocs (modes docset)
|
||||
"Map major MODES (one major-mode symbol or a list of them) to a devdocs
|
||||
DOCSET (a string).
|
||||
|
||||
See `devdocs-alist' for the defaults. "
|
||||
`(dolist (mode ',modes)
|
||||
(push (cons mode ,docset) devdocs-alist)))
|
40
modules/feature/lookup/autoload/docsets.el
Normal file
40
modules/feature/lookup/autoload/docsets.el
Normal file
|
@ -0,0 +1,40 @@
|
|||
;;; feature/lookup/autoload/docsets.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! +docsets)
|
||||
|
||||
;;;###autoload
|
||||
(def-setting! :docset (modes &rest docsets)
|
||||
"Registers a list of DOCSETS (strings) for MODES (either one major mode
|
||||
symbol or a list of them).
|
||||
|
||||
If MODES is a minor mode, you can use :add or :remove as the first element of
|
||||
DOCSETS, to instruct it to append (or remove) those from the docsets already set
|
||||
by a major-mode, if any.
|
||||
|
||||
Used by `+lookup/in-docsets' and `+lookup/documentation'."
|
||||
(let* ((modes (doom-unquote modes))
|
||||
(ivy-p (featurep! :completion ivy))
|
||||
(hook-sym (intern (format "+lookup|%s-docsets--%s"
|
||||
(cond ((eq ',(car docsets) :add) 'add)
|
||||
((eq ',(car docsets) :remove) 'remove)
|
||||
('set))
|
||||
(string-join docsets "-"))))
|
||||
(var-sym (if ivy-p 'counsel-dash-docsets 'helm-dash-docsets)))
|
||||
`(progn
|
||||
(defun ,hook-sym ()
|
||||
(make-variable-buffer-local ',var-sym)
|
||||
,(cond ((eq ',(car docsets) :add)
|
||||
`(setq ,var-sym (append ,var-sym (list ,@(cdr docsets)))))
|
||||
((eq ',(car docsets) :remove)
|
||||
`(setq ,var-sym
|
||||
(cl-loop with to-delete = (list ,@(cdr docsets))
|
||||
for docset in ,var-sym
|
||||
unless (member docset to-delete)
|
||||
collect docset)))
|
||||
(`(setq ,var-sym (list ,@docsets)))))
|
||||
(add-hook! ,modes #',hook-sym))))
|
||||
|
||||
;;;###autoload
|
||||
(autoload 'helm-dash-installed-docsets "helm-dash")
|
||||
|
||||
;;;###autoload
|
||||
(autoload 'helm-dash-docset-installed-p "helm-dash")
|
|
@ -160,6 +160,7 @@ Goes down a list of possible backends:
|
|||
identifier
|
||||
(+lookup--online-provider (not current-prefix-arg))))))
|
||||
|
||||
(defvar ffap-file-finder)
|
||||
;;;###autoload
|
||||
(defun +lookup/file (path)
|
||||
"Figure out PATH from whatever is at point and open it.
|
||||
|
|
|
@ -122,33 +122,29 @@ ones."
|
|||
;;
|
||||
|
||||
(def-package! dumb-jump
|
||||
:commands (dumb-jump-go dumb-jump-quick-look
|
||||
dumb-jump-back dumb-jump-result-follow)
|
||||
:commands dumb-jump-result-follow
|
||||
:config
|
||||
(setq dumb-jump-default-project doom-emacs-dir
|
||||
dumb-jump-aggressive nil
|
||||
dumb-jump-selector
|
||||
(cond ((featurep! :completion ivy) 'ivy)
|
||||
((featurep! :completion helm) 'helm)
|
||||
(t 'popup))))
|
||||
('popup))))
|
||||
|
||||
|
||||
;;
|
||||
;; xref
|
||||
;;
|
||||
|
||||
(def-package! xref
|
||||
:commands (xref-backend-identifier-at-point xref-find-definitions xref-find-references)
|
||||
:config
|
||||
;; By default, `etags--xref-backend' is the default xref backend. No need.
|
||||
;; We'll set these up ourselves in other modules.
|
||||
;; By default, `etags--xref-backend' is the default xref backend. No need. We'll
|
||||
;; set these up ourselves in other modules.
|
||||
(setq-default xref-backend-functions '(t))
|
||||
|
||||
;; ...however, it breaks `projectile-find-tag', unless we put it back.
|
||||
(defun +lookup*projectile-find-tag (orig-fn)
|
||||
(let ((xref-backend-functions '(etags--xref-backend t)))
|
||||
(funcall orig-fn)))
|
||||
(advice-add #'projectile-find-tag :around #'+lookup*projectile-find-tag))
|
||||
(advice-add #'projectile-find-tag :around #'+lookup*projectile-find-tag)
|
||||
|
||||
|
||||
(def-package! ivy-xref
|
||||
|
@ -168,41 +164,9 @@ ones."
|
|||
;;
|
||||
|
||||
(when (featurep! +docsets)
|
||||
(def-setting! :docset (modes &rest docsets)
|
||||
"Registers a list of DOCSETS (strings) for MODES (either one major mode
|
||||
symbol or a list of them).
|
||||
|
||||
If MODES is a minor mode, you can use :add or :remove as the first element of
|
||||
DOCSETS, to instruct it to append (or remove) those from the docsets already set
|
||||
by a major-mode, if any.
|
||||
|
||||
Used by `+lookup/in-docsets' and `+lookup/documentation'."
|
||||
(let* ((modes (doom-unquote modes))
|
||||
(ivy-p (featurep! :completion ivy))
|
||||
(hook-sym (intern (format "+lookup|%s-docsets--%s"
|
||||
(cond ((eq ',(car docsets) :add) 'add)
|
||||
((eq ',(car docsets) :remove) 'remove)
|
||||
('set))
|
||||
(string-join docsets "-"))))
|
||||
(var-sym (if ivy-p 'counsel-dash-docsets 'helm-dash-docsets)))
|
||||
`(progn
|
||||
(defun ,hook-sym ()
|
||||
(make-variable-buffer-local ',var-sym)
|
||||
,(cond ((eq ',(car docsets) :add)
|
||||
`(setq ,var-sym (append ,var-sym (list ,@(cdr docsets)))))
|
||||
((eq ',(car docsets) :remove)
|
||||
`(setq ,var-sym
|
||||
(cl-loop with to-delete = (list ,@(cdr docsets))
|
||||
for docset in ,var-sym
|
||||
unless (member docset to-delete)
|
||||
collect docset)))
|
||||
(`(setq ,var-sym (list ,@docsets)))))
|
||||
(add-hook! ,modes #',hook-sym))))
|
||||
|
||||
;; Both packages depend on helm-dash
|
||||
(def-package! helm-dash
|
||||
:commands (helm-dash helm-dash-install-docset helm-dash-at-point
|
||||
helm-dash-docset-installed-p helm-dash-installed-docsets)
|
||||
:defer t
|
||||
:init
|
||||
(setq helm-dash-enable-debugging doom-debug-mode
|
||||
helm-dash-browser-func #'eww)
|
||||
|
@ -214,7 +178,7 @@ Used by `+lookup/in-docsets' and `+lookup/documentation'."
|
|||
|
||||
(def-package! counsel-dash
|
||||
:when (featurep! :completion ivy)
|
||||
:commands (counsel-dash counsel-dash-install-docset)
|
||||
:commands counsel-dash-install-docset
|
||||
:config (setq counsel-dash-min-length 2)))
|
||||
|
||||
|
||||
|
@ -223,20 +187,11 @@ Used by `+lookup/in-docsets' and `+lookup/documentation'."
|
|||
;;
|
||||
|
||||
(when (featurep! +devdocs)
|
||||
(def-setting! :devdocs (modes docset)
|
||||
"Map major MODES (one major-mode symbol or a list of them) to a devdocs
|
||||
DOCSET (a string).
|
||||
|
||||
See `devdocs-alist' for the defaults. "
|
||||
`(dolist (mode ',modes)
|
||||
(push (cons mode ,docset) devdocs-alist)))
|
||||
|
||||
(def-package! devdocs-lookup
|
||||
:commands (devdocs-setup devdocs-lookup)
|
||||
:config
|
||||
(after! devdocs-lookup
|
||||
(unless (assoc "SCSS" devdocs-subjects)
|
||||
(setq devdocs-subjects
|
||||
(append '(("SCSS" "scss")
|
||||
("GFM" "markdown")
|
||||
("Typescript" "typescript"))
|
||||
devdocs-subjects))))
|
||||
devdocs-subjects)))))
|
||||
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
;;; feature/snippets/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +snippets-dir (expand-file-name "snippets/" doom-private-dir)
|
||||
"Directory where `yasnippet' will search for your private snippets.")
|
||||
|
||||
|
||||
;;
|
||||
;; Plugins
|
||||
;;
|
||||
|
||||
(def-package! yasnippet
|
||||
:commands (yas-minor-mode yas-minor-mode-on yas-expand yas-expand-snippet
|
||||
yas-lookup-snippet yas-insert-snippet yas-new-snippet
|
||||
yas-visit-snippet-file snippet-mode)
|
||||
:commands (yas-minor-mode-on yas-expand yas-expand-snippet yas-lookup-snippet
|
||||
yas-insert-snippet yas-new-snippet yas-visit-snippet-file)
|
||||
:preface
|
||||
(defvar yas-minor-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
|
@ -23,28 +30,25 @@
|
|||
(setq yas-verbosity (if doom-debug-mode 3 0)
|
||||
yas-also-auto-indent-first-line t
|
||||
yas-prompt-functions (delq #'yas-dropdown-prompt yas-prompt-functions)
|
||||
;; Allow nested snippets
|
||||
yas-triggers-in-field t)
|
||||
yas-triggers-in-field t) ; Allow nested snippets
|
||||
|
||||
(cl-pushnew (expand-file-name "snippets/" doom-private-dir) yas-snippet-dirs
|
||||
:test #'string=)
|
||||
(add-to-list 'yas-snippet-dirs '+snippets-dir nil #'eq)
|
||||
|
||||
(defun +snippets|enable-project-modes (mode &rest _)
|
||||
"Enable snippets for project modes."
|
||||
"Automatically enable snippet libraries for project minor modes defined with
|
||||
`def-project-mode!'."
|
||||
(if (symbol-value mode)
|
||||
(yas-activate-extra-mode mode)
|
||||
(yas-deactivate-extra-mode mode)))
|
||||
(add-hook 'doom-project-hook #'+snippets|enable-project-modes)
|
||||
|
||||
;; fix an error caused by smartparens interfering with yasnippet bindings
|
||||
(advice-add #'yas-expand :before #'sp-remove-active-pair-overlay)
|
||||
|
||||
;; Exit snippets on ESC from normal mode
|
||||
(add-hook 'doom-escape-hook #'yas-abort-snippet))
|
||||
(add-hook 'doom-escape-hook #'yas-abort-snippet)
|
||||
|
||||
(after! smartparens
|
||||
;; fix an error caused by smartparens interfering with yasnippet bindings
|
||||
(advice-add #'yas-expand :before #'sp-remove-active-pair-overlay)))
|
||||
|
||||
|
||||
(def-package! auto-yasnippet
|
||||
:commands (aya-create aya-expand aya-open-line aya-persist-snippet)
|
||||
:config
|
||||
(after! auto-yasnippet
|
||||
(setq aya-persist-snippets-dir (concat doom-local-dir "auto-snippets/")))
|
||||
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; feature/snippets/doctor.el
|
||||
|
||||
(require 'yasnippet)
|
||||
(unless (ignore-errors (yas-reload-all)
|
||||
(yas--get-snippet-tables))
|
||||
(warn! "Couldn't find any snippets in any of these directories: %s" yas-snippet-dirs))
|
|
@ -8,7 +8,7 @@ Since spellchecking can be slow in some buffers, this can be disabled with:
|
|||
(setq-hook! 'LaTeX-mode-hook +spellcheck-immediately nil)")
|
||||
|
||||
(def-package! flyspell ; built-in
|
||||
:commands flyspell-mode
|
||||
:defer t
|
||||
:init
|
||||
(add-hook 'flyspell-mode-hook #'+spellcheck|immediately)
|
||||
:config
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; feature/spellcheck/packages.el
|
||||
|
||||
(package! flyspell-correct)
|
||||
(when (package! flyspell-correct)
|
||||
(cond ((featurep! :completion ivy)
|
||||
(package! flyspell-correct-ivy))
|
||||
((featurep! :completion helm)
|
||||
(package! flyspell-correct-helm))
|
||||
(t
|
||||
(package! flyspell-correct-popup)))
|
||||
(package! flyspell-correct-popup))))
|
||||
|
||||
|
|
|
@ -1,18 +1,11 @@
|
|||
;;; feature/syntax-checker/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; Since Doom doesn't use `package-initialize', pkg-info won't get autoloaded
|
||||
;; when `flycheck-version' needs it, so we need this:
|
||||
(autoload 'pkg-info-version-info "pkg-info")
|
||||
|
||||
(def-package! flycheck
|
||||
:commands (flycheck-mode flycheck-list-errors flycheck-buffer)
|
||||
:commands (flycheck-list-errors flycheck-buffer)
|
||||
:config
|
||||
;; Emacs feels snappier without checks on newline
|
||||
(setq flycheck-check-syntax-automatically '(save idle-change mode-enabled))
|
||||
|
||||
;; Popup
|
||||
(add-hook 'flycheck-mode-hook #'+syntax-checker-popup-mode)
|
||||
|
||||
(after! evil
|
||||
(defun +syntax-checkers|flycheck-buffer ()
|
||||
"Flycheck buffer on ESC in normal mode."
|
||||
|
@ -20,21 +13,16 @@
|
|||
(ignore-errors (flycheck-buffer))
|
||||
nil))
|
||||
(add-hook 'doom-escape-hook #'+syntax-checkers|flycheck-buffer t)
|
||||
(add-hook 'evil-insert-state-exit-hook #'+syntax-checkers|flycheck-buffer)
|
||||
|
||||
;; With the option of flychecking the buffer on escape or leaving insert
|
||||
;; mode, we don't need auto-flychecking on idle-change (which can feel slow,
|
||||
;; esp on computers without SSDs).
|
||||
(delq 'idle-change flycheck-check-syntax-automatically)))
|
||||
(add-hook 'evil-insert-state-exit-hook #'+syntax-checkers|flycheck-buffer)))
|
||||
|
||||
|
||||
(def-package! flycheck-popup-tip
|
||||
:commands (flycheck-popup-tip-show-popup flycheck-popup-tip-delete-popup))
|
||||
:commands (flycheck-popup-tip-show-popup flycheck-popup-tip-delete-popup)
|
||||
:init (add-hook 'flycheck-mode-hook #'+syntax-checker-popup-mode))
|
||||
|
||||
|
||||
(def-package! flycheck-posframe
|
||||
:when EMACS26+
|
||||
:when (featurep! +childframe)
|
||||
:when (and EMACS26+ (featurep! +childframe))
|
||||
:commands flycheck-posframe-show-posframe
|
||||
:config
|
||||
(setq flycheck-posframe-warning-prefix "⚠ "
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
;;; feature/version-control/+git.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; These don't need `def-package!' blocks because they've already been set up by
|
||||
;; `doom-initialize'.
|
||||
(autoload 'gitconfig-mode "gitconfig-mode" nil t)
|
||||
(autoload 'gitignore-mode "gitignore-mode" nil t)
|
||||
|
||||
(when (featurep! :feature evil)
|
||||
(add-hook 'git-commit-mode-hook #'evil-insert-state))
|
||||
|
||||
|
@ -33,7 +28,7 @@
|
|||
(ignore (git-gutter))))
|
||||
(add-hook 'doom-escape-hook #'+version-control|update-git-gutter t))
|
||||
|
||||
(def-hydra! +version-control@git-gutter
|
||||
(defhydra +version-control@git-gutter
|
||||
(:body-pre (git-gutter-mode 1) :hint nil)
|
||||
"
|
||||
╭─────────────────┐
|
||||
|
@ -59,7 +54,7 @@
|
|||
|
||||
|
||||
(def-package! git-timemachine
|
||||
:commands (git-timemachine git-timemachine-toggle)
|
||||
:defer t
|
||||
:config
|
||||
;; Sometimes I forget `git-timemachine' is enabled in a buffer, so instead of
|
||||
;; showing revision details in the minibuffer, show them in
|
||||
|
@ -67,10 +62,6 @@
|
|||
(setq git-timemachine-show-minibuffer-details t)
|
||||
(advice-add #'git-timemachine--show-minibuffer-details :override #'+vcs*update-header-line)
|
||||
|
||||
(after! evil
|
||||
;; Force evil to rehash keybindings for the current state
|
||||
(add-hook 'git-timemachine-mode-hook #'evil-force-normal-state))
|
||||
|
||||
|
||||
(def-package! git-link
|
||||
:commands (git-link git-link-commit git-link-homepage))
|
||||
|
||||
(add-hook 'git-timemachine-mode-hook #'evil-force-normal-state)))
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
(defalias #'smerge-diff-upper-lower #'smerge-diff-mine-other)
|
||||
(defalias #'smerge-diff-base-lower #'smerge-diff-base-other)))
|
||||
|
||||
(def-hydra! +hydra-smerge (:hint nil
|
||||
(defhydra +hydra-smerge (:hint nil
|
||||
:pre (smerge-mode 1)
|
||||
;; Disable `smerge-mode' when quitting hydra if
|
||||
;; no merge conflicts remain.
|
||||
|
|
|
@ -211,7 +211,7 @@ current workspace (by name) from session files."
|
|||
(completing-read
|
||||
"Workspace to load: "
|
||||
(persp-list-persp-names-in-file
|
||||
(expand-file-name +workspace-data-file persp-save-dir))))))
|
||||
(expand-file-name +workspaces-data-file persp-save-dir))))))
|
||||
(if (not (+workspace-load name))
|
||||
(+workspace-error (format "Couldn't load workspace %s" name))
|
||||
(+workspace/switch-to name)
|
||||
|
|
|
@ -27,7 +27,7 @@ new project directory.")
|
|||
stored in `persp-save-dir'.")
|
||||
|
||||
(defun +workspaces-restore-last-session (&rest _)
|
||||
(add-hook 'emacs-startup-hook #'+workspace/load-session 'append))
|
||||
(add-hook 'doom-post-init-hook #'+workspace/load-session 'append))
|
||||
(map-put command-switch-alist '"--restore" #'+workspaces-restore-last-session)
|
||||
|
||||
|
||||
|
@ -77,7 +77,7 @@ Uses `+workspaces-main' to determine the name of the main workspace."
|
|||
(display-buffer-in-side-window
|
||||
warnings '((window-height . shrink-window-if-larger-than-buffer))))))))))
|
||||
|
||||
(add-hook 'doom-init-hook #'+workspaces|init t)
|
||||
(add-hook 'doom-post-init-hook #'+workspaces|init t)
|
||||
:config
|
||||
(setq persp-autokill-buffer-on-remove 'kill-weak
|
||||
persp-nil-hidden t
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
;;; feature/workspaces/test/autoload-workspaces.el
|
||||
|
||||
(require! :feature workspaces)
|
||||
(doom|init-custom-hooks)
|
||||
|
||||
(defmacro with-workspace!! (buffer-args &rest body)
|
||||
(declare (indent defun))
|
||||
|
@ -13,7 +14,8 @@
|
|||
(require 'persp-mode)
|
||||
(let (noninteractive)
|
||||
(persp-mode +1))
|
||||
(+workspace-switch +workspaces-main t)
|
||||
(let (persp-before-switch-functions persp-activated-functions)
|
||||
(+workspace-switch +workspaces-main t))
|
||||
(let* (,@buffers)
|
||||
(cl-loop with persp = (get-current-persp)
|
||||
for buf in (list ,@(mapcar #'car buffers))
|
||||
|
|
4
modules/lang/assembly/autoload.el
Normal file
4
modules/lang/assembly/autoload.el
Normal file
|
@ -0,0 +1,4 @@
|
|||
;;; lang/assembly/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(map-put auto-mode-alist "\\.hax\\'" 'haxor-mode)
|
|
@ -1,8 +0,0 @@
|
|||
;;; lang/assembly/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! mips-mode :mode "\\.mips$")
|
||||
|
||||
(def-package! haxor-mode :mode "\\.hax$")
|
||||
|
||||
(def-package! nasm-mode :commands nasm-mode)
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
(interactive)
|
||||
(unless (memq major-mode '(c-mode c++-mode objc-mode))
|
||||
(user-error "Not a C/C++/ObjC buffer"))
|
||||
(unless (doom-project-has! "compile_commands.json")
|
||||
(unless (project-file-exists-p! "compile_commands.json")
|
||||
(user-error "No compile_commands.json file"))
|
||||
;; first rtag
|
||||
(when (and (featurep 'rtags)
|
||||
|
@ -89,13 +89,6 @@ compilation dbs."
|
|||
nconc (list "-I" path)))
|
||||
(doom-project-root)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +cc|init-rtags ()
|
||||
"Start an rtags server in c-mode and c++-mode buffers."
|
||||
(when (and (memq major-mode '(c-mode c++-mode))
|
||||
(rtags-executable-find "rtags"))
|
||||
(rtags-start-process-unless-running)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +cc|cleanup-rtags ()
|
||||
"Kill rtags server(s) if there are no C/C++ buffers open."
|
||||
|
|
|
@ -101,8 +101,8 @@ compilation database is present in the project.")
|
|||
(label . 0))))
|
||||
|
||||
;;; Keybindings
|
||||
;; Completely disable electric keys because it interferes with smartparens and
|
||||
;; custom bindings. We'll do this ourselves.
|
||||
;; Disable electric keys because it interferes with smartparens and custom
|
||||
;; bindings. We'll do it ourselves (mostly).
|
||||
(setq c-tab-always-indent nil
|
||||
c-electric-flag nil)
|
||||
(dolist (key '("#" "}" "/" "*" ";" "," ":" "(" ")" "\177"))
|
||||
|
@ -129,6 +129,7 @@ compilation database is present in the project.")
|
|||
|
||||
|
||||
(def-package! irony
|
||||
:when (featurep! +irony)
|
||||
:commands (irony-install-server irony-mode)
|
||||
:preface
|
||||
(setq irony-server-install-prefix (concat doom-etc-dir "irony-server/"))
|
||||
|
@ -172,23 +173,13 @@ compilation database is present in the project.")
|
|||
;;
|
||||
|
||||
(def-package! cmake-mode
|
||||
:mode "/CMakeLists\\.txt$"
|
||||
:mode "\\.cmake\\$"
|
||||
:defer t
|
||||
:config
|
||||
(set! :company-backend 'cmake-mode '(company-cmake company-yasnippet)))
|
||||
|
||||
(def-package! cuda-mode :mode "\\.cuh?$")
|
||||
(def-package! opencl-mode :mode "\\.cl\\'")
|
||||
|
||||
(def-package! opencl-mode :mode "\\.cl$")
|
||||
|
||||
(def-package! demangle-mode
|
||||
:hook llvm-mode)
|
||||
|
||||
(def-package! glsl-mode
|
||||
:mode "\\.glsl$"
|
||||
:mode "\\.vert$"
|
||||
:mode "\\.frag$"
|
||||
:mode "\\.geom$")
|
||||
(def-package! demangle-mode :hook llvm-mode)
|
||||
|
||||
|
||||
;;
|
||||
|
@ -213,7 +204,12 @@ compilation database is present in the project.")
|
|||
(def-package! rtags
|
||||
:commands rtags-executable-find
|
||||
:init
|
||||
(add-hook! (c-mode c++-mode) #'+cc|init-rtags)
|
||||
(defun +cc|init-rtags ()
|
||||
"Start an rtags server in c-mode and c++-mode buffers."
|
||||
(when (and (memq major-mode '(c-mode c++-mode))
|
||||
(rtags-executable-find "rtags"))
|
||||
(rtags-start-process-unless-running)))
|
||||
(add-hook 'c-mode-common-hook #'+cc|init-rtags)
|
||||
:config
|
||||
(setq rtags-autostart-diagnostics t
|
||||
rtags-use-bookmarks nil
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
(warn! "Couldn't find the rtag client and/or server programs %s. Disabling rtags support" bins)))
|
||||
|
||||
;; irony server
|
||||
(require 'irony)
|
||||
(when (require 'irony nil t)
|
||||
(unless (file-directory-p irony-server-install-prefix)
|
||||
(warn! "Irony server isn't installed. Run M-x irony-install-server"))
|
||||
(warn! "Irony server isn't installed. Run M-x irony-install-server")))
|
||||
|
||||
(when (featurep! :completion company)
|
||||
;; glslangValidator
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
;;; lang/clojure/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! clojure-mode
|
||||
:mode "\\.clj$"
|
||||
:mode "\\.edn$"
|
||||
:mode "\\(?:build\\|profile\\)\\.boot$"
|
||||
:mode ("\\.cljs$" . clojurescript-mode)
|
||||
:mode ("\\.cljc$" . clojurec-mode)
|
||||
:config
|
||||
(add-hook 'clojure-mode #'rainbow-delimiters-mode))
|
||||
;; `clojure-mode'
|
||||
(add-hook 'clojure-mode #'rainbow-delimiters-mode)
|
||||
|
||||
|
||||
(def-package! clj-refactor
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
;;; lang/crystal/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! crystal-mode
|
||||
:mode "\\.cr$"
|
||||
:interpreter "crystal"
|
||||
:defer t
|
||||
:config
|
||||
(set! :lookup 'crystal-mode
|
||||
:definition #'crystal-def-jump
|
||||
|
@ -19,5 +18,4 @@
|
|||
:config (add-hook 'crystal-mode-hook #'flycheck-mode))
|
||||
|
||||
|
||||
(def-package! inf-crystal
|
||||
:commands (inf-crystal crystal-switch-to-inf))
|
||||
(def-package! inf-crystal :commands crystal-switch-to-inf)
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
;;; lang/csharp/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! csharp-mode :mode "\\.cs$")
|
||||
|
||||
(def-package! shader-mode :mode "\\.shader$") ; unity shaders
|
||||
(add-to-list 'auto-mode-alist '("\\.shader$" . shader-mode)) ; unity shaders
|
||||
|
||||
|
||||
(def-package! omnisharp
|
||||
:after csharp-mode
|
||||
:hook (csharp-mode . omnisharp-mode)
|
||||
:commands omnisharp-install-server
|
||||
:preface
|
||||
(setq omnisharp-auto-complete-want-documentation nil
|
||||
omnisharp-cache-directory (concat doom-cache-dir "omnisharp"))
|
||||
:config
|
||||
(add-hook! csharp-mode #'(flycheck-mode omnisharp-mode))
|
||||
(add-hook 'csharp-mode-hook #'flycheck-mode)
|
||||
|
||||
(defun +csharp|cleanup-omnisharp-server ()
|
||||
"Clean up the omnisharp server once you kill the last csharp-mode buffer."
|
||||
|
|
|
@ -1,47 +1,41 @@
|
|||
;;; lang/data/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(push '("/sxhkdrc" . conf-mode) auto-mode-alist)
|
||||
;; Built in plugins
|
||||
(dolist (spec '(("/sxhkdrc\\'" . conf-mode)
|
||||
("\\.\\(?:hex\\|nes\\)\\'" . hexl-mode)
|
||||
("\\.plist\\'" . nxml-mode)))
|
||||
(map-put auto-mode-alist (car spec) (cdr spec)))
|
||||
|
||||
(set! :company-backend 'nxml-mode '(company-nxml company-yasnippet))
|
||||
|
||||
|
||||
(def-package! dockerfile-mode
|
||||
:mode "/Dockerfile$")
|
||||
;;
|
||||
;; Third-party plugins
|
||||
;;
|
||||
|
||||
;; `csv-mode'
|
||||
(map! :after csv-mode
|
||||
:map csv-mode-map
|
||||
(:localleader
|
||||
:desc "Align fields" :nvm "a" #'csv-align-fields
|
||||
:desc "Unalign fields" :nvm "u" #'csv-unalign-fields
|
||||
:desc "Sort fields" :nvm "s" #'csv-sort-fields
|
||||
:desc "Sort fields (n)" :nvm "S" #'csv-sort-numeric-fields
|
||||
:desc "Kill fields" :nvm "k" #'csv-kill-fields
|
||||
:desc "Transpose fields" :nvm "t" #'csv-transpose))
|
||||
|
||||
(def-package! graphql-mode
|
||||
:mode "\\.g\\(?:raph\\)?ql$")
|
||||
|
||||
|
||||
(def-package! hexl ; For ROM hacking or debugging
|
||||
:mode ("\\.hex$" . hexl-mode)
|
||||
:mode ("\\.nes$" . hexl-mode))
|
||||
|
||||
:mode "\\.gql\\'")
|
||||
|
||||
(def-package! json-mode
|
||||
:mode "\\.js\\(?:on\\|[hl]int\\(rc\\)?\\)$"
|
||||
:mode "\\.js\\(?:on\\|[hl]int\\(rc\\)?\\)\\'"
|
||||
:config
|
||||
(when (featurep! :feature syntax-checker)
|
||||
(add-hook 'json-mode-hook #'flycheck-mode))
|
||||
(set! :electric 'json-mode :chars '(?\n ?: ?{ ?})))
|
||||
|
||||
|
||||
(def-package! nxml-mode
|
||||
:mode "\\.plist$"
|
||||
:config
|
||||
(set! :company-backend 'nxml-mode '(company-nxml company-yasnippet)))
|
||||
|
||||
|
||||
(def-package! toml-mode
|
||||
:mode "\\.toml$")
|
||||
|
||||
|
||||
(def-package! vimrc-mode
|
||||
:mode "/\\.?g?vimrc$"
|
||||
:mode "\\.vimp?$"
|
||||
:mode "\\.?vimperatorrc$")
|
||||
|
||||
|
||||
(def-package! yaml-mode
|
||||
:mode "\\.ya?ml$")
|
||||
:mode "\\.?vimperatorrc\\'")
|
||||
|
||||
|
||||
;;
|
||||
|
|
|
@ -7,4 +7,4 @@
|
|||
(package! toml-mode)
|
||||
(package! vimrc-mode)
|
||||
(package! yaml-mode)
|
||||
|
||||
(package! csv-mode)
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
;;; lang/elixir/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! elixir-mode
|
||||
:mode "\\.exs?\\'"
|
||||
:mode "\\.elixir2\\'"
|
||||
:init
|
||||
;; sp's default elixir rules are obnoxious, so disable them
|
||||
(provide 'smartparens-elixir)
|
||||
:defer t
|
||||
:config
|
||||
;; ...and only complete the basics
|
||||
(after! smartparens
|
||||
(sp-with-modes 'elixir-mode
|
||||
(sp-local-pair "do" "end"
|
||||
:when '(("RET" "<evil-ret>"))
|
||||
|
@ -15,7 +12,7 @@
|
|||
:skip-match 'sp-elixir-skip-def-p
|
||||
:post-handlers '("||\n[i]"))
|
||||
(sp-local-pair "do " " end" :unless '(sp-in-comment-p sp-in-string-p))
|
||||
(sp-local-pair "fn " " end" :unless '(sp-in-comment-p sp-in-string-p))))
|
||||
(sp-local-pair "fn " " end" :unless '(sp-in-comment-p sp-in-string-p)))))
|
||||
|
||||
|
||||
(def-package! alchemist
|
||||
|
@ -30,13 +27,13 @@
|
|||
|
||||
(def-package! alchemist-company
|
||||
:when (featurep! :completion company)
|
||||
:after elixir-mode
|
||||
:commands alchemist-company
|
||||
:init
|
||||
(set! :company-backend 'elixir-mode '(alchemist-company company-yasnippet))
|
||||
:config
|
||||
;; Alchemist doesn't use hook symbols to add these backends, so we have to use
|
||||
;; the entire closure to get rid of it.
|
||||
(let ((fn (byte-compile (lambda () (add-to-list (make-local-variable 'company-backends) 'alchemist-company)))))
|
||||
(remove-hook 'alchemist-mode-hook fn)
|
||||
(remove-hook 'alchemist-iex-mode-hook fn))
|
||||
|
||||
(set! :company-backend 'elixir-mode '(alchemist-company company-yasnippet)))
|
||||
(remove-hook 'alchemist-iex-mode-hook fn)))
|
||||
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
;;; lang/elm/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! elm-mode
|
||||
:mode "\\.elm$"
|
||||
:config
|
||||
(load "elm-mode-autoloads" nil t)
|
||||
;; `elm-mode'
|
||||
(setq elm-format-on-save t)
|
||||
|
||||
(add-hook! 'elm-mode-hook #'(flycheck-mode rainbow-delimiters-mode))
|
||||
(set! :company-backend 'elm-mode '(company-elm))
|
||||
|
||||
(set! :company-backend 'elm-mode 'company-elm)
|
||||
(set! :repl 'elm-mode #'run-elm-interactive)
|
||||
(setq elm-format-on-save t))
|
||||
|
||||
|
||||
(def-package! flycheck-elm
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
;;; lang/emacs-lisp/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(autoload 'overseer-test "overseer" nil t)
|
||||
|
||||
|
||||
;;
|
||||
;; Library
|
||||
;;
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp/repl ()
|
||||
"Open the Emacs Lisp REPL (`ielm')."
|
||||
|
|
|
@ -67,27 +67,17 @@
|
|||
;; Plugins
|
||||
;;
|
||||
|
||||
(def-package! auto-compile
|
||||
:commands auto-compile-on-save-mode
|
||||
:config
|
||||
;; `auto-compile'
|
||||
(setq auto-compile-display-buffer nil
|
||||
auto-compile-use-mode-line nil))
|
||||
auto-compile-use-mode-line nil)
|
||||
|
||||
|
||||
(def-package! highlight-quoted
|
||||
:commands highlight-quoted-mode)
|
||||
|
||||
|
||||
(def-package! slime
|
||||
:defer t
|
||||
:config
|
||||
;; `slime'
|
||||
(setq inferior-lisp-program "clisp")
|
||||
(require 'slime-fuzzy))
|
||||
(after! slime (require 'slime-fuzzy))
|
||||
|
||||
|
||||
(def-package! macrostep
|
||||
:commands macrostep-expand
|
||||
:config
|
||||
(after! macrostep
|
||||
(map! :map macrostep-keymap
|
||||
:n "RET" #'macrostep-expand
|
||||
:n "e" #'macrostep-expand
|
||||
|
@ -104,6 +94,7 @@
|
|||
|
||||
:n "q" #'macrostep-collapse-all
|
||||
:n "C" #'macrostep-collapse-all)
|
||||
|
||||
;; `evil-normalize-keymaps' seems to be required for macrostep or it won't
|
||||
;; apply for the very first invocation
|
||||
(add-hook 'macrostep-mode-hook #'evil-normalize-keymaps))
|
||||
|
@ -111,18 +102,14 @@
|
|||
|
||||
(def-package! flycheck-cask
|
||||
:when (featurep! :feature syntax-checker)
|
||||
:commands flycheck-cask-setup
|
||||
:defer t
|
||||
:init
|
||||
(add-hook! 'emacs-lisp-mode-hook
|
||||
(add-hook 'flycheck-mode-hook #'flycheck-cask-setup nil t)))
|
||||
|
||||
|
||||
(def-package! overseer
|
||||
:commands overseer-test)
|
||||
|
||||
|
||||
;;
|
||||
;;
|
||||
;; Project modes
|
||||
;;
|
||||
|
||||
(def-project-mode! +emacs-lisp-ert-mode
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
;;; private/erlang/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! erlang
|
||||
;; customizations
|
||||
:mode "\\.erlang$"
|
||||
(dolist (regexp '("\\.erlang$"
|
||||
;; rebar files
|
||||
:mode "/rebar\\.config\\(?:\\.script\\)?$"
|
||||
"/rebar\\.config\\(?:\\.script\\)?$"
|
||||
;; erlang configs
|
||||
:mode "/\\(?:app\\|sys\\)\\.config$")
|
||||
"/\\(?:app\\|sys\\)\\.config$"))
|
||||
(map-put auto-mode-alist regexp 'erlang-mode))
|
||||
|
||||
|
||||
(def-package! flycheck-rebar3
|
||||
:when (featurep! :feature syntax-checker)
|
||||
:after erlang
|
||||
:config
|
||||
(flycheck-rebar3-setup))
|
||||
:after flycheck
|
||||
:config (flycheck-rebar3-setup))
|
||||
|
||||
|
||||
;; Completion via Ivy
|
||||
(def-package! ivy-erlang-complete
|
||||
:when (featurep! :completion ivy)
|
||||
:hook (erlang-mode . ivy-erlang-complete-init)
|
||||
|
@ -23,7 +22,6 @@
|
|||
(add-hook 'after-save-hook #'ivy-erlang-complete-reparse nil t)))
|
||||
|
||||
|
||||
;; Completion via Company
|
||||
(def-package! company-erlang
|
||||
:when (featurep! :completion company)
|
||||
:hook (erlang-mode . company-erlang-init))
|
||||
|
|
|
@ -79,6 +79,6 @@
|
|||
:n "cn" #'ess-noweb-next-chunk))))
|
||||
|
||||
|
||||
(def-package! ess-smart-equals
|
||||
:hook ((ess-mode . ess-smart-equals-mode)
|
||||
(inferior-ess-mode . ess-smart-equals-mode)))
|
||||
;; `ess-smart-equals-mode'
|
||||
(add-hook! (ess-mode inferior-ess)
|
||||
#'ess-smart-equals-mode)
|
||||
|
|
|
@ -4,10 +4,7 @@
|
|||
;; Plugins
|
||||
;;
|
||||
|
||||
(def-package! go-mode
|
||||
:mode "\\.go$"
|
||||
:interpreter "go"
|
||||
:config
|
||||
(after! go-mode
|
||||
(set! :env "GOPATH" "GOROOT")
|
||||
(set! :repl 'go-mode #'gorepl-run)
|
||||
(set! :lookup 'go-mode
|
||||
|
@ -15,11 +12,12 @@
|
|||
:references #'go-guru-referrers
|
||||
:documentation #'godoc-at-point)
|
||||
|
||||
(when (executable-find "goimports")
|
||||
(setq gofmt-command "goimports"))
|
||||
(when-let* ((goimports (executable-find "goimports")))
|
||||
(setq gofmt-command goimports))
|
||||
|
||||
(setq gofmt-show-errors nil) ; Leave it to flycheck
|
||||
(add-hook 'go-mode-hook #'flycheck-mode)
|
||||
|
||||
(add-hook! 'go-mode-hook #'(flycheck-mode go-eldoc-setup))
|
||||
(add-hook! go-mode
|
||||
(add-hook 'before-save-hook #'gofmt-before-save nil t))
|
||||
|
||||
|
@ -70,25 +68,13 @@
|
|||
:v "r" #'go-play-region))
|
||||
|
||||
|
||||
(def-package! go-eldoc
|
||||
:hook (go-mode . go-eldoc-setup))
|
||||
|
||||
|
||||
(def-package! go-guru
|
||||
:commands (go-guru-describe go-guru-freevars go-guru-implements go-guru-peers
|
||||
go-guru-referrers go-guru-definition go-guru-pointsto
|
||||
go-guru-callstack go-guru-whicherrs go-guru-callers go-guru-callees
|
||||
go-guru-expand-region))
|
||||
|
||||
|
||||
(def-package! gorepl-mode
|
||||
:commands (gorepl-run gorepl-run-load-current-file))
|
||||
:commands gorepl-run-load-current-file)
|
||||
|
||||
|
||||
(def-package! company-go
|
||||
:when (featurep! :completion company)
|
||||
:init (setq command-go-gocode-command "gocode")
|
||||
:after go-mode
|
||||
:config
|
||||
(setq company-go-show-annotation t)
|
||||
(set! :company-backend 'go-mode '(company-go)))
|
||||
(set! :company-backend 'go-mode 'company-go)
|
||||
(setq company-go-show-annotation t))
|
||||
|
|
|
@ -8,18 +8,7 @@
|
|||
;; Common plugins
|
||||
;;
|
||||
|
||||
(def-package! haskell-mode
|
||||
:mode "\\.hs$"
|
||||
:mode ("\\.ghci$" . ghci-script-mode)
|
||||
:mode ("\\.cabal$" . haskell-cabal-mode)
|
||||
:interpreter (("runghc" . haskell-mode)
|
||||
("runhaskell" . haskell-mode))
|
||||
:config
|
||||
(load "haskell-mode-autoloads" nil t)
|
||||
(after! haskell-mode
|
||||
(set! :repl 'haskell-mode #'switch-to-haskell)
|
||||
(push ".hi" completion-ignored-extensions)
|
||||
|
||||
(autoload 'switch-to-haskell "inf-haskell" nil t)
|
||||
(after! inf-haskell
|
||||
(map! :map inferior-haskell-mode-map "ESC ESC" #'+popup/close)))
|
||||
(add-to-list 'completion-ignored-extensions ".hi"))
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
;;; lang/hy/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! hy-mode
|
||||
:mode "\\.hy$"
|
||||
:mode "\\.hy\\'"
|
||||
:interpreter "hy"
|
||||
:config
|
||||
(set! :repl 'hy-mode #'hy-shell-start-or-switch-to-shell)
|
||||
(set! :company-backend 'hy-mode '(company-hy)))
|
||||
(set! :company-backend 'hy-mode 'company-hy))
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
;;;###autoload
|
||||
(defun +java|android-mode-maybe ()
|
||||
(when (doom-project-has! (or "local.properties"
|
||||
(when (project-file-exists-p! (or "local.properties"
|
||||
"AndroidManifest.xml"
|
||||
"src/main/AndroidManifest.xml"))
|
||||
(android-mode +1)
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
(add-hook 'java-mode-hook #'rainbow-delimiters-mode)
|
||||
|
||||
(cond ((featurep! +meghanada) (load! +meghanada))
|
||||
;; TODO lang/java +eclim
|
||||
;; ((featurep! +eclim) (load! +eclim))
|
||||
;; TODO lang/java +lsp (lsp-java?)
|
||||
;; ((featurep! +lsp) (load! +lsp))
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
(add-hook! 'js2-mode-hook #'(flycheck-mode rainbow-delimiters-mode))
|
||||
|
||||
(set! :electric 'js2-mode :chars '(?\} ?\) ?. ?:))
|
||||
(set! :repl 'js2-mode #'+javascript/repl)
|
||||
|
||||
;; Conform switch-case indentation to js2 normal indent
|
||||
(defvaralias 'js-switch-indent-offset 'js2-basic-offset)
|
||||
|
@ -34,16 +35,7 @@
|
|||
:n "S" #'+javascript/skewer-this-buffer))
|
||||
|
||||
|
||||
(def-package! typescript-mode
|
||||
:commands typescript-mode
|
||||
:config
|
||||
(add-hook! 'typescript-mode-hook #'(flycheck-mode rainbow-delimiters-mode))
|
||||
(set! :electric 'typescript-mode
|
||||
:chars '(?\} ?\)) :words '("||" "&&")))
|
||||
|
||||
|
||||
(def-package! rjsx-mode
|
||||
:commands rjsx-mode
|
||||
:mode "components/.+\\.js$"
|
||||
:init
|
||||
(defun +javascript-jsx-file-p ()
|
||||
|
@ -54,8 +46,7 @@
|
|||
magic-mode-regexp-match-limit t)
|
||||
(progn (goto-char (match-beginning 1))
|
||||
(not (sp-point-in-string-or-comment)))))
|
||||
|
||||
(push '(+javascript-jsx-file-p . rjsx-mode) magic-mode-alist)
|
||||
(map-put magic-mode-alist #'+javascript-jsx-file-p 'rjsx-mode)
|
||||
:config
|
||||
(set! :electric 'rjsx-mode :chars '(?\} ?\) ?. ?>))
|
||||
(add-hook! 'rjsx-mode-hook
|
||||
|
@ -67,14 +58,19 @@
|
|||
;; However, the parser doesn't run immediately, so a fast typist can outrun
|
||||
;; it, causing issues, so force it to parse.
|
||||
(defun +javascript|reparse (n)
|
||||
;; if n != 0, then rjsx-maybe-reparse will be run elsewhere
|
||||
(if (= n 0) (rjsx-maybe-reparse)))
|
||||
;; if n != 1, rjsx-electric-gt calls rjsx-maybe-reparse itself
|
||||
(if (= n 1) (rjsx-maybe-reparse)))
|
||||
(advice-add #'rjsx-electric-gt :before #'+javascript|reparse))
|
||||
|
||||
|
||||
(def-package! coffee-mode
|
||||
:defer t ; file extensions registered by autoloads file
|
||||
:init (setq coffee-indent-like-python-mode t))
|
||||
(after! typescript-mode
|
||||
(add-hook! 'typescript-mode-hook #'(flycheck-mode rainbow-delimiters-mode))
|
||||
(set! :electric 'typescript-mode
|
||||
:chars '(?\} ?\)) :words '("||" "&&")))
|
||||
|
||||
|
||||
;; `coffee-mode'
|
||||
(setq coffee-indent-like-python-mode t)
|
||||
|
||||
|
||||
;;
|
||||
|
@ -86,6 +82,7 @@
|
|||
:hook (typescript-mode . tide-setup)
|
||||
:init
|
||||
(defun +javascript|init-tide-in-web-mode ()
|
||||
"Enable `tide-mode' if in a *.tsx file."
|
||||
(when (string= (file-name-extension (or buffer-file-name "")) "tsx")
|
||||
(tide-setup)))
|
||||
(add-hook 'web-mode-hook #'+javascript|init-tide-in-web-mode)
|
||||
|
@ -156,12 +153,6 @@
|
|||
:init (set! :lookup 'js2-mode :xref-backend #'xref-js2-xref-backend))
|
||||
|
||||
|
||||
(def-package! nodejs-repl
|
||||
:commands nodejs-repl
|
||||
:init
|
||||
(set! :repl 'js2-mode #'+javascript/repl))
|
||||
|
||||
|
||||
(def-package! js2-refactor
|
||||
:commands
|
||||
(js2r-extract-function js2r-extract-method js2r-introduce-parameter
|
||||
|
@ -174,51 +165,38 @@
|
|||
js2r-debug-this js2r-forward-slurp js2r-forward-barf))
|
||||
|
||||
|
||||
(def-package! web-beautify
|
||||
:commands web-beautify-js
|
||||
:init
|
||||
(map! :map* (json-mode js2-mode-map) :n "gQ" #'web-beautify-js))
|
||||
|
||||
|
||||
(def-package! eslintd-fix
|
||||
:commands (eslintd-fix-mode eslintd-fix)
|
||||
:commands eslintd-fix
|
||||
:config
|
||||
(defun +javascript|set-flycheck-executable-to-eslint ()
|
||||
(setq flycheck-javascript-eslint-executable eslintd-fix-executable))
|
||||
(add-hook 'eslintd-fix-mode-hook #'+javascript|set-flycheck-executable-to-eslint))
|
||||
|
||||
|
||||
(def-package! skewer-mode
|
||||
:commands (skewer-mode run-skewer)
|
||||
:config
|
||||
(map! :map skewer-mode-map
|
||||
;; `skewer-mode'
|
||||
(map! (:after skewer-mode
|
||||
:map skewer-mode-map
|
||||
:localleader
|
||||
:n "sE" #'skewer-eval-last-expression
|
||||
:n "se" #'skewer-eval-defun
|
||||
:n "sf" #'skewer-load-buffer))
|
||||
:n "sf" #'skewer-load-buffer)
|
||||
|
||||
|
||||
(def-package! skewer-css ; in skewer-mode
|
||||
:commands skewer-css-mode
|
||||
:config
|
||||
(map! :map skewer-css-mode-map
|
||||
(:after skewer-css
|
||||
:map skewer-css-mode-map
|
||||
:localleader
|
||||
:n "se" #'skewer-css-eval-current-declaration
|
||||
:n "sr" #'skewer-css-eval-current-rule
|
||||
:n "sb" #'skewer-css-eval-buffer
|
||||
:n "sc" #'skewer-css-clear-all))
|
||||
:n "sc" #'skewer-css-clear-all)
|
||||
|
||||
|
||||
(def-package! skewer-html ; in skewer-mode
|
||||
:commands skewer-html-mode
|
||||
:config
|
||||
(map! :map skewer-html-mode-map
|
||||
(:after skewer-html
|
||||
:map skewer-html-mode-map
|
||||
:localleader
|
||||
:n "se" #'skewer-html-eval-tag))
|
||||
|
||||
|
||||
(def-package! skewer-repl
|
||||
:commands skewer-repl)
|
||||
;; `web-beautify'
|
||||
(map! :map* (json-mode-map js2-mode-map) :n "gQ" #'web-beautify-js)
|
||||
|
||||
|
||||
;;
|
||||
|
@ -226,7 +204,7 @@
|
|||
;;
|
||||
|
||||
(def-project-mode! +javascript-screeps-mode
|
||||
:match "/screeps\\(-ai\\)?/.+$"
|
||||
:match "/screeps\\(?:-ai\\)?/.+$"
|
||||
:modes (+javascript-npm-mode)
|
||||
:add-hooks (+javascript|init-screeps-mode)
|
||||
:on-load (load! +screeps))
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
;;; lang/julia/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package julia-mode
|
||||
:mode "\\.jl$"
|
||||
:interpreter "julia"
|
||||
:config
|
||||
(set! :repl 'julia-mode #'+julia/repl)
|
||||
|
|
|
@ -18,21 +18,12 @@
|
|||
"Sets the directory where AUCTeX will search for PDFs associated to BibTeX references."
|
||||
`(setq +latex-bibtex-dir ,dir))
|
||||
|
||||
;; sp's default latex rules are obnoxious, so disable them
|
||||
(provide 'smartparens-latex)
|
||||
|
||||
|
||||
;;
|
||||
;; Plugins
|
||||
;;
|
||||
|
||||
(def-package! tex-site
|
||||
:init
|
||||
;; Manually load the AUCTEX autoloads. This is normally done by
|
||||
;; package-initialize, ... which we do not use.
|
||||
(load "auctex.el" nil t t)
|
||||
(load "auctex-autoloads.el" nil t t)
|
||||
:config
|
||||
(after! tex-site
|
||||
;; Set some varibles to fontify common LaTeX commands.
|
||||
(load! +fontification)
|
||||
(setq ;; Enable parse on load.
|
||||
|
@ -182,7 +173,6 @@
|
|||
|
||||
(def-package! bibtex
|
||||
:defer t
|
||||
:mode ("\\.bib\\'" . bibtex-mode)
|
||||
:config
|
||||
(setq bibtex-dialect 'biblatex
|
||||
bibtex-align-at-equal-sign t
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
;;; lang/ledger/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! ledger-mode
|
||||
:mode "\\.ledger$"
|
||||
:config (setq ledger-clear-whole-transactions 1))
|
||||
;; `ledger-mode'
|
||||
(setq ledger-clear-whole-transactions 1)
|
||||
|
||||
|
||||
(def-package! evil-ledger
|
||||
|
@ -12,4 +11,5 @@
|
|||
|
||||
(def-package! flycheck-ledger
|
||||
:when (featurep! :feature syntax-checker)
|
||||
:init (add-hook 'ledger-mode-hook #'flycheck-mode))
|
||||
:after ledger-mode
|
||||
:config (add-hook 'ledger-mode-hook #'flycheck-mode))
|
||||
|
|
|
@ -1,18 +1,12 @@
|
|||
;;; lang/lua/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! lua-mode
|
||||
:mode "\\.lua$"
|
||||
:interpreter "lua"
|
||||
:init
|
||||
;; sp's default lua rules are obnoxious, so disable them. Use snippets
|
||||
;; instead!
|
||||
(provide 'smartparens-lua)
|
||||
:config
|
||||
(after! lua-mode
|
||||
(add-hook 'lua-mode-hook #'flycheck-mode)
|
||||
|
||||
(set! :lookup 'lua-mode :documentation 'lua-search-documentation)
|
||||
(set! :electric 'lua-mode :words '("else" "end"))
|
||||
(set! :repl 'lua-mode #'+lua/repl)
|
||||
(set! :company-backend 'lua-mode '(company-lua company-yasnippet))
|
||||
|
||||
(def-menu! +lua/build-menu
|
||||
"Build/compilation commands for `lua-mode' buffers."
|
||||
|
@ -24,15 +18,8 @@
|
|||
:n "b" #'+lua/build-menu))
|
||||
|
||||
|
||||
(def-package! company-lua
|
||||
:after (:all company lua-mode)
|
||||
:config
|
||||
(set! :company-backend 'lua-mode '(company-lua company-yasnippet)))
|
||||
|
||||
|
||||
(def-package! moonscript
|
||||
:mode ("\\.moon$" . moonscript-mode)
|
||||
:config (defvaralias 'moonscript-indent-offset 'tab-width))
|
||||
(after! moonscript
|
||||
(defvaralias 'moonscript-indent-offset 'tab-width))
|
||||
|
||||
|
||||
;;
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
;;; lang/markdown/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! markdown-mode
|
||||
:mode "/README$"
|
||||
:mode ("/README\\.md$" . gfm-mode)
|
||||
:mode "\\.m\\(?:d\\|arkdown\\)$"
|
||||
:mode ("/README\\(?:\\.\\(?:markdown\\|md\\)\\)?\\'" . gfm-mode)
|
||||
:init
|
||||
(setq markdown-enable-wiki-links t
|
||||
markdown-enable-math t
|
||||
|
|
|
@ -1,32 +1,20 @@
|
|||
;;; lang/nim/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! nim-mode
|
||||
:mode "\\.nim\\'"
|
||||
:mode ("\\.nim\\(ble\\|s\\)\\'" . nimscript-mode)
|
||||
:config
|
||||
(load "nim-mode-autoloads" nil t)
|
||||
;; NOTE nim-mode autoloads sets up xref
|
||||
|
||||
(after! nim-mode
|
||||
(defun +nim|init-nimsuggest-mode ()
|
||||
"Conditionally load `nimsuggest-mode', instead of clumsily erroring out if
|
||||
nimsuggest isn't installed."
|
||||
(when (executable-find "nimsuggest")
|
||||
(when (file-executable-p nimsuggest-path)
|
||||
(nimsuggest-mode)))
|
||||
(add-hook 'nim-mode-hook #'+nim|init-nimsuggest-mode)
|
||||
|
||||
(map! :map nim-mode-map
|
||||
:localleader
|
||||
:n "b" #'+nim/build-menu)
|
||||
|
||||
(def-menu! +nim/build-menu
|
||||
"Building commands for `nim-mode' buffers."
|
||||
'(("Build & run" :exec nim-compile))
|
||||
:prompt "Build"))
|
||||
:n "b" #'nim-compile))
|
||||
|
||||
|
||||
(def-package! flycheck-nim
|
||||
:when (featurep! :feature syntax-checker)
|
||||
:after nim-mode
|
||||
:config
|
||||
(add-hook 'nimsuggest-mode-hook #'flycheck-mode))
|
||||
:config (add-hook 'nimsuggest-mode-hook #'flycheck-mode))
|
||||
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
;;; lang/nix/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! nix-mode
|
||||
:mode "\\.nix$")
|
|
@ -1,9 +1,13 @@
|
|||
;;; lang/ocaml/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! tuareg
|
||||
:mode ("\\.ml[4ilpy]?$" . tuareg-mode))
|
||||
:mode ("\\.ml[4ilpy]?\\'" . tuareg-mode))
|
||||
|
||||
|
||||
(def-package! merlin
|
||||
:after tuareg
|
||||
:hook (tuareg-mode . merlin-mode))
|
||||
:hook (tuareg-mode . merlin-mode)
|
||||
:config
|
||||
(set! :company-backend 'tuareg-mode 'merlin-compand-backend)
|
||||
(after! company
|
||||
(remove-hook 'company-backends 'merlin-compand-backend)))
|
||||
|
|
|
@ -16,12 +16,8 @@
|
|||
;; Plugins
|
||||
;;
|
||||
|
||||
(def-package! toc-org
|
||||
:commands toc-org-enable
|
||||
:config (setq toc-org-hrefify-default "org"))
|
||||
|
||||
(def-package! org-bullets
|
||||
:commands org-bullets-mode)
|
||||
;; `toc-org'
|
||||
(setq toc-org-hrefify-default "org")
|
||||
|
||||
(def-package! evil-org
|
||||
:when (featurep! :feature evil)
|
||||
|
@ -126,7 +122,13 @@ unfold to point on startup."
|
|||
org-agenda-dim-blocked-tasks nil
|
||||
org-agenda-files (ignore-errors (directory-files +org-dir t "\\.org$" t))
|
||||
org-agenda-inhibit-startup t
|
||||
org-agenda-skip-unavailable-files t))
|
||||
org-agenda-skip-unavailable-files t)
|
||||
;; Move the agenda to show the previous 3 days and the next 7 days for a bit
|
||||
;; better context instead of just the current week which is a bit confusing
|
||||
;; on, for example, a sunday
|
||||
(setq org-agenda-span 10
|
||||
org-agenda-start-on-weekday nil
|
||||
org-agenda-start-day "-3d"))
|
||||
|
||||
(defun +org|setup-ui ()
|
||||
"Configures the UI for `org-mode'."
|
||||
|
@ -278,12 +280,14 @@ between the two."
|
|||
:ni [M-return] (λ! (+org/insert-item 'below))
|
||||
:ni [S-M-return] (λ! (+org/insert-item 'above))
|
||||
;; more org-ish vim motion keys
|
||||
:n "]]" (λ! (org-forward-heading-same-level nil) (org-beginning-of-line))
|
||||
:n "[[" (λ! (org-backward-heading-same-level nil) (org-beginning-of-line))
|
||||
:n "]l" #'org-next-link
|
||||
:n "[l" #'org-previous-link
|
||||
:n "]s" #'org-babel-next-src-block
|
||||
:n "[s" #'org-babel-previous-src-block
|
||||
:m "]]" (λ! (org-forward-heading-same-level nil) (org-beginning-of-line))
|
||||
:m "[[" (λ! (org-backward-heading-same-level nil) (org-beginning-of-line))
|
||||
:m "]h" #'org-next-visible-heading
|
||||
:m "[h" #'org-previous-visible-heading
|
||||
:m "]l" #'org-next-link
|
||||
:m "[l" #'org-previous-link
|
||||
:m "]s" #'org-babel-next-src-block
|
||||
:m "[s" #'org-babel-previous-src-block
|
||||
:m "^" #'evil-org-beginning-of-line
|
||||
:m "0" (λ! (let ((visual-line-mode)) (org-beginning-of-line)))
|
||||
:n "gQ" #'org-fill-paragraph
|
||||
|
@ -348,10 +352,11 @@ between the two."
|
|||
(def-package! org-clock
|
||||
:commands org-clock-save
|
||||
:hook (org-mode . org-clock-load)
|
||||
:config
|
||||
:init
|
||||
(setq org-clock-persist 'history
|
||||
org-clock-persist-file (concat doom-etc-dir "org-clock-save.el"))
|
||||
(add-hook 'kill-emacs-hook 'org-clock-save))
|
||||
:config
|
||||
(add-hook 'kill-emacs-hook #'org-clock-save))
|
||||
|
||||
;;
|
||||
(when (featurep 'org)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
;;; lang/plantuml/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! plantuml-mode
|
||||
:mode "\\.p\\(?:lant\\)?uml$"
|
||||
:defer t
|
||||
:init
|
||||
(setq plantuml-jar-path (concat doom-etc-dir "plantuml.jar")
|
||||
org-plantuml-jar-path plantuml-jar-path)
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
;;; lang/purescript/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! purescript-mode
|
||||
:mode "\\.purs$"
|
||||
:config
|
||||
(after! purescript-mode
|
||||
(add-hook! 'purescript-mode-hook
|
||||
#'(flycheck-mode purescript-indentation-mode rainbow-delimiters-mode)))
|
||||
#'(flycheck-mode
|
||||
purescript-indentation-mode
|
||||
rainbow-delimiters-mode)))
|
||||
|
||||
|
||||
;; (def-package! flycheck-purescript
|
||||
;; :after purescript-mode
|
||||
;; :config
|
||||
;; (add-hook 'flycheck-mode-hook #'flycheck-purescript-setup))
|
||||
|
||||
|
||||
(def-package! psc-ide
|
||||
:hook (purescript-mode . psc-ide-mode))
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue