commit
4c6b9d25c1
162 changed files with 4333 additions and 5028 deletions
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016-2018 Henrik Lissner.
|
||||
Copyright (c) 2016-2019 Henrik Lissner.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
|
3
bin/doom
3
bin/doom
|
@ -30,6 +30,7 @@
|
|||
" doom run -p ~/.other.doom.d -e ~/.other.emacs.d -nw file.txt\n"
|
||||
"\n"
|
||||
(format! (bold "Options:\n"))
|
||||
" -h --help\t\tSame as help command\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"
|
||||
" -i --insecure\t\tDisable TLS/SSL validation (not recommended)\n"
|
||||
|
@ -46,7 +47,7 @@
|
|||
(while (ignore-errors (string-prefix-p "-" (car args)))
|
||||
(pcase (pop args)
|
||||
((or "-h" "--help")
|
||||
(error "Did you mean 'doom help'?"))
|
||||
(push "help" args))
|
||||
((or "-d" "--debug")
|
||||
(setenv "DEBUG" "1")
|
||||
(message "Debug mode on"))
|
||||
|
|
|
@ -4,17 +4,24 @@
|
|||
":"; [[ $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.
|
||||
;; The Doom doctor is essentially one big, self-contained elisp shell script
|
||||
;; that uses a series of simple heuristics to diagnose common issues on your
|
||||
;; system. Issues that could intefere with Doom Emacs.
|
||||
;;
|
||||
;; Doom module may optionally have a doctor.el file to run their own heuristics
|
||||
;; in. Doctor scripts may run in versions of Emacs as old as Emacs 23, so you
|
||||
;; are limited to very basic standard library calls (e.g. avoid cl, subr-x, and
|
||||
;; any Doom dependencies).
|
||||
|
||||
;; In case it isn't defined (in really old versions of Emacs, like the one that
|
||||
;; ships with MacOS).
|
||||
;; In really old versions of Emacs `user-emacs-directory' isn't defined
|
||||
(defvar user-emacs-directory (expand-file-name "../" (file-name-directory load-file-name)))
|
||||
|
||||
(unless (file-directory-p user-emacs-directory)
|
||||
(error "Couldn't find a Doom config!"))
|
||||
(unless noninteractive
|
||||
(error "This script must not be run from an interactive session."))
|
||||
(when (getenv "DEBUG")
|
||||
(setq debug-on-error t))
|
||||
|
||||
(require 'pp)
|
||||
|
||||
|
@ -117,10 +124,10 @@
|
|||
|
||||
;; --- is emacs set up properly? ------------------------------
|
||||
|
||||
(when (version< emacs-version "25.1")
|
||||
(when (version< emacs-version "25.3")
|
||||
(error! "Important: Emacs %s detected [%s]" emacs-version (executable-find "emacs"))
|
||||
(explain!
|
||||
"DOOM only supports >= 25.1. Perhaps your PATH wasn't set up properly."
|
||||
"DOOM only supports >= 25.3. Perhaps your PATH wasn't set up properly."
|
||||
(when (eq system-type 'darwin)
|
||||
(concat "\nMacOS users should use homebrew (https://brew.sh) to install Emacs\n"
|
||||
" brew install emacs --with-modules --with-imagemagick --with-cocoa"))))
|
||||
|
@ -166,7 +173,7 @@
|
|||
font font-dest)
|
||||
(explain! "You can install it by running `M-x all-the-icons-install-fonts' within Emacs.\n\n"
|
||||
"This could also mean you've installed them in non-standard locations, in which "
|
||||
"case, ignore this warning."))))))
|
||||
"case feel free to ignore this warning."))))))
|
||||
|
||||
;; gnutls-cli & openssl
|
||||
(section! "Checking gnutls/openssl...")
|
||||
|
@ -289,6 +296,9 @@
|
|||
(or (cdr-safe ex) (car ex)))
|
||||
(setq doom-modules nil)))
|
||||
|
||||
(section! "Checking Doom core for irregularities...")
|
||||
(load (expand-file-name "doctor.el" doom-core-dir) nil 'nomessage)
|
||||
|
||||
(when (bound-and-true-p doom-modules)
|
||||
(section! "Checking your enabled modules...")
|
||||
(let ((indent 4))
|
||||
|
@ -296,22 +306,21 @@
|
|||
(maphash
|
||||
(lambda (key plist)
|
||||
(let ((prefix (format "%s" (color 1 "(%s %s) " (car key) (cdr key)))))
|
||||
(condition-case ex
|
||||
(condition-case-unless-debug ex
|
||||
(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))
|
||||
(let ((doom--stage 'packages))
|
||||
(when (load packages-file t t)
|
||||
(cl-loop for (name . plist) in doom-packages
|
||||
unless (or (doom-package-prop name :disable)
|
||||
(doom-package-prop name :ignore t)
|
||||
(package-built-in-p name)
|
||||
(package-installed-p name))
|
||||
do (error! "%s is not installed" name)))
|
||||
(let ((doom--stage 'doctor))
|
||||
(load doctor-file t t)))))
|
||||
(packages-file (doom-module-path (car key) (cdr key) "packages.el")))
|
||||
(cl-loop with doom--stage = 'packages
|
||||
for name in (let (doom-packages
|
||||
doom-disabled-packages)
|
||||
(load packages-file 'noerror 'nomessage)
|
||||
(mapcar #'car doom-packages))
|
||||
unless (or (doom-package-prop name :disable)
|
||||
(doom-package-prop name :ignore t)
|
||||
(package-built-in-p name)
|
||||
(package-installed-p name))
|
||||
do (error! "%s is not installed" name))
|
||||
(let ((doom--stage 'doctor))
|
||||
(load doctor-file 'noerror 'nomessage)))
|
||||
(file-missing (error! "%s" (error-message-string ex)))
|
||||
(error (error! "Syntax error: %s" ex)))))
|
||||
doom-modules)))
|
||||
|
|
|
@ -34,11 +34,6 @@ See `doom-real-buffer-p' for more information.")
|
|||
"The name of the buffer to fall back to if no other buffers exist (will create
|
||||
it if it doesn't exist).")
|
||||
|
||||
;;;###autoload
|
||||
(defvar doom-cleanup-hook ()
|
||||
"A list of hooks run when `doom/cleanup-session' is run, meant to clean up
|
||||
leftover buffers and processes.")
|
||||
|
||||
|
||||
;;
|
||||
;; Functions
|
||||
|
@ -54,7 +49,8 @@ BUF should be skipped over by functions like `next-buffer' and `other-buffer'."
|
|||
(defun doom-fallback-buffer ()
|
||||
"Returns the fallback buffer, creating it if necessary. By default this is the
|
||||
scratch buffer. See `doom-fallback-buffer-name' to change this."
|
||||
(get-buffer-create doom-fallback-buffer-name))
|
||||
(let (buffer-list-update-hook)
|
||||
(get-buffer-create doom-fallback-buffer-name)))
|
||||
|
||||
;;;###autoload
|
||||
(defalias 'doom-buffer-list #'buffer-list)
|
||||
|
@ -224,15 +220,17 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
|||
(format "Buffer %s is modified; kill anyway?" buf))))
|
||||
(message "Aborted")
|
||||
(set-buffer-modified-p nil)
|
||||
(when (or ;; if there aren't more real buffers than visible buffers,
|
||||
;; then there are no real, non-visible buffers left.
|
||||
(not (cl-set-difference (doom-real-buffer-list)
|
||||
(doom-visible-buffers)))
|
||||
;; if we end up back where we start (or previous-buffer
|
||||
;; returns nil), we have nowhere left to go
|
||||
(memq (previous-buffer) (list buf 'nil)))
|
||||
(switch-to-buffer (doom-fallback-buffer)))
|
||||
(kill-buffer buf)))
|
||||
(let (buffer-list-update-hook)
|
||||
(when (or ;; if there aren't more real buffers than visible buffers,
|
||||
;; then there are no real, non-visible buffers left.
|
||||
(not (cl-set-difference (doom-real-buffer-list)
|
||||
(doom-visible-buffers)))
|
||||
;; if we end up back where we start (or previous-buffer
|
||||
;; returns nil), we have nowhere left to go
|
||||
(memq (switch-to-prev-buffer nil t) (list buf 'nil)))
|
||||
(switch-to-buffer (doom-fallback-buffer)))
|
||||
(unless (delq (selected-window) (get-buffer-window-list buf nil t))
|
||||
(kill-buffer buf)))))
|
||||
((funcall orig-fn)))))
|
||||
|
||||
|
||||
|
@ -254,7 +252,8 @@ If DONT-SAVE, don't prompt to save modified buffers (discarding their changes)."
|
|||
(set-buffer-modified-p nil)))
|
||||
(kill-buffer buffer)
|
||||
(cl-loop for win in windows
|
||||
if (doom-real-buffer-p (window-buffer win))
|
||||
if (and (window-live-p win)
|
||||
(doom-unreal-buffer-p (window-buffer win)))
|
||||
do (with-selected-window win (previous-buffer)))))
|
||||
|
||||
;;;###autoload
|
||||
|
@ -264,10 +263,16 @@ If DONT-SAVE, don't prompt to save modified buffers (discarding their changes)."
|
|||
If PROJECT-P (universal argument), don't close windows and only kill buffers
|
||||
that belong to the current project."
|
||||
(interactive "P")
|
||||
(save-some-buffers)
|
||||
(unless project-p
|
||||
(delete-other-windows))
|
||||
(switch-to-buffer (doom-fallback-buffer))
|
||||
(doom/cleanup-session nil (if project-p (doom-project-buffer-list))))
|
||||
(let ((buffers (if project-p (doom-project-buffer-list) (doom-buffer-list))))
|
||||
(mapc #'kill-buffer buffers)
|
||||
(when (called-interactively-p 'interactive)
|
||||
(message "Killed %s buffers"
|
||||
(- (length buffers)
|
||||
(length (cl-remove-if-not #'buffer-live-p buffers)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/kill-other-buffers (&optional project-p)
|
||||
|
@ -276,13 +281,14 @@ that belong to the current project."
|
|||
If PROJECT-P (universal argument), kill only buffers that belong to the current
|
||||
project."
|
||||
(interactive "P")
|
||||
(let ((buffers (if project-p (doom-project-buffer-list) (doom-buffer-list)))
|
||||
(current-buffer (current-buffer)))
|
||||
(dolist (buf buffers)
|
||||
(unless (eq buf current-buffer)
|
||||
(doom-kill-buffer-and-windows buf)))
|
||||
(let ((buffers
|
||||
(delq (current-buffer)
|
||||
(if project-p (doom-project-buffer-list) (doom-buffer-list)))))
|
||||
(mapc #'doom-kill-buffer-and-windows buffers)
|
||||
(when (called-interactively-p 'interactive)
|
||||
(message "Killed %s buffers" (length buffers)))))
|
||||
(message "Killed %s buffers"
|
||||
(- (length buffers)
|
||||
(length (cl-remove-if-not #'buffer-live-p buffers)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/kill-matching-buffers (pattern &optional project-p)
|
||||
|
@ -293,44 +299,23 @@ project."
|
|||
(interactive
|
||||
(list (read-regexp "Buffer pattern: ")
|
||||
current-prefix-arg))
|
||||
(let* ((buffers (if project-p (doom-project-buffer-list) (doom-buffer-list)))
|
||||
(n (doom-kill-matching-buffers pattern buffers)))
|
||||
(let* ((buffers (if project-p (doom-project-buffer-list) (doom-buffer-list))))
|
||||
(doom-kill-matching-buffers pattern buffers)
|
||||
(when (called-interactively-p 'interactive)
|
||||
(message "Killed %s buffers" n))))
|
||||
(message "Killed %d buffer(s)"
|
||||
(- (length buffers)
|
||||
(length (cl-remove-if-not #'buffer-live-p buffers)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/cleanup-session (arg &optional buffer-list)
|
||||
"Clean up buried buries and orphaned processes in the current workspace. If
|
||||
ALL-P (universal argument), clean them up globally."
|
||||
(defun doom/kill-buried-buffers (&optional project-p)
|
||||
"Kill buffers that are buried.
|
||||
|
||||
If PROJECT-P (universal argument), only kill buried buffers belonging to the
|
||||
current project."
|
||||
(interactive "P")
|
||||
(let ((buffers (doom-buried-buffers buffer-list))
|
||||
(n 0))
|
||||
(dolist (buf buffers)
|
||||
(unless (buffer-modified-p buf)
|
||||
(kill-buffer buf)
|
||||
(cl-incf n)))
|
||||
(when arg
|
||||
(setq n (+ n (doom/cleanup-buffer-processes))))
|
||||
(dolist (hook doom-cleanup-hook)
|
||||
(let ((m (funcall hook)))
|
||||
(when (integerp m)
|
||||
(setq n (+ n m)))))
|
||||
(message "Cleaned up %s buffers" n)
|
||||
n))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/cleanup-buffer-processes ()
|
||||
"Kill all processes that have no visible associated buffers. Return number of
|
||||
processes killed."
|
||||
(interactive)
|
||||
(let ((n 0))
|
||||
(dolist (p (process-list))
|
||||
(let ((process-buffer (process-buffer p)))
|
||||
(when (and (process-live-p p)
|
||||
(not (string= (process-name p) "server"))
|
||||
(or (not process-buffer)
|
||||
(and (bufferp process-buffer)
|
||||
(not (buffer-live-p process-buffer)))))
|
||||
(delete-process p)
|
||||
(cl-incf n))))
|
||||
n))
|
||||
(let ((buffers (doom-buried-buffers (if project-p (doom-project-buffer-list)))))
|
||||
(mapc #'kill-buffer buffers)
|
||||
(when (called-interactively-p 'interactive)
|
||||
(message "Killed %d buffer(s)"
|
||||
(- (length buffers)
|
||||
(length (cl-remove-if-not #'buffer-live-p buffers)))))))
|
||||
|
|
|
@ -3,17 +3,38 @@
|
|||
(require 'core-cli)
|
||||
|
||||
(defun doom--run (command &optional yes)
|
||||
(let ((default-directory doom-emacs-dir)
|
||||
(doom-auto-accept yes))
|
||||
(let ((compilation-buffer-name-function (lambda (_) "*bin/doom*")))
|
||||
(compile (format "bin/doom %s" command) t))
|
||||
(while compilation-in-progress
|
||||
(sit-for 1))
|
||||
(when (y-or-n-p "Reload Doom config?")
|
||||
(doom/reload))
|
||||
(message "Done")))
|
||||
(let* ((default-directory doom-emacs-dir)
|
||||
(doom-auto-accept yes)
|
||||
(buf (get-buffer-create " *bin/doom*"))
|
||||
(wconf (current-window-configuration))
|
||||
(ignore-window-parameters t)
|
||||
(noninteractive t)
|
||||
(standard-output
|
||||
(lambda (char)
|
||||
(with-current-buffer buf
|
||||
(insert char)
|
||||
(when (memq char '(?\n ?\r))
|
||||
(ansi-color-apply-on-region (line-beginning-position -1) (line-end-position))
|
||||
(redisplay))))))
|
||||
(doom-initialize t)
|
||||
(setq doom-modules (doom-modules))
|
||||
(doom-initialize-modules t)
|
||||
(doom-initialize-packages t)
|
||||
(with-current-buffer (switch-to-buffer buf)
|
||||
(erase-buffer)
|
||||
(require 'package)
|
||||
(redisplay)
|
||||
(doom-dispatch command nil)
|
||||
(print! (green "\nDone!"))))
|
||||
(message (format! (green "Done!"))))
|
||||
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//autoloads (&optional yes)
|
||||
"TODO"
|
||||
(interactive "P")
|
||||
(doom--run "autoloads" yes))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//update (&optional yes)
|
||||
"TODO"
|
||||
|
@ -24,7 +45,9 @@
|
|||
(defun doom//upgrade (&optional yes)
|
||||
"TODO"
|
||||
(interactive "P")
|
||||
(doom--run "upgrade" yes))
|
||||
(doom--run "upgrade" yes)
|
||||
(when (y-or-n-p "You must restart Emacs for the upgrade to take effect. Restart?")
|
||||
(doom/restart-and-restore)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//install (&optional yes)
|
||||
|
@ -43,24 +66,3 @@
|
|||
"TODO"
|
||||
(interactive "P")
|
||||
(doom--run "refresh" yes))
|
||||
|
||||
;;;###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 "P")
|
||||
(require 'core-cli)
|
||||
(doom-reload-autoloads force-p)
|
||||
(setq load-path doom-site-load-path)
|
||||
(let (doom-init-p)
|
||||
(doom-initialize))
|
||||
(with-demoted-errors "PRIVATE CONFIG ERROR: %s"
|
||||
(doom-initialize-modules 'force))
|
||||
(run-hook-wrapped 'doom-reload-hook #'doom-try-run-hook)
|
||||
(message "Finished!"))
|
||||
|
|
38
core/autoload/config.el
Normal file
38
core/autoload/config.el
Normal file
|
@ -0,0 +1,38 @@
|
|||
;;; core/autoload/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/open-private-config ()
|
||||
"TODO"
|
||||
(interactive)
|
||||
(unless (file-directory-p doom-private-dir)
|
||||
(make-directory doom-private-dir t))
|
||||
(doom-project-browse doom-private-dir))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/find-file-in-private-config ()
|
||||
"TODO"
|
||||
(interactive)
|
||||
(doom-project-find-file doom-private-dir))
|
||||
|
||||
;;;###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 "P")
|
||||
(require 'core-cli)
|
||||
(doom-reload-autoloads force-p)
|
||||
(setq load-path doom-site-load-path)
|
||||
(let (doom-init-p)
|
||||
(doom-initialize))
|
||||
(with-demoted-errors "PRIVATE CONFIG ERROR: %s"
|
||||
(doom-initialize-modules 'force))
|
||||
(when (bound-and-true-p doom-packages)
|
||||
(doom/reload-packages))
|
||||
(run-hook-wrapped 'doom-reload-hook #'doom-try-run-hook)
|
||||
(message "Finished!"))
|
|
@ -61,8 +61,8 @@ ready to be pasted in a bug report on github."
|
|||
"n/a")
|
||||
(or (ignore-errors
|
||||
(require 'use-package)
|
||||
(cl-loop for (name . plist) in (doom-get-packages :private t)
|
||||
if (use-package-plist-delete (copy-sequence plist) :private)
|
||||
(cl-loop for (name . plist) in (doom-find-packages :private t)
|
||||
if (use-package-plist-delete (copy-sequence plist) :modules)
|
||||
collect (format "%s" (cons name it))
|
||||
else
|
||||
collect (symbol-name name)))
|
||||
|
@ -115,7 +115,7 @@ markdown and copies it to your clipboard, ready to be pasted into bug reports!"
|
|||
branch and commit."
|
||||
(interactive)
|
||||
(require 'vc-git)
|
||||
(print! "Doom v%s (Emacs v%s)\nBranch: %s\nCommit: %s."
|
||||
(print! "Doom v%s (Emacs v%s)\nBranch: %s\nCommit: %s"
|
||||
doom-version
|
||||
emacs-version
|
||||
(or (vc-git--symbolic-ref doom-core-dir)
|
||||
|
@ -139,25 +139,38 @@ pasting into a bug report or discord."
|
|||
|
||||
(defvar doom--sandbox-init-doom-p nil)
|
||||
|
||||
(defun doom--run-vanilla-sandbox (&optional load-doom-p)
|
||||
(defun doom--run-vanilla-sandbox (&optional mode)
|
||||
(interactive)
|
||||
(let ((contents (buffer-string))
|
||||
(file (make-temp-file "doom-sandbox-")))
|
||||
(require 'package)
|
||||
(with-temp-file file
|
||||
(insert
|
||||
(prin1-to-string
|
||||
`(cond (,load-doom-p
|
||||
(setq doom-private-dir "/tmp/does/not/exist"
|
||||
doom-modules ,doom-modules)
|
||||
(load ,user-init-file))
|
||||
((setq package--init-file-ensured t
|
||||
package-user-dir ,package-user-dir
|
||||
package-archives ',package-archives
|
||||
user-emacs-directory ,doom-emacs-dir)
|
||||
(package-initialize))))
|
||||
(macroexp-progn
|
||||
(append `((setq debug-on-error t
|
||||
package--init-file-ensured t
|
||||
package-user-dir ,package-user-dir
|
||||
package-archives ',package-archives
|
||||
user-emacs-directory ,doom-emacs-dir
|
||||
doom-modules ,doom-modules))
|
||||
(pcase mode
|
||||
(`vanilla-doom+ ; Doom core + modules - private config
|
||||
`((setq doom-private-dir "/tmp/does/not/exist")
|
||||
(load-file ,user-init-file)
|
||||
(doom|run-all-startup-hooks)))
|
||||
(`vanilla-doom ; only Doom core
|
||||
`((setq doom-private-dir "/tmp/does/not/exist"
|
||||
doom-init-modules-p t)
|
||||
(load-file ,user-init-file)
|
||||
(doom|run-all-startup-hooks)))
|
||||
(`vanilla ; nothing loaded
|
||||
`((package-initialize)))))))
|
||||
"\n(unwind-protect (progn\n" contents "\n)\n"
|
||||
(format "(delete-file %S))" file)))
|
||||
(let ((args (list "-Q" "-l" file)))
|
||||
(let ((args (if (eq mode 'doom)
|
||||
(list "-l" file)
|
||||
(list "-Q" "-l" file))))
|
||||
(require 'restart-emacs)
|
||||
(condition-case e
|
||||
(cond ((display-graphic-p)
|
||||
|
@ -174,30 +187,58 @@ pasting into a bug report or discord."
|
|||
(delete-file file)
|
||||
(signal (car e) (cdr e)))))))
|
||||
|
||||
(defun doom--run-vanilla-doom-sandbox ()
|
||||
(interactive)
|
||||
(doom--run-vanilla-sandbox t))
|
||||
(fset 'doom--run-vanilla-emacs (lambda! (doom--run-vanilla-sandbox 'vanilla)))
|
||||
(fset 'doom--run-vanilla-doom (lambda! (doom--run-vanilla-sandbox 'vanilla-doom)))
|
||||
(fset 'doom--run-vanilla-doom+ (lambda! (doom--run-vanilla-sandbox 'vanilla-doom+)))
|
||||
(fset 'doom--run-full-doom (lambda! (doom--run-vanilla-sandbox 'doom)))
|
||||
|
||||
(defvar doom-sandbox-emacs-lisp-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map (kbd "C-c C-c") #'doom--run-vanilla-emacs)
|
||||
(define-key map (kbd "C-c C-d") #'doom--run-vanilla-doom)
|
||||
(define-key map (kbd "C-c C-p") #'doom--run-vanilla-doom+)
|
||||
(define-key map (kbd "C-c C-f") #'doom--run-full-doom)
|
||||
(define-key map (kbd "C-c C-k") #'kill-this-buffer)
|
||||
map))
|
||||
|
||||
(define-derived-mode doom-sandbox-emacs-lisp-mode emacs-lisp-mode "Sandbox Elisp"
|
||||
"TODO")
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/open-vanilla-sandbox ()
|
||||
"Open an Emacs Lisp buffer destinated to run in a blank Emacs session (and
|
||||
optionally load only Doom and its modules, without your private config).
|
||||
"Open the Emacs Lisp sandbox.
|
||||
|
||||
This provides a testbed for debugging code without Doom (or your private config)
|
||||
standing in the way, and without sacrificing access to installed packages."
|
||||
This is a test bed for running Emacs Lisp in an instance of Emacs with varying
|
||||
amounts of Doom loaded, including:
|
||||
|
||||
a) vanilla Emacs (nothing loaded),
|
||||
b) vanilla Doom (only Doom core) and
|
||||
c) Doom + modules - your private config.
|
||||
|
||||
This is done without sacrificing access to installed packages. Use the sandbox
|
||||
to reproduce bugs and determine if Doom is to blame."
|
||||
(interactive)
|
||||
(let* ((buffer-name "*doom:vanilla-sandbox*")
|
||||
(exists (get-buffer buffer-name))
|
||||
(buf (get-buffer-create buffer-name)))
|
||||
(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-d") #'doom--run-vanilla-doom-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-d to run it with vanilla Doom loaded / C-c C-k to abort it")
|
||||
(doom-sandbox-emacs-lisp-mode)
|
||||
(setq header-line-format
|
||||
(concat "C-c C-c = vanilla Emacs"
|
||||
" / "
|
||||
"C-c C-d = Doom core"
|
||||
" / "
|
||||
"C-c C-p = Doom core + modules - private config"
|
||||
" / "
|
||||
"C-c C-f = Full Doom"
|
||||
" / "
|
||||
"C-c C-k to abort"))
|
||||
(setq-local default-directory doom-emacs-dir)
|
||||
(unless (buffer-live-p exists)
|
||||
(doom-template-insert "VANILLA_SANDBOX"))
|
||||
(doom-template-insert "VANILLA_SANDBOX")
|
||||
(let ((contents (substitute-command-keys (buffer-string))))
|
||||
(erase-buffer)
|
||||
(insert contents "\n")))
|
||||
(goto-char (point-max)))
|
||||
(pop-to-buffer buf)))
|
||||
|
||||
|
@ -320,3 +361,14 @@ If INIT-FILE is non-nil, profile that instead of USER-INIT-FILE."
|
|||
|
||||
;;;###autoload
|
||||
(advice-add #'esup :override #'doom/profile-emacs)
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/toggle-debug-mode (&optional arg)
|
||||
"Toggle `debug-on-error' and `doom-debug-mode' for verbose logging."
|
||||
(interactive (list (or current-prefix-arg 'toggle)))
|
||||
(let ((value
|
||||
(cond ((eq arg 'toggle) (not doom-debug-mode))
|
||||
((> (prefix-numeric-value arg) 0)))))
|
||||
(setq doom-debug-mode value
|
||||
debug-on-error value)
|
||||
(message "Debug mode %s" (if value "on" "off"))))
|
||||
|
|
|
@ -184,9 +184,9 @@ file if it exists, without confirmation."
|
|||
(when (file-exists-p old-path)
|
||||
(delete-file old-path))
|
||||
(kill-this-buffer)
|
||||
(find-file new-path)
|
||||
(doom--forget-file old-path new-path)
|
||||
(doom--update-file new-path)
|
||||
(find-file new-path)
|
||||
(message "File successfully moved to %s" dest))))
|
||||
(`overwrite-self (error "Cannot overwrite self"))
|
||||
(`aborted (message "Aborted"))
|
||||
|
|
|
@ -1,45 +1,67 @@
|
|||
;;; core/autoload/help.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar doom--module-mode-alist
|
||||
'((c-mode :lang cc)
|
||||
(c++-mode :lang cc)
|
||||
(objc++-mode :lang cc)
|
||||
(java-mode :lang java)
|
||||
(csharp-mode :lang csharp)
|
||||
(clojure-mode :lang clojure)
|
||||
'((dockerfile-mode :tools docker)
|
||||
(haxor-mode :lang assembly)
|
||||
(mips-mode :lang assembly)
|
||||
(nasm-mode :lang assembly)
|
||||
(c-mode :lang cc)
|
||||
(c++-mode :lang cc)
|
||||
(objc++-mode :lang cc)
|
||||
(crystal-mode :lang crystal)
|
||||
(lisp-mode :lang common-lisp)
|
||||
(csharp-mode :lang csharp)
|
||||
(clojure-mode :lang clojure)
|
||||
(graphql-mode :lang data)
|
||||
(toml-mode :lang data)
|
||||
(json-mode :lang data)
|
||||
(yaml-mode :lang data)
|
||||
(csv-mode :lang data)
|
||||
(dhall-mode :lang data)
|
||||
(erlang-mode :lang erlang)
|
||||
(elixir-mode :lang elixir)
|
||||
(elm-mode :lang elm)
|
||||
(emacs-lisp-mode :lang emacs-lisp)
|
||||
(go-mode :lang go)
|
||||
(haskell-mode :lang haskell)
|
||||
(js2-mode :lang javascript)
|
||||
(julia-mode :lang julia)
|
||||
(latex-mode :lang latex)
|
||||
(LaTeX-mode :lang latex)
|
||||
(ledger-mode :lang ledger)
|
||||
(lua-mode :lang lua)
|
||||
(markdown-mode :lang markdown)
|
||||
(gfm-mode :lang markdown)
|
||||
(ocaml-mode :lang ocaml)
|
||||
(org-mode :lang org)
|
||||
(perl-mode :lang perl)
|
||||
(php-mode :lang php)
|
||||
(hack-mode :lang php)
|
||||
(plantuml-mode :lang plantuml)
|
||||
(ess-r-mode :lang ess)
|
||||
(ess-julia-mode :lang ess)
|
||||
(go-mode :lang go)
|
||||
(haskell-mode :lang haskell)
|
||||
(hy-mode :lang hy)
|
||||
(java-mode :lang java)
|
||||
(js2-mode :lang javascript)
|
||||
(rjsx-mode :lang javascript)
|
||||
(typescript-mode :lang javascript)
|
||||
(coffee-mode :lang javascript)
|
||||
(julia-mode :lang julia)
|
||||
(latex-mode :lang latex)
|
||||
(LaTeX-mode :lang latex)
|
||||
(ledger-mode :lang ledger)
|
||||
(lua-mode :lang lua)
|
||||
(markdown-mode :lang markdown)
|
||||
(gfm-mode :lang markdown)
|
||||
(nim-mode :lang nim)
|
||||
(nix-mode :lang nix)
|
||||
(taureg-mode :lang ocaml)
|
||||
(org-mode :lang org)
|
||||
(perl-mode :lang perl)
|
||||
(php-mode :lang php)
|
||||
(hack-mode :lang php)
|
||||
(plantuml-mode :lang plantuml)
|
||||
(purescript-mode :lang purescript)
|
||||
(python-mode :lang python)
|
||||
(python-mode :lang python)
|
||||
(restclient-mode :lang rest)
|
||||
(ruby-mode :lang ruby)
|
||||
(enh-ruby-mode :lang ruby)
|
||||
(rust-mode :lang rust)
|
||||
(scala-mode :lang scala)
|
||||
(sh-mode :lang sh)
|
||||
(swift-mode :lang swift)
|
||||
(typescript-mode :lang typescript)
|
||||
(web-mode :lang web)
|
||||
(css-mode :lang web)
|
||||
(scss-mode :lang web)
|
||||
(sass-mode :lang web)
|
||||
(less-css-mode :lang web)
|
||||
(stylus-mode :lang web))
|
||||
(ruby-mode :lang ruby)
|
||||
(enh-ruby-mode :lang ruby)
|
||||
(rust-mode :lang rust)
|
||||
(scala-mode :lang scala)
|
||||
(sh-mode :lang sh)
|
||||
(swift-mode :lang swift)
|
||||
(web-mode :lang web)
|
||||
(css-mode :lang web)
|
||||
(scss-mode :lang web)
|
||||
(sass-mode :lang web)
|
||||
(less-css-mode :lang web)
|
||||
(stylus-mode :lang web))
|
||||
"TODO")
|
||||
|
||||
|
||||
|
@ -54,16 +76,17 @@
|
|||
collect mode))
|
||||
|
||||
|
||||
|
||||
;;
|
||||
;; Commands
|
||||
|
||||
;;;###autoload
|
||||
(define-obsolete-function-alias 'doom/describe-setting 'doom/describe-setters "2.1.0")
|
||||
(defun doom/describe-autodefs (autodef)
|
||||
"Open the documentation of Doom autodefs.
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/describe-setters (setting)
|
||||
"Open the documentation of Doom functions and configuration macros."
|
||||
What is an autodef? It's a function or macro that is always defined, even if its
|
||||
containing module is disabled (in which case it will safely no-op). This
|
||||
syntactic sugar lets you use them without needing to check if they are
|
||||
available."
|
||||
(interactive
|
||||
(let* ((settings
|
||||
(cl-loop with case-fold-search = nil
|
||||
|
@ -74,42 +97,52 @@
|
|||
(string-match-p "[a-z]!$" sym-name))
|
||||
collect sym))
|
||||
(sym (symbol-at-point))
|
||||
(setting
|
||||
(autodef
|
||||
(completing-read
|
||||
"Describe setter: "
|
||||
;; TODO Could be cleaner (refactor me!)
|
||||
(cl-loop with maxwidth = (apply #'max (mapcar #'length (mapcar #'symbol-name settings)))
|
||||
for def in (sort settings #'string-lessp)
|
||||
if (or (get def 'doom-module)
|
||||
(doom-module-from-path (symbol-file def)))
|
||||
if (get def 'doom-module)
|
||||
collect
|
||||
(format (format "%%-%ds%%s" (+ maxwidth 4))
|
||||
def (propertize (format "%s %s" (car it) (cdr it))
|
||||
'face 'font-lock-comment-face))
|
||||
else if (file-in-directory-p (symbol-file def) doom-core-dir)
|
||||
else if (and (string-match-p "^set-.+!$" (symbol-name def))
|
||||
(symbol-file def)
|
||||
(file-in-directory-p (symbol-file def) doom-core-dir))
|
||||
collect
|
||||
(format (format "%%-%ds%%s" (+ maxwidth 4))
|
||||
def (propertize (format "%s %s" :core (file-name-sans-extension (file-relative-name (symbol-file def) doom-core-dir)))
|
||||
'face 'font-lock-comment-face))
|
||||
else
|
||||
collect (symbol-name def))
|
||||
def (propertize (format "core/%s.el" (file-name-sans-extension (file-relative-name (symbol-file def) doom-core-dir)))
|
||||
'face 'font-lock-comment-face)))
|
||||
nil t
|
||||
(when (and (symbolp sym)
|
||||
(string-match-p "!$" (symbol-name sym)))
|
||||
(symbol-name sym)))))
|
||||
(list (and setting (car (split-string setting " "))))))
|
||||
(or (stringp setting)
|
||||
(functionp setting)
|
||||
(signal 'wrong-type-argument (list '(stringp functionp) setting)))
|
||||
(let ((fn (if (functionp setting)
|
||||
setting
|
||||
(intern-soft setting))))
|
||||
(list (and autodef (car (split-string autodef " "))))))
|
||||
(or (stringp autodef)
|
||||
(functionp autodef)
|
||||
(signal 'wrong-type-argument (list '(stringp functionp) autodef)))
|
||||
(let ((fn (if (functionp autodef)
|
||||
autodef
|
||||
(intern-soft autodef))))
|
||||
(or (fboundp fn)
|
||||
(error "'%s' is not a valid DOOM setting" setting))
|
||||
(error "'%s' is not a valid DOOM autodef" autodef))
|
||||
(if (fboundp 'helpful-callable)
|
||||
(helpful-callable fn)
|
||||
(describe-function fn))))
|
||||
|
||||
;;;###autoload
|
||||
(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
|
||||
(cond ((stringp mode) (intern mode))
|
||||
((symbolp mode) mode)
|
||||
((error "Expected a symbol/string, got a %s" (type-of mode))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/describe-module (category module)
|
||||
"Open the documentation of CATEGORY MODULE.
|
||||
|
@ -162,55 +195,121 @@ current file is in, or d) the module associated with the current major mode (see
|
|||
(cl-check-type module symbol)
|
||||
(or (doom-module-p category module)
|
||||
(error "'%s %s' isn't a valid module" category module))
|
||||
(let ((doc-path (doom-module-path category module "README.org")))
|
||||
(unless (file-exists-p doc-path)
|
||||
(error "There is no documentation for this module (%s)" doc-path))
|
||||
(find-file doc-path)))
|
||||
(doom-project-browse (doom-module-path category module)))
|
||||
|
||||
(defun doom--describe-package-insert-button (label path &optional regexp)
|
||||
(declare (indent defun))
|
||||
(insert-text-button
|
||||
(string-trim label)
|
||||
'face 'link
|
||||
'follow-link t
|
||||
'action
|
||||
`(lambda (_)
|
||||
(unless (file-exists-p ,path)
|
||||
(user-error "Module doesn't exist"))
|
||||
(when (window-dedicated-p)
|
||||
(other-window 1))
|
||||
(let ((buffer (find-file ,path)))
|
||||
(when ,(stringp regexp)
|
||||
(with-current-buffer buffer
|
||||
(goto-char (point-min))
|
||||
(if (re-search-forward ,regexp nil t)
|
||||
(recenter)
|
||||
(message "Couldn't find the config block"))))))))
|
||||
|
||||
;;;###autoload
|
||||
(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."
|
||||
(global-set-key [remap describe-package] #'doom/describe-package)
|
||||
|
||||
(defvar doom--describe-package-list-cache nil)
|
||||
;;;###autoload
|
||||
(defun doom/describe-package (package)
|
||||
"Like `describe-packages', but is Doom aware.
|
||||
|
||||
Only shows installed packages. Includes information about where packages are
|
||||
defined and configured.
|
||||
|
||||
If prefix arg is prsent, refresh the cache."
|
||||
(interactive
|
||||
(list (completing-read "Minor mode: " (doom-active-minor-modes))))
|
||||
(describe-minor-mode-from-symbol
|
||||
(cond ((stringp mode) (intern mode))
|
||||
((symbolp mode) mode)
|
||||
((error "Expected a symbol/string, got a %s" (type-of mode))))))
|
||||
(list
|
||||
(let* ((guess (or (function-called-at-point)
|
||||
(symbol-at-point))))
|
||||
(require 'finder-inf nil t)
|
||||
(require 'core-packages)
|
||||
(doom-initialize-packages)
|
||||
(let ((packages
|
||||
(or (unless current-prefix-arg doom--describe-package-list-cache)
|
||||
(cl-loop for pkg
|
||||
in (cl-delete-duplicates
|
||||
(sort (append (mapcar #'car package-alist)
|
||||
(mapcar #'car package-archive-contents)
|
||||
(mapcar #'car package--builtins))
|
||||
#'string-greaterp))
|
||||
if (assq pkg package-alist)
|
||||
collect (symbol-name pkg)
|
||||
else
|
||||
collect (propertize (symbol-name pkg) 'face 'font-lock-comment-face)))))
|
||||
(unless (memq guess packages)
|
||||
(setq guess nil))
|
||||
(setq doom--describe-package-list-cache packages)
|
||||
(intern
|
||||
(completing-read
|
||||
(if guess
|
||||
(format "Describe package (default %s): "
|
||||
guess)
|
||||
"Describe package: ")
|
||||
packages nil t nil nil
|
||||
(if guess (symbol-name guess))))))))
|
||||
(describe-package package)
|
||||
(save-excursion
|
||||
(with-current-buffer (help-buffer)
|
||||
(let ((inhibit-read-only t))
|
||||
(goto-char (point-min))
|
||||
(when (and (doom-package-installed-p package)
|
||||
(re-search-forward "^ *Status: " nil t))
|
||||
(end-of-line)
|
||||
(let ((indent (make-string (length (match-string 0)) ? )))
|
||||
(insert "\n" indent "Installed by the following Doom modules:\n")
|
||||
(dolist (m (get package 'doom-module))
|
||||
(insert indent)
|
||||
(doom--describe-package-insert-button
|
||||
(format " %s %s" (car m) (or (cdr m) ""))
|
||||
(pcase (car m)
|
||||
(:core doom-core-dir)
|
||||
(:private doom-private-dir)
|
||||
(category (doom-module-path category (cdr m)))))
|
||||
(insert "\n"))
|
||||
|
||||
(package--print-help-section "Source")
|
||||
(pcase (doom-package-backend package)
|
||||
(`elpa (insert "[M]ELPA"))
|
||||
(`quelpa (insert (format "QUELPA %s" (prin1-to-string (doom-package-prop package :recipe)))))
|
||||
(`emacs (insert "Built-in")))
|
||||
(insert "\n")
|
||||
|
||||
(package--print-help-section "Configs")
|
||||
(dolist (file (get package 'doom-files))
|
||||
(doom--describe-package-insert-button
|
||||
(abbreviate-file-name file)
|
||||
file
|
||||
(format "\\((\\(:?after!\\|def-package!\\)[ \t\n]*%s\\|^[ \t]*;; `%s'$\\)"
|
||||
package package))
|
||||
(insert "\n" indent))
|
||||
(delete-char -1)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/what-face (arg &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 "P")
|
||||
(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 (or (listp face) arg)
|
||||
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
|
||||
if arg concat (concat (symbol-name ov) " ")
|
||||
else concat (concat (propertize (symbol-name ov) 'face ov) " "))
|
||||
"n/a")))
|
||||
(t
|
||||
(and (or faces overlays)
|
||||
(list faces overlays))))))
|
||||
(defun doom/describe-symbol (symbol)
|
||||
"Show help for SYMBOL, a variable, function or macro."
|
||||
(interactive
|
||||
(list (helpful--read-symbol "Symbol: " #'helpful--bound-p)))
|
||||
(let* ((sym (intern-soft symbol))
|
||||
(bound (boundp sym))
|
||||
(fbound (fboundp sym)))
|
||||
(cond ((and sym bound (not fbound))
|
||||
(helpful-variable sym))
|
||||
((and sym fbound (not bound))
|
||||
(helpful-callable sym))
|
||||
((apropos (format "^%s\$" symbol)))
|
||||
((apropos (format "%s" symbol))))))
|
||||
|
||||
;;;###autoload
|
||||
(defalias 'doom/help 'doom/open-manual)
|
||||
|
@ -219,4 +318,14 @@ whose car is the list of faces and cadr is the list of overlay faces."
|
|||
(defun doom/open-manual ()
|
||||
"TODO"
|
||||
(interactive)
|
||||
(find-file (expand-file-name "index.org" doom-docs-dir)))
|
||||
(user-error "This command isn't implemented yet")
|
||||
;; (find-file (expand-file-name "index.org" doom-docs-dir))
|
||||
)
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/open-news ()
|
||||
"TODO"
|
||||
(interactive)
|
||||
(user-error "This command isn't implemented yet")
|
||||
;; (find-file (expand-file-name (concat "news/" doom-version) doom-docs-dir))
|
||||
)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
;;; core/autoload/line-numbers.el -*- lexical-binding: t; -*-
|
||||
;;;###if (not EMACS26+)
|
||||
;;;###if (version< emacs-version "26.1")
|
||||
|
||||
;; This was lifted out of the display-line-numbers library in Emacs 26.1 and
|
||||
;; modified to use nlinum for Emacs 25.x users. It should be removed should
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
"TODO")
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-ansi-apply (style text)
|
||||
(defun doom-color-apply (style text)
|
||||
"Apply CODE to formatted MESSAGE with ARGS. CODE is derived from any of
|
||||
`doom-message-fg', `doom-message-bg' or `doom-message-fx'.
|
||||
|
||||
|
@ -53,19 +53,27 @@ Otherwise, it maps colors to a term-color-* face."
|
|||
`(:foreground ,(face-foreground (caddr (assq style doom-ansi-alist)))))
|
||||
((cddr (assq style doom-ansi-alist)))))))))
|
||||
|
||||
(defun doom--short-color-replace (forms)
|
||||
"Replace color-name functions with calls to `doom-color-apply'."
|
||||
(cond ((null forms) nil)
|
||||
((listp forms)
|
||||
(append (cond ((not (symbolp (car forms)))
|
||||
(list (doom--short-color-replace (car forms))))
|
||||
((assq (car forms) doom-ansi-alist)
|
||||
`(doom-color-apply ',(car forms)))
|
||||
((eq (car forms) 'color)
|
||||
(pop forms)
|
||||
`(doom-color-apply ,(car forms)))
|
||||
((list (car forms))))
|
||||
(doom--short-color-replace (cdr forms))
|
||||
nil))
|
||||
(forms)))
|
||||
|
||||
;;;###autoload
|
||||
(defmacro format! (message &rest args)
|
||||
"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
|
||||
(,@(mapcar (lambda (rule) `(,(car rule)
|
||||
(lambda (message)
|
||||
(doom-ansi-apply ',(car rule) message))))
|
||||
doom-ansi-alist)
|
||||
(color
|
||||
(lambda (code format)
|
||||
(doom-ansi-apply code format))))
|
||||
(format ,message ,@args)))
|
||||
`(format ,@(doom--short-color-replace `(,message ,@args))))
|
||||
|
||||
;;;###autoload
|
||||
(defmacro print! (message &rest args)
|
||||
|
@ -79,8 +87,5 @@ Can be colored using (color ...) blocks:
|
|||
(print! (green \"Great %s!\") \"success\")
|
||||
|
||||
Uses faces in interactive sessions and ANSI codes otherwise."
|
||||
`(if (not noninteractive)
|
||||
(message (format! ,message ,@args))
|
||||
;; princ prints to stdout, message to stderr
|
||||
(princ (format! ,message ,@args))
|
||||
(terpri)))
|
||||
`(progn (princ (format! ,message ,@args))
|
||||
(terpri)))
|
||||
|
|
|
@ -40,8 +40,9 @@
|
|||
|
||||
;;;###autoload
|
||||
(defun doom-package-backend (name &optional noerror)
|
||||
"Get which backend the package NAME was installed with. Can either be elpa or
|
||||
quelpa. Throws an error if NOERROR is nil and the package isn't installed."
|
||||
"Get which backend the package NAME was installed with. Can either be elpa,
|
||||
quelpa or emacs (built-in). Throws an error if NOERROR is nil and the package
|
||||
isn't installed."
|
||||
(cl-check-type name symbol)
|
||||
(cond ((assq name quelpa-cache) 'quelpa)
|
||||
((assq name package-alist) 'elpa)
|
||||
|
@ -96,7 +97,6 @@ list of the package."
|
|||
"Return t if a package named NAME (a symbol) has a new backend than what it
|
||||
was installed with. Returns nil otherwise, or if package isn't installed."
|
||||
(cl-check-type name symbol)
|
||||
(doom-initialize-packages)
|
||||
(and (package-installed-p name)
|
||||
(let* ((plist (cdr (assq name doom-packages)))
|
||||
(old-backend (doom-package-backend name 'noerror))
|
||||
|
@ -108,7 +108,6 @@ was installed with. Returns nil otherwise, or if package isn't installed."
|
|||
"Return t if a package named NAME (a symbol) has a different recipe than it
|
||||
was installed with."
|
||||
(cl-check-type name symbol)
|
||||
(doom-initialize-packages)
|
||||
(and (package-installed-p name)
|
||||
(when-let* ((quelpa-recipe (assq name quelpa-cache))
|
||||
(doom-recipe (assq name doom-packages)))
|
||||
|
@ -116,15 +115,16 @@ was installed with."
|
|||
(cdr (plist-get (cdr doom-recipe) :recipe)))))))
|
||||
|
||||
;;;###autoload
|
||||
(cl-defun doom-get-packages (&key (installed 'any)
|
||||
(private 'any)
|
||||
(disabled 'any)
|
||||
(pinned 'any)
|
||||
(ignored 'any)
|
||||
(sort t)
|
||||
changed
|
||||
backend
|
||||
deps)
|
||||
(cl-defun doom-find-packages (&key (installed 'any)
|
||||
(private 'any)
|
||||
(disabled 'any)
|
||||
(pinned 'any)
|
||||
(ignored 'any)
|
||||
(core 'any)
|
||||
sort
|
||||
changed
|
||||
backend
|
||||
deps)
|
||||
"Retrieves a list of primary packages (i.e. non-dependencies). Each element is
|
||||
a cons cell, whose car is the package symbol and whose cdr is the quelpa recipe
|
||||
(if any).
|
||||
|
@ -132,76 +132,146 @@ a cons cell, whose car is the package symbol and whose cdr is the quelpa recipe
|
|||
You can build a filtering criteria using one or more of the following
|
||||
properties:
|
||||
|
||||
:backend BACKEND
|
||||
Can be 'quelpa, 'elpa or 'emacs
|
||||
:installed BOOL
|
||||
Only return installed packages (t) or uninstalled packages (nil)
|
||||
:private BOOL
|
||||
Only return private packages (t) or non-private packages (nil)
|
||||
:disabled BOOL
|
||||
Only return packages that are disabled (t) or otherwise (nil)
|
||||
:ignored BOOL
|
||||
Only return packages that are ignored (t) or otherwise (nil)
|
||||
:backend 'quelpa|'elpa|'emacs|'any
|
||||
Include packages installed through 'quelpa, 'elpa or 'emacs. 'any is the
|
||||
wildcard.
|
||||
:installed BOOL|'any
|
||||
t = only include installed packages
|
||||
nil = exclude installed packages
|
||||
:private BOOL|'any
|
||||
t = only include user-installed packages
|
||||
nil = exclude user-installed packages
|
||||
:core BOOL|'any
|
||||
t = only include Doom core packages
|
||||
nil = exclude Doom core packages
|
||||
:disabled BOOL|'any
|
||||
t = only include disabled packages
|
||||
nil = exclude disabled packages
|
||||
:ignored BOOL|'any
|
||||
t = only include ignored packages
|
||||
nil = exclude ignored packages
|
||||
:pinned BOOL|ARCHIVE
|
||||
Only return packages that are pinned (t), not pinned (nil) or pinned to a
|
||||
specific archive (stringp)
|
||||
:deps BOOL
|
||||
Includes the package's dependencies (t).
|
||||
Includes the package's dependencies (t) or not (nil).
|
||||
|
||||
The resulting list is sorted unless :sort nil is passed to this function.
|
||||
|
||||
Warning: this function is expensive, as it re-evaluates your all packages.el
|
||||
files."
|
||||
(doom-initialize-packages)
|
||||
(cl-remove-duplicates
|
||||
(cl-loop with packages = (append (mapcar #'list doom-core-packages)
|
||||
doom-packages)
|
||||
for (sym . plist)
|
||||
in (if sort
|
||||
(cl-sort (copy-sequence packages) #'string-lessp :key #'car)
|
||||
packages)
|
||||
if (and (or (not backend)
|
||||
(eq (doom-package-backend sym t) backend))
|
||||
(or (eq ignored 'any)
|
||||
(let* ((form (plist-get plist :ignore))
|
||||
(value (eval form)))
|
||||
(if ignored value (not value))))
|
||||
(or (eq disabled 'any)
|
||||
(if disabled
|
||||
(plist-get plist :disable)
|
||||
(not (plist-get plist :disable))))
|
||||
(or (eq installed 'any)
|
||||
(if installed
|
||||
(doom-package-installed-p sym)
|
||||
(not (doom-package-installed-p sym))))
|
||||
(or (eq private 'any)
|
||||
(if private
|
||||
(plist-get plist :private)
|
||||
(not (plist-get plist :private))))
|
||||
(or (eq pinned 'any)
|
||||
(cond ((eq pinned 't)
|
||||
(plist-get plist :pin))
|
||||
((null pinned)
|
||||
(not (plist-get plist :pin)))
|
||||
((equal (plist-get plist :pin) pinned)))))
|
||||
collect (cons sym plist)
|
||||
and if (and deps (not (package-built-in-p sym)))
|
||||
nconc
|
||||
(cl-loop for pkg in (doom-get-dependencies-for sym 'recursive 'noerror)
|
||||
if (or (eq installed 'any)
|
||||
(if installed
|
||||
(doom-package-installed-p pkg)
|
||||
(not (doom-package-installed-p pkg))))
|
||||
collect (cons pkg (cdr (assq pkg doom-packages)))))
|
||||
:key #'car))
|
||||
(cl-loop with packages = doom-packages
|
||||
for (sym . plist)
|
||||
in (if sort
|
||||
(cl-sort (copy-sequence doom-packages) #'string-lessp :key #'car)
|
||||
packages)
|
||||
if (and (or (not backend)
|
||||
(eq (doom-package-backend sym t) backend))
|
||||
(or (eq ignored 'any)
|
||||
(let* ((form (plist-get plist :ignore))
|
||||
(value (eval form)))
|
||||
(if ignored value (not value))))
|
||||
(or (eq disabled 'any)
|
||||
(if disabled
|
||||
(plist-get plist :disable)
|
||||
(not (plist-get plist :disable))))
|
||||
(or (eq installed 'any)
|
||||
(if installed
|
||||
(doom-package-installed-p sym)
|
||||
(not (doom-package-installed-p sym))))
|
||||
(or (eq private 'any)
|
||||
(let ((modules (plist-get plist :modules)))
|
||||
(if private
|
||||
(assq :private modules)
|
||||
(not (assq :private modules)))))
|
||||
(or (eq core 'any)
|
||||
(let ((modules (plist-get plist :modules)))
|
||||
(if core
|
||||
(assq :core modules)
|
||||
(not (assq :core modules)))))
|
||||
(or (eq pinned 'any)
|
||||
(cond ((eq pinned 't)
|
||||
(plist-get plist :pin))
|
||||
((null pinned)
|
||||
(not (plist-get plist :pin)))
|
||||
((equal (plist-get plist :pin) pinned)))))
|
||||
collect (cons sym plist)
|
||||
and if (and deps (not (package-built-in-p sym)))
|
||||
nconc
|
||||
(cl-loop for pkg in (doom-get-dependencies-for sym 'recursive 'noerror)
|
||||
if (or (eq installed 'any)
|
||||
(if installed
|
||||
(doom-package-installed-p pkg)
|
||||
(not (doom-package-installed-p pkg))))
|
||||
collect (cons pkg (cdr (assq pkg doom-packages))))))
|
||||
|
||||
(defun doom--read-module-packages-file (file &optional raw noerror)
|
||||
(with-temp-buffer ; prevent buffer-local settings from propagating
|
||||
(condition-case e
|
||||
(if (not raw)
|
||||
(load file noerror t t)
|
||||
(when (file-readable-p file)
|
||||
(insert-file-contents file)
|
||||
(while (re-search-forward "(package! " nil t)
|
||||
(save-excursion
|
||||
(goto-char (match-beginning 0))
|
||||
(cl-destructuring-bind (name . plist) (cdr (sexp-at-point))
|
||||
(push (cons name
|
||||
(plist-put plist :modules
|
||||
(cond ((file-in-directory-p file doom-private-dir)
|
||||
(list :private))
|
||||
((file-in-directory-p file doom-core-dir)
|
||||
(list :core))
|
||||
((doom-module-from-path file)))))
|
||||
doom-packages))))))
|
||||
((debug error)
|
||||
(signal 'doom-package-error
|
||||
(list (or (doom-module-from-path file)
|
||||
'(:private . packages))
|
||||
e))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-package-list (&optional all-p)
|
||||
"Retrieve a list of explicitly declared packages from enabled modules.
|
||||
|
||||
This excludes core packages listed in `doom-core-packages'.
|
||||
|
||||
If ALL-P, gather packages unconditionally across all modules, including disabled
|
||||
ones."
|
||||
(let ((noninteractive t)
|
||||
(doom--stage 'packages)
|
||||
(doom-modules (doom-modules))
|
||||
doom-packages
|
||||
doom-disabled-packages
|
||||
package-pinned-packages)
|
||||
(doom--read-module-packages-file (expand-file-name "packages.el" doom-core-dir) all-p)
|
||||
(let ((private-packages (expand-file-name "packages.el" doom-private-dir)))
|
||||
(unless all-p
|
||||
;; We load the private packages file twice to ensure disabled packages
|
||||
;; are seen ASAP, and a second time to ensure privately overridden
|
||||
;; packages are properly overwritten.
|
||||
(doom--read-module-packages-file private-packages nil t))
|
||||
(if all-p
|
||||
(mapc #'doom--read-module-packages-file
|
||||
(doom-files-in doom-modules-dir
|
||||
:depth 2
|
||||
:full t
|
||||
:match "/packages\\.el$"))
|
||||
(cl-loop for key being the hash-keys of doom-modules
|
||||
for path = (doom-module-path (car key) (cdr key) "packages.el")
|
||||
for doom--current-module = key
|
||||
do (doom--read-module-packages-file path nil t)))
|
||||
(doom--read-module-packages-file private-packages all-p t))
|
||||
(append (cl-loop for package in doom-core-packages
|
||||
collect (list package :modules '((:core internal))))
|
||||
(nreverse doom-packages))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-get-package-alist ()
|
||||
"Returns a list of all desired packages, their dependencies and their desc
|
||||
objects, in the order of their `package! blocks.'"
|
||||
(doom-initialize-packages)
|
||||
(cl-remove-duplicates
|
||||
(cl-loop for name in (append doom-core-packages (mapcar #'car doom-packages))
|
||||
(cl-loop for name in (mapcar #'car doom-packages)
|
||||
if (assq name package-alist)
|
||||
nconc (cl-loop for dep in (package--get-deps name)
|
||||
if (assq dep package-alist)
|
||||
|
@ -244,49 +314,46 @@ 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 t)
|
||||
(doom-refresh-packages-maybe doom-debug-mode)
|
||||
(require 'async)
|
||||
(let (quelpa-pkgs elpa-pkgs)
|
||||
;; Separate quelpa from elpa packages
|
||||
(dolist (pkg (mapcar #'car package-alist))
|
||||
(when (and (or (not (doom-package-prop pkg :freeze 'eval))
|
||||
include-frozen-p)
|
||||
(not (doom-package-prop pkg :ignore 'eval))
|
||||
(not (doom-package-different-backend-p pkg)))
|
||||
(push pkg
|
||||
(if (eq (doom-package-backend pkg) 'quelpa)
|
||||
quelpa-pkgs
|
||||
elpa-pkgs))))
|
||||
(let-alist
|
||||
(seq-group-by
|
||||
#'doom-package-backend
|
||||
(cl-loop for package in (mapcar #'car package-alist)
|
||||
when (and (or (not (doom-package-prop package :freeze 'eval))
|
||||
include-frozen-p)
|
||||
(not (doom-package-prop package :ignore 'eval))
|
||||
(not (doom-package-different-backend-p package)))
|
||||
collect package))
|
||||
;; The bottleneck in this process is quelpa's version checks, so check them
|
||||
;; asynchronously.
|
||||
(let (futures)
|
||||
(dolist (pkg quelpa-pkgs)
|
||||
(when doom-debug-mode
|
||||
(message "New thread for: %s" pkg))
|
||||
(push (async-start
|
||||
`(lambda ()
|
||||
(let ((gc-cons-threshold ,doom-gc-cons-upper-limit)
|
||||
(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)
|
||||
(user-emacs-directory ,user-emacs-directory)
|
||||
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
|
||||
(append (mapcar #'doom-package-outdated-p elpa-pkgs)
|
||||
(mapcar #'async-get (reverse futures)))))))
|
||||
(cl-loop with partitions = (min 2 (/ (length .quelpa) 4))
|
||||
for package-list in (seq-partition .quelpa partitions)
|
||||
do (doom-log "New thread for: %s" package-list)
|
||||
collect
|
||||
(async-start
|
||||
`(lambda ()
|
||||
(let ((gc-cons-threshold ,doom-gc-cons-upper-limit)
|
||||
(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)
|
||||
(user-emacs-directory ,user-emacs-directory)
|
||||
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)
|
||||
(delq nil (mapcar #'doom-package-outdated-p ',package-list)))))
|
||||
into futures
|
||||
finally return
|
||||
(append (delq nil (mapcar #'doom-package-outdated-p .elpa))
|
||||
(mapcan #'async-get futures)
|
||||
nil))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-get-orphaned-packages ()
|
||||
|
@ -295,7 +362,7 @@ depended on.
|
|||
|
||||
Used by `doom-packages-autoremove'."
|
||||
(let ((package-selected-packages
|
||||
(mapcar #'car (doom-get-packages :ignored nil :disabled nil))))
|
||||
(mapcar #'car (doom-find-packages :ignored nil :disabled nil))))
|
||||
(append (package--removable-packages)
|
||||
(cl-loop for pkg in package-selected-packages
|
||||
if (and (doom-package-different-backend-p pkg)
|
||||
|
@ -303,22 +370,17 @@ Used by `doom-packages-autoremove'."
|
|||
collect pkg))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-get-missing-packages (&optional include-ignored-p)
|
||||
(defun doom-get-missing-packages ()
|
||||
"Return a list of requested packages that aren't installed or built-in, but
|
||||
are enabled (with a `package!' directive). Each element is a list whose CAR is
|
||||
the package symbol, and whose CDR is a plist taken from that package's
|
||||
`package!' declaration.
|
||||
|
||||
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)
|
||||
(cl-loop for (name . plist)
|
||||
in (doom-get-packages :ignored (if include-ignored-p 'any)
|
||||
:disabled nil
|
||||
:deps t
|
||||
:sort nil)
|
||||
in (doom-find-packages :ignored nil
|
||||
:disabled nil
|
||||
:deps t)
|
||||
if (and (or (plist-get plist :pin)
|
||||
(not (package-built-in-p name)))
|
||||
(or (not (doom-package-installed-p name))
|
||||
|
@ -343,7 +405,6 @@ Used by `doom-packages-install'."
|
|||
"Installs package NAME with optional quelpa RECIPE (see `quelpa-recipe' for an
|
||||
example; the package name can be omitted)."
|
||||
(cl-check-type name symbol)
|
||||
(doom-initialize-packages)
|
||||
(when (and (package-installed-p name)
|
||||
(not (package-built-in-p name)))
|
||||
(if (or (doom-package-different-backend-p name)
|
||||
|
@ -362,6 +423,7 @@ example; the package name can be omitted)."
|
|||
(package-install name))
|
||||
(if (not (package-installed-p name))
|
||||
(doom--delete-package-files name)
|
||||
(add-to-list 'package-selected-packages name nil 'eq)
|
||||
(setf (alist-get name doom-packages) plist)
|
||||
name)))
|
||||
|
||||
|
@ -370,7 +432,6 @@ example; the package name can be omitted)."
|
|||
"Updates package NAME (a symbol) if it is out of date, using quelpa or
|
||||
package.el as appropriate."
|
||||
(cl-check-type name symbol)
|
||||
(doom-initialize-packages)
|
||||
(unless (package-installed-p name)
|
||||
(error "%s isn't installed" name))
|
||||
(when (doom-package-different-backend-p name)
|
||||
|
@ -401,7 +462,6 @@ package.el as appropriate."
|
|||
(defun doom-delete-package (name &optional force-p)
|
||||
"Uninstalls package NAME if it exists, and clears it from `quelpa-cache'."
|
||||
(cl-check-type name symbol)
|
||||
(doom-initialize-packages)
|
||||
(unless (package-installed-p name)
|
||||
(user-error "%s isn't installed" name))
|
||||
(let ((inhibit-message (not doom-debug-mode))
|
||||
|
@ -419,6 +479,14 @@ package.el as appropriate."
|
|||
;;
|
||||
;; Interactive commands
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/reload-packages ()
|
||||
"Reload `doom-packages', `package' and `quelpa'."
|
||||
(interactive)
|
||||
(message "Reloading packages")
|
||||
(doom-initialize-packages t)
|
||||
(message "Reloading packages...DONE"))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/update-package (pkg)
|
||||
"Prompts the user with a list of outdated packages and updates the selected
|
||||
|
@ -436,7 +504,6 @@ calls."
|
|||
(unless name
|
||||
(user-error "'%s' is already up-to-date" selection))
|
||||
(list (assq name packages))))
|
||||
(doom-initialize-packages)
|
||||
(cl-destructuring-bind (package old-version new-version) pkg
|
||||
(if-let* ((desc (doom-package-outdated-p package)))
|
||||
(let ((old-v-str (package-version-join old-version))
|
||||
|
@ -456,7 +523,6 @@ calls."
|
|||
;;;###autoload
|
||||
(defun doom*package-delete (desc &rest _)
|
||||
"Update `quelpa-cache' upon a successful `package-delete'."
|
||||
(doom-initialize-packages)
|
||||
(let ((name (package-desc-name desc)))
|
||||
(unless (package-installed-p name)
|
||||
(when-let* ((spec (assq name quelpa-cache)))
|
||||
|
@ -474,8 +540,7 @@ calls."
|
|||
|
||||
;; Replace with Doom variants
|
||||
;;;###autoload
|
||||
(advice-add #'package-autoremove :override (λ! (doom-packages-autoremove current-prefix-arg)))
|
||||
(advice-add #'package-autoremove :override #'doom//autoremove)
|
||||
|
||||
;;;###autoload
|
||||
(advice-add #'package-install-selected-packages :override (λ! (doom-packages-install current-prefix-arg)))
|
||||
|
||||
(advice-add #'package-install-selected-packages :override #'doom//install)
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
;;; core/autoload/projects.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(autoload 'projectile-relevant-known-projects "projectile")
|
||||
|
||||
|
||||
;;
|
||||
;; Macros
|
||||
|
||||
|
@ -33,6 +37,28 @@ they are absolute."
|
|||
(dolist (fn projectile-project-root-files-functions)
|
||||
(remhash (format "%s-%s" fn default-directory) projectile-project-root-cache)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/find-file-in-other-project (project-root)
|
||||
"Preforms `projectile-find-file' in a known project of your choosing."
|
||||
(interactive
|
||||
(list
|
||||
(completing-read "Find file in project: " (projectile-relevant-known-projects)
|
||||
nil nil nil nil (doom-project-root))))
|
||||
(unless (file-directory-p project-root)
|
||||
(error "Project directory '%s' doesn't exist" project-root))
|
||||
(doom-project-find-file project-root))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/browse-in-other-project (project-root)
|
||||
"Preforms `find-file' in a known project of your choosing."
|
||||
(interactive
|
||||
(list
|
||||
(completing-read "Browse in project: " (projectile-relevant-known-projects)
|
||||
nil nil nil nil (doom-project-root))))
|
||||
(unless (file-directory-p project-root)
|
||||
(error "Project directory '%s' doesn't exist" project-root))
|
||||
(doom-project-browse project-root))
|
||||
|
||||
|
||||
;;
|
||||
;; Library
|
||||
|
|
119
core/autoload/sessions.el
Normal file
119
core/autoload/sessions.el
Normal file
|
@ -0,0 +1,119 @@
|
|||
;;; core/autoload/sessions.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;
|
||||
;;; Helpers
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-save-session (&optional file)
|
||||
"TODO"
|
||||
(setq file (expand-file-name (or file (doom-session-file))))
|
||||
(cond ((require 'persp-mode nil t)
|
||||
(unless persp-mode (persp-mode +1))
|
||||
(setq persp-auto-save-opt 0)
|
||||
(persp-save-state-to-file file))
|
||||
((and (require 'frameset nil t)
|
||||
(require 'restart-emacs nil t))
|
||||
(let ((frameset-filter-alist (append '((client . restart-emacs--record-tty-file))
|
||||
frameset-filter-alist))
|
||||
(desktop-base-file-name (file-name-nondirectory file))
|
||||
(desktop-dirname (file-name-directory file))
|
||||
(desktop-restore-eager t)
|
||||
desktop-file-modtime)
|
||||
(make-directory desktop-dirname t)
|
||||
(desktop-save desktop-dirname t)))
|
||||
((error "No session backend to save session with"))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-load-session (&optional file)
|
||||
"TODO"
|
||||
(setq file (expand-file-name (or file (doom-session-file))))
|
||||
(message "Attempting to load %s" file)
|
||||
(cond ((require 'persp-mode nil t)
|
||||
(unless persp-mode (persp-mode +1))
|
||||
(persp-load-state-from-file file))
|
||||
((and (require 'frameset nil t)
|
||||
(require 'restart-emacs nil t))
|
||||
(restart-emacs--restore-frames-using-desktop file))
|
||||
((error "No session backend to load session with"))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-session-file ()
|
||||
"TODO"
|
||||
(cond ((require 'persp-mode nil t)
|
||||
(expand-file-name persp-auto-save-fname persp-save-dir))
|
||||
((require 'desktop nil t)
|
||||
(desktop-full-file-name))
|
||||
((error "No session backend available"))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Command line switch
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-restore-session-handler (&rest _)
|
||||
"TODO"
|
||||
(add-hook 'window-setup-hook #'doom-load-session 'append))
|
||||
|
||||
;;;###autoload
|
||||
(add-to-list 'command-switch-alist (cons "--restore" #'doom-restore-session-handler))
|
||||
|
||||
|
||||
;;
|
||||
;;; Commands
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/quickload-session ()
|
||||
"TODO"
|
||||
(interactive)
|
||||
(message "Restoring session...")
|
||||
(doom-load-session)
|
||||
(message "Session restored. Welcome back."))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/quicksave-session ()
|
||||
"TODO"
|
||||
(interactive)
|
||||
(message "Saving session")
|
||||
(doom-save-session)
|
||||
(message "Saving session...DONE"))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/load-session (file)
|
||||
"TODO"
|
||||
(interactive
|
||||
(let ((session-file (doom-session-file)))
|
||||
(list (or (read-file-name "Session to restore: "
|
||||
(file-name-directory session-file)
|
||||
nil t
|
||||
(file-name-nondirectory session-file))
|
||||
(user-error "No session selected. Aborting")))))
|
||||
(unless file
|
||||
(error "No session file selected"))
|
||||
(message "Loading '%s' session" file)
|
||||
(doom-load-session file))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/save-session (file)
|
||||
"TODO"
|
||||
(interactive
|
||||
(let ((session-file (doom-session-file)))
|
||||
(list (or (read-file-name "Save session to: "
|
||||
(file-name-directory session-file)
|
||||
nil nil
|
||||
(file-name-nondirectory session-file))
|
||||
(user-error "No session selected. Aborting")))))
|
||||
(unless file
|
||||
(error "No session file selected"))
|
||||
(message "Saving '%s' session" file)
|
||||
(doom-save-session file))
|
||||
|
||||
;;;###autoload
|
||||
(defalias 'doom/restart #'restart-emacs)
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/restart-and-restore (&optional debug)
|
||||
"TODO"
|
||||
(interactive "P")
|
||||
(doom/quicksave-session)
|
||||
(restart-emacs
|
||||
(delq nil (list (if debug "--debug-init") "--restore"))))
|
|
@ -1,4 +1,4 @@
|
|||
;;; core/autoload/editor.el -*- lexical-binding: t; -*-
|
||||
;;; core/autoload/text.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-surrounded-p (pair &optional inline balanced)
|
||||
|
@ -108,7 +108,7 @@ afterwards, kill line to beginning of line."
|
|||
(interactive)
|
||||
(let ((empty-line-p (save-excursion (beginning-of-line)
|
||||
(looking-at-p "[ \t]*$"))))
|
||||
(funcall (if (featurep 'evil)
|
||||
(funcall (if (fboundp 'evil-delete)
|
||||
#'evil-delete
|
||||
#'delete-region)
|
||||
(point-at-bol) (point))
|
||||
|
@ -132,30 +132,6 @@ opposite indentation style."
|
|||
(tabify beg end)
|
||||
(untabify beg end))))
|
||||
|
||||
(defvar-local doom--buffer-narrowed-origin nil)
|
||||
;;;###autoload
|
||||
(defun doom/clone-and-narrow-buffer (beg end &optional clone-p)
|
||||
"Restrict editing in this buffer to the current region, indirectly. With CLONE-P,
|
||||
clone the buffer and hard-narrow the selection. If mark isn't active, then widen
|
||||
the buffer (if narrowed).
|
||||
|
||||
Inspired from http://demonastery.org/2013/04/emacs-evil-narrow-region/"
|
||||
(interactive "rP")
|
||||
(cond ((or (region-active-p)
|
||||
(and beg end))
|
||||
(deactivate-mark)
|
||||
(when clone-p
|
||||
(let ((old-buf (current-buffer)))
|
||||
(switch-to-buffer (clone-indirect-buffer nil nil))
|
||||
(setq doom--buffer-narrowed-origin old-buf)))
|
||||
(narrow-to-region beg end))
|
||||
(doom--buffer-narrowed-origin
|
||||
(kill-this-buffer)
|
||||
(switch-to-buffer doom--buffer-narrowed-origin)
|
||||
(setq doom--buffer-narrowed-origin nil))
|
||||
(t
|
||||
(widen))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/delete-trailing-newlines ()
|
||||
"Trim trailing newlines.
|
|
@ -163,6 +163,30 @@ OPACITY is an integer between 0 to 100, inclusive."
|
|||
100))))
|
||||
(set-frame-parameter nil 'alpha opacity))
|
||||
|
||||
(defvar-local doom--buffer-narrowed-origin nil)
|
||||
;;;###autoload
|
||||
(defun doom/clone-and-narrow-buffer (beg end &optional clone-p)
|
||||
"Restrict editing in this buffer to the current region, indirectly. With CLONE-P,
|
||||
clone the buffer and hard-narrow the selection. If mark isn't active, then widen
|
||||
the buffer (if narrowed).
|
||||
|
||||
Inspired from http://demonastery.org/2013/04/emacs-evil-narrow-region/"
|
||||
(interactive "rP")
|
||||
(cond ((or (region-active-p)
|
||||
(and beg end))
|
||||
(deactivate-mark)
|
||||
(when clone-p
|
||||
(let ((old-buf (current-buffer)))
|
||||
(switch-to-buffer (clone-indirect-buffer nil nil))
|
||||
(setq doom--buffer-narrowed-origin old-buf)))
|
||||
(narrow-to-region beg end))
|
||||
(doom--buffer-narrowed-origin
|
||||
(kill-this-buffer)
|
||||
(switch-to-buffer doom--buffer-narrowed-origin)
|
||||
(setq doom--buffer-narrowed-origin nil))
|
||||
(t
|
||||
(widen))))
|
||||
|
||||
|
||||
;;
|
||||
;; Modes
|
||||
|
|
|
@ -37,9 +37,8 @@ it exists."
|
|||
(print! (bold (green "\nFinished!")))
|
||||
(message "If you have a running Emacs Session, you will need to restart it or")
|
||||
(message "reload Doom for changes to take effect:\n")
|
||||
(when (fboundp '+workspace/restart-emacs-then-restore)
|
||||
(message " M-x +workspace/restart-emacs-then-restore"))
|
||||
(message " M-x restart-emacs")
|
||||
(message " M-x doom/restart-and-restore")
|
||||
(message " M-x doom/restart")
|
||||
(message " M-x doom/reload"))
|
||||
|
||||
(defun doom--do-load (&rest files)
|
||||
|
@ -156,7 +155,7 @@ even if it doesn't need reloading!"
|
|||
forms)
|
||||
(while (re-search-forward "^;;;###autodef *\\([^\n]+\\)?\n" nil t)
|
||||
(let* ((sexp (sexp-at-point))
|
||||
(pred (match-string 1))
|
||||
(alt-sexp (match-string 1))
|
||||
(type (car sexp))
|
||||
(name (doom-unquote (cadr sexp)))
|
||||
(origin (cond ((doom-module-from-path path))
|
||||
|
@ -166,37 +165,39 @@ even if it doesn't need reloading!"
|
|||
`(:core . ,(intern (file-name-base path))))))
|
||||
(doom-file-form
|
||||
`(put ',name 'doom-file ,(abbreviate-file-name path))))
|
||||
(cond ((memq type '(defun defmacro cl-defun cl-defmacro))
|
||||
(cond ((and (not member-p) alt-sexp)
|
||||
(push (read alt-sexp) forms))
|
||||
|
||||
((memq type '(defun defmacro cl-defun cl-defmacro))
|
||||
(cl-destructuring-bind (_ name arglist &rest body) sexp
|
||||
(let ((docstring (if (stringp (car body))
|
||||
(pop body)
|
||||
"No documentation.")))
|
||||
(push (cond ((not (and member-p
|
||||
(or (null pred)
|
||||
(let ((load-file-name path))
|
||||
(eval (read pred) t)))))
|
||||
(push doom-file-form forms)
|
||||
(setq docstring (format "THIS FUNCTION DOES NOTHING BECAUSE %s IS DISABLED\n\n%s"
|
||||
origin docstring))
|
||||
(condition-case-unless-debug e
|
||||
(append (list (pcase type
|
||||
(`defun 'defmacro)
|
||||
(`cl-defun `cl-defmacro)
|
||||
(_ type))
|
||||
name arglist docstring)
|
||||
(cl-loop for arg in arglist
|
||||
if (and (symbolp arg)
|
||||
(not (keywordp arg))
|
||||
(not (memq arg cl--lambda-list-keywords)))
|
||||
collect arg into syms
|
||||
else if (listp arg)
|
||||
collect (car arg) into syms
|
||||
finally return (if syms `((ignore ,@syms)))))
|
||||
('error
|
||||
(message "Ignoring autodef %s (%s)"
|
||||
name e)
|
||||
nil)))
|
||||
((make-autoload sexp (abbreviate-file-name (file-name-sans-extension path)))))
|
||||
(push (if member-p
|
||||
(make-autoload sexp (abbreviate-file-name (file-name-sans-extension path)))
|
||||
(push doom-file-form forms)
|
||||
(setq docstring (format "THIS FUNCTION DOES NOTHING BECAUSE %s IS DISABLED\n\n%s"
|
||||
origin docstring))
|
||||
(condition-case-unless-debug e
|
||||
(if alt-sexp
|
||||
(read alt-sexp)
|
||||
(append (list (pcase type
|
||||
(`defun 'defmacro)
|
||||
(`cl-defun `cl-defmacro)
|
||||
(_ type))
|
||||
name arglist docstring)
|
||||
(cl-loop for arg in arglist
|
||||
if (and (symbolp arg)
|
||||
(not (keywordp arg))
|
||||
(not (memq arg cl--lambda-list-keywords)))
|
||||
collect arg into syms
|
||||
else if (listp arg)
|
||||
collect (car arg) into syms
|
||||
finally return (if syms `((ignore ,@syms))))))
|
||||
('error
|
||||
(message "Ignoring autodef %s (%s)"
|
||||
name e)
|
||||
nil)))
|
||||
forms)
|
||||
(push `(put ',name 'doom-module ',origin) forms))))
|
||||
|
||||
|
@ -204,19 +205,16 @@ even if it doesn't need reloading!"
|
|||
(cl-destructuring-bind (_type name target &optional docstring) sexp
|
||||
(let ((name (doom-unquote name))
|
||||
(target (doom-unquote target)))
|
||||
(unless (and member-p
|
||||
(or (null pred)
|
||||
(let ((load-file-name path))
|
||||
(eval (read pred) t))))
|
||||
(unless member-p
|
||||
(setq docstring (format "THIS FUNCTION DOES NOTHING BECAUSE %s IS DISABLED\n\n%s"
|
||||
origin docstring))
|
||||
(setq target #'ignore))
|
||||
(push doom-file-form forms)
|
||||
(push `(put ',name 'doom-module ',origin) forms)
|
||||
(push `(defalias ',name #',target ,docstring)
|
||||
forms))))
|
||||
|
||||
((and member-p
|
||||
(or (null pred)
|
||||
(eval (read pred) t)))
|
||||
(member-p
|
||||
(push sexp forms)))))
|
||||
(if forms
|
||||
(concat (string-join (mapcar #'prin1-to-string (reverse forms)) "\n")
|
||||
|
@ -320,7 +318,7 @@ modified."
|
|||
(prin1 `(setq load-path ',load-path
|
||||
auto-mode-alist ',auto-mode-alist
|
||||
Info-directory-list ',Info-directory-list
|
||||
doom-disabled-packages ',doom-disabled-packages
|
||||
doom-disabled-packages ',(mapcar #'car (doom-find-packages :disabled t))
|
||||
package-activated-list ',package-activated-list)
|
||||
(current-buffer)))
|
||||
|
||||
|
@ -354,10 +352,10 @@ This should be run whenever your `doom!' block or update your packages."
|
|||
(with-temp-file doom-package-autoload-file
|
||||
(doom--generate-header 'doom-reload-package-autoloads)
|
||||
(save-excursion
|
||||
;; Cache the important and expensive-to-initialize state here.
|
||||
;; Cache important and expensive-to-initialize state here.
|
||||
(doom--generate-var-cache)
|
||||
(print! (green "✓ Cached package state"))
|
||||
;; Loop through packages and concatenate all their autoloads files.
|
||||
;; Concatenate the autoloads of all installed packages.
|
||||
(doom--generate-package-autoloads)
|
||||
(print! (green "✓ Package autoloads included")))
|
||||
;; Remove `load-path' and `auto-mode-alist' modifications (most of them,
|
||||
|
|
|
@ -60,6 +60,9 @@ packages and regenerates the autoloads file."
|
|||
(doom-packages-install doom-auto-accept)
|
||||
(print! "Regenerating autoloads files")
|
||||
(doom-reload-autoloads nil 'force-p)
|
||||
(when (y-or-n-p "Download and install all-the-icon's fonts?")
|
||||
(require 'all-the-icons)
|
||||
(all-the-icons-install-fonts 'yes))
|
||||
(print! (bold (green "\nFinished! Doom is ready to go!\n")))
|
||||
(with-temp-buffer
|
||||
(doom-template-insert "QUICKSTART_INTRO")
|
||||
|
|
|
@ -16,46 +16,46 @@ If neither is available, run all tests in all enabled modules."
|
|||
;; Core libraries aren't fully loaded in a noninteractive session, so we
|
||||
;; reload it with `noninteractive' set to nil to force them to.
|
||||
(quiet! (doom-reload-autoloads))
|
||||
(doom-initialize 'force t)
|
||||
(doom-initialize-modules 'force)
|
||||
(let ((target-paths
|
||||
;; Convert targets into a list of string paths, pointing to the root
|
||||
;; directory of modules
|
||||
(cond ((stringp (car modules)) ; command line
|
||||
(save-match-data
|
||||
(cl-loop for arg in modules
|
||||
if (string= arg ":core") collect doom-core-dir
|
||||
else if (string-match-p "/" arg)
|
||||
nconc (mapcar (apply-partially #'expand-file-name arg)
|
||||
doom-modules-dirs)
|
||||
else
|
||||
nconc (cl-loop for dir in doom-modules-dirs
|
||||
for path = (expand-file-name arg dir)
|
||||
if (file-directory-p path)
|
||||
nconc (doom-files-in path :type 'dirs :depth 1 :full t))
|
||||
finally do (setq argv nil))))
|
||||
(let ((doom-modules (doom-modules))
|
||||
noninteractive)
|
||||
(let ((target-paths
|
||||
;; Convert targets into a list of string paths, pointing to the root
|
||||
;; directory of modules
|
||||
(cond ((stringp (car modules)) ; command line
|
||||
(save-match-data
|
||||
(cl-loop for arg in modules
|
||||
if (string= arg ":core") collect doom-core-dir
|
||||
else if (string-match-p "/" arg)
|
||||
nconc (mapcar (apply-partially #'expand-file-name arg)
|
||||
doom-modules-dirs)
|
||||
else
|
||||
nconc (cl-loop for dir in doom-modules-dirs
|
||||
for path = (expand-file-name arg dir)
|
||||
if (file-directory-p path)
|
||||
nconc (doom-files-in path :type 'dirs :depth 1 :full t))
|
||||
finally do (setq argv nil))))
|
||||
|
||||
(modules ; cons-cells given to MODULES
|
||||
(cl-loop for (module . submodule) in modules
|
||||
if (doom-module-locate-path module submodule)
|
||||
collect it))
|
||||
(modules ; cons-cells given to MODULES
|
||||
(cl-loop for (module . submodule) in modules
|
||||
if (doom-module-locate-path module submodule)
|
||||
collect it))
|
||||
|
||||
((append (list doom-core-dir)
|
||||
(doom-module-load-path))))))
|
||||
;; Load all the unit test files...
|
||||
(require 'buttercup)
|
||||
(mapc (lambda (file) (load file :noerror (not doom-debug-mode)))
|
||||
(doom-files-in (mapcar (apply-partially #'expand-file-name "test/")
|
||||
target-paths)
|
||||
:match "\\.el$" :full t))
|
||||
;; ... then run them
|
||||
(when doom-debug-mode
|
||||
(setq buttercup-stack-frame-style 'pretty))
|
||||
(let ((split-width-threshold 0)
|
||||
(split-height-threshold 0)
|
||||
(window-min-width 0)
|
||||
(window-min-height 0))
|
||||
(buttercup-run))))
|
||||
((append (list doom-core-dir)
|
||||
(doom-module-load-path))))))
|
||||
;; Load all the unit test files...
|
||||
(require 'buttercup)
|
||||
(mapc (lambda (file) (load file :noerror (not doom-debug-mode)))
|
||||
(doom-files-in (mapcar (apply-partially #'expand-file-name "test/")
|
||||
target-paths)
|
||||
:match "\\.el$" :full t))
|
||||
;; ... then run them
|
||||
(when doom-debug-mode
|
||||
(setq buttercup-stack-frame-style 'pretty))
|
||||
(let ((split-width-threshold 0)
|
||||
(split-height-threshold 0)
|
||||
(window-min-width 0)
|
||||
(window-min-height 0))
|
||||
(buttercup-run)))))
|
||||
|
||||
|
||||
;;
|
||||
|
|
|
@ -21,7 +21,7 @@ successfully sets indent_style/indent_size.")
|
|||
detected.")
|
||||
|
||||
(setq-default
|
||||
large-file-warning-threshold 30000000
|
||||
large-file-warning-threshold 15000000
|
||||
vc-follow-symlinks t
|
||||
;; Save clipboard contents into kill-ring before replacing them
|
||||
save-interprogram-paste-before-kill t
|
||||
|
@ -37,7 +37,7 @@ detected.")
|
|||
hscroll-margin 2
|
||||
hscroll-step 1
|
||||
scroll-conservatively 1001
|
||||
scroll-margin 0
|
||||
scroll-margin 2
|
||||
scroll-preserve-screen-position t
|
||||
;; Whitespace (see `editorconfig')
|
||||
indent-tabs-mode nil
|
||||
|
@ -52,23 +52,14 @@ detected.")
|
|||
;; Remove hscroll-margin in shells, otherwise it causes jumpiness
|
||||
(setq-hook! '(eshell-mode-hook term-mode-hook) hscroll-margin 0)
|
||||
|
||||
(defun doom|check-large-file ()
|
||||
"Check if the buffer's file is large (see `doom-large-file-size'). If so, ask
|
||||
for confirmation to open it literally (read-only, disabled undo and in
|
||||
fundamental-mode) for performance sake."
|
||||
(when (and (not (memq major-mode doom-large-file-modes-list))
|
||||
auto-mode-alist
|
||||
(get-buffer-window))
|
||||
(when-let* ((size (nth 7 (file-attributes buffer-file-name))))
|
||||
(when (and (> size (* 1024 1024 doom-large-file-size))
|
||||
(y-or-n-p
|
||||
(format (concat "%s is a large file, open literally to "
|
||||
"avoid performance issues?")
|
||||
(file-relative-name buffer-file-name))))
|
||||
(setq buffer-read-only t)
|
||||
(buffer-disable-undo)
|
||||
(fundamental-mode)))))
|
||||
(add-hook 'find-file-hook #'doom|check-large-file)
|
||||
(defun doom*optimize-literal-mode-for-large-files (buffer)
|
||||
"TODO"
|
||||
(with-current-buffer buffer
|
||||
(when find-file-literally
|
||||
(setq buffer-read-only t)
|
||||
(buffer-disable-undo))
|
||||
buffer))
|
||||
(advice-add #'find-file-noselect-1 :filter-return #'doom*optimize-literal-mode-for-large-files)
|
||||
|
||||
|
||||
;;
|
||||
|
@ -156,7 +147,7 @@ savehist file."
|
|||
(def-package! smartparens
|
||||
;; Auto-close delimiters and blocks as you type. It's more powerful than that,
|
||||
;; but that is all Doom uses it for.
|
||||
:after-call (doom-exit-buffer-hook after-find-file)
|
||||
:after-call (doom-switch-buffer-hook after-find-file)
|
||||
:commands (sp-pair sp-local-pair sp-with-modes sp-point-in-comment sp-point-in-string)
|
||||
:config
|
||||
(require 'smartparens-config)
|
||||
|
@ -229,9 +220,9 @@ savehist file."
|
|||
(advice-add #'dtrt-indent-mode :around #'doom*fix-broken-smie-modes))
|
||||
|
||||
|
||||
(def-package! undo-tree
|
||||
(def-package! undo-tree
|
||||
;; Branching & persistent undo
|
||||
:after-call (doom-exit-buffer-hook after-find-file)
|
||||
:after-call (doom-switch-buffer-hook after-find-file)
|
||||
:config
|
||||
(setq undo-tree-auto-save-history t
|
||||
;; undo-in-region is known to cause undo history corruption, which can
|
||||
|
@ -278,23 +269,29 @@ savehist file."
|
|||
command-log-mode-is-global t))
|
||||
|
||||
|
||||
(def-package! expand-region
|
||||
:commands (er/contract-region er/mark-symbol er/mark-word)
|
||||
:config
|
||||
(defun doom*quit-expand-region ()
|
||||
"Properly abort an expand-region region."
|
||||
(when (memq last-command '(er/expand-region er/contract-region))
|
||||
(er/contract-region 0)))
|
||||
(advice-add #'evil-escape :before #'doom*quit-expand-region)
|
||||
(advice-add #'doom/escape :before #'doom*quit-expand-region))
|
||||
|
||||
|
||||
;; `helpful' --- a better *help* buffer
|
||||
(let ((map (current-global-map)))
|
||||
(define-key map [remap describe-function] #'helpful-callable)
|
||||
(define-key map [remap describe-command] #'helpful-command)
|
||||
(define-key map [remap describe-variable] #'helpful-variable)
|
||||
(define-key map [remap describe-key] #'helpful-key))
|
||||
(def-package! helpful
|
||||
:commands helpful--read-symbol
|
||||
:init
|
||||
(define-key!
|
||||
[remap describe-function] #'helpful-callable
|
||||
[remap describe-command] #'helpful-command
|
||||
[remap describe-variable] #'helpful-variable
|
||||
[remap describe-key] #'helpful-key
|
||||
[remap describe-symbol] #'doom/describe-symbol)
|
||||
|
||||
(after! apropos
|
||||
;; patch apropos buttons to call helpful instead of help
|
||||
(dolist (fun-bt '(apropos-function apropos-macro apropos-command))
|
||||
(button-type-put
|
||||
fun-bt 'action
|
||||
(lambda (button)
|
||||
(helpful-callable (button-get button 'apropos-symbol)))))
|
||||
(dolist (var-bt '(apropos-variable apropos-user-option))
|
||||
(button-type-put
|
||||
var-bt 'action
|
||||
(lambda (button)
|
||||
(helpful-variable (button-get button 'apropos-symbol)))))))
|
||||
|
||||
|
||||
(def-package! ws-butler
|
||||
|
|
|
@ -2,26 +2,54 @@
|
|||
|
||||
;; A centralized keybinds system, integrated with `which-key' to preview
|
||||
;; available keybindings. All built into one powerful macro: `map!'. If evil is
|
||||
;; never loaded, then evil bindings set with `map!' will be ignored.
|
||||
;; never loaded, then evil bindings set with `map!' are ignored (i.e. omitted
|
||||
;; entirely for performance reasons).
|
||||
|
||||
(defvar doom-leader-key "SPC"
|
||||
"The leader prefix key for Evil users.")
|
||||
"The leader prefix key for Evil users.
|
||||
|
||||
This needs to be changed from $DOOMDIR/init.el.")
|
||||
|
||||
(defvar doom-leader-alt-key "M-SPC"
|
||||
"An alternative leader prefix key, used for Insert and Emacs states, and for
|
||||
non-evil users.")
|
||||
non-evil users.
|
||||
|
||||
This needs to be changed from $DOOMDIR/init.el.")
|
||||
|
||||
(defvar doom-localleader-key "SPC m"
|
||||
"The localleader prefix key, for major-mode specific commands.")
|
||||
"The localleader prefix key, for major-mode specific commands.
|
||||
|
||||
This needs to be changed from $DOOMDIR/init.el.")
|
||||
|
||||
(defvar doom-localleader-alt-key "M-SPC m"
|
||||
"The localleader prefix key, for major-mode specific commands.")
|
||||
"The localleader prefix key, for major-mode specific commands. Used for Insert
|
||||
and Emacs states, and for non-evil users.
|
||||
|
||||
This needs to be changed from $DOOMDIR/init.el.")
|
||||
|
||||
(defvar doom-leader-map (make-sparse-keymap)
|
||||
"An overriding keymap for <leader> keys.")
|
||||
|
||||
(defvar doom-which-key-leader-prefix-regexp nil)
|
||||
|
||||
|
||||
;;
|
||||
;;; Universal, non-nuclear escape
|
||||
|
||||
;; `keyboard-quit' is too much of a nuclear option. I wanted an ESC/C-g to
|
||||
;; do-what-I-mean. It serves four purposes (in order):
|
||||
;;
|
||||
;; 1. Quit active states; e.g. highlights, searches, snippets, iedit,
|
||||
;; multiple-cursors, recording macros, etc.
|
||||
;; 2. Close popup windows remotely (if it is allowed to)
|
||||
;; 3. Refresh buffer indicators, like git-gutter and flycheck
|
||||
;; 4. Or fall back to `keyboard-quit'
|
||||
;;
|
||||
;; And it should do these things incrementally, rather than all at once. And it
|
||||
;; shouldn't interfere with recording macros or the minibuffer. This may require
|
||||
;; you press ESC/C-g two or three times on some occasions to reach
|
||||
;; `keyboard-quit', but this is much more intuitive.
|
||||
|
||||
(defvar doom-escape-hook nil
|
||||
"A hook run after C-g is pressed (or ESC in normal mode, for evil users). Both
|
||||
trigger `doom/escape'.
|
||||
|
@ -29,13 +57,13 @@ trigger `doom/escape'.
|
|||
If any hook returns non-nil, all hooks after it are ignored.")
|
||||
|
||||
(defun doom/escape ()
|
||||
"Run the `doom-escape-hook'."
|
||||
"Run `doom-escape-hook'."
|
||||
(interactive)
|
||||
(cond ((minibuffer-window-active-p (minibuffer-window))
|
||||
;; quit the minibuffer if open.
|
||||
(abort-recursive-edit))
|
||||
;; Run all escape hooks. If any returns non-nil, then stop there.
|
||||
((cl-find-if #'funcall doom-escape-hook))
|
||||
((run-hook-with-args-until-success 'doom-escape-hook))
|
||||
;; don't abort macros
|
||||
((or defining-kbd-macro executing-kbd-macro) nil)
|
||||
;; Back to the default
|
||||
|
@ -45,53 +73,122 @@ If any hook returns non-nil, all hooks after it are ignored.")
|
|||
|
||||
|
||||
;;
|
||||
;; General
|
||||
;;; General + leader/localleader keys
|
||||
|
||||
(require 'general)
|
||||
|
||||
;; Convenience aliases
|
||||
(defalias 'define-key! #'general-def)
|
||||
(defalias 'unmap! #'general-unbind)
|
||||
|
||||
;; leader/localleader keys
|
||||
(defvar doom-leader-alist `((t . ,doom-leader-map)))
|
||||
(add-to-list 'emulation-mode-map-alists 'doom-leader-alist)
|
||||
|
||||
;; We avoid `general-create-definer' to ensure that :states, :prefix and
|
||||
;; We avoid `general-create-definer' to ensure that :states, :wk-full-keys and
|
||||
;; :keymaps cannot be overwritten.
|
||||
(defmacro define-leader-key! (&rest args)
|
||||
`(general-define-key
|
||||
:states nil
|
||||
:wk-full-keys nil
|
||||
:keymaps 'doom-leader-map
|
||||
:prefix doom-leader-alt-key
|
||||
,@args))
|
||||
|
||||
(general-create-definer define-localleader-key!
|
||||
:major-modes t
|
||||
:wk-full-keys nil
|
||||
:prefix doom-localleader-alt-key)
|
||||
|
||||
;; Because :non-normal-prefix doesn't work for non-evil sessions (only evil's
|
||||
;; emacs state), we must redefine `define-localleader-key!' once evil is loaded
|
||||
;; :non-normal-prefix doesn't apply to non-evil sessions (only evil's emacs
|
||||
;; state), so we must redefine `define-localleader-key!' to behave differently
|
||||
;; where evil is present.
|
||||
(after! evil
|
||||
(defmacro define-leader-key! (&rest args)
|
||||
`(general-define-key
|
||||
:states '(normal visual motion emacs)
|
||||
:keymaps 'doom-leader-map
|
||||
:prefix doom-leader-key
|
||||
:non-normal-prefix doom-leader-alt-key
|
||||
,@args))
|
||||
|
||||
(general-create-definer define-localleader-key!
|
||||
:states '(normal visual motion emacs)
|
||||
:major-modes t
|
||||
:wk-full-keys nil
|
||||
:prefix doom-localleader-key
|
||||
:non-normal-prefix doom-localleader-alt-key))
|
||||
|
||||
;; We use a prefix commands instead of general's :prefix/:non-normal-prefix
|
||||
;; properties because general is incredibly slow binding keys en mass with them
|
||||
;; in conjunction with :states -- an effective doubling of Doom's startup time!
|
||||
(define-prefix-command 'doom/leader 'doom-leader-map)
|
||||
(define-key doom-leader-map [override-state] 'all)
|
||||
|
||||
;; Bind `doom-leader-key' and `doom-leader-alt-key' as late as possible to give
|
||||
;; the user a chance to modify them.
|
||||
(defun doom|init-leader-keys ()
|
||||
"Bind `doom-leader-key' and `doom-leader-alt-key'."
|
||||
(let ((map general-override-mode-map))
|
||||
(if (not (featurep 'evil))
|
||||
(define-key map (kbd doom-leader-alt-key) 'doom/leader)
|
||||
(evil-define-key* '(normal visual motion) map (kbd doom-leader-key) 'doom/leader)
|
||||
(evil-define-key* '(emacs insert) map (kbd doom-leader-alt-key) 'doom/leader))
|
||||
(general-override-mode +1))
|
||||
(unless (stringp doom-which-key-leader-prefix-regexp)
|
||||
(setq doom-which-key-leader-prefix-regexp
|
||||
(concat "\\(?:"
|
||||
(cl-loop for key in (append (list doom-leader-key doom-leader-alt-key)
|
||||
(where-is-internal 'doom/leader))
|
||||
if (stringp key) collect key into keys
|
||||
else collect (key-description key) into keys
|
||||
finally return (string-join keys "\\|"))
|
||||
"\\)"))))
|
||||
(add-hook 'doom-after-init-modules-hook #'doom|init-leader-keys)
|
||||
|
||||
;; However, the prefix command approach (along with :wk-full-keys in
|
||||
;; `define-leader-key!') means that which-key is only informed of the key
|
||||
;; sequence minus `doom-leader-key'/`doom-leader-alt-key'. e.g. binding to `SPC
|
||||
;; f s' creates a wildcard label for any key that ends in 'f s'.
|
||||
;;
|
||||
;; So we forcibly inject `doom-leader-key' and `doom-leader-alt-key' into the
|
||||
;; which-key key replacement regexp for keybinds created on `doom-leader-map'.
|
||||
;; This is a dirty hack, but I'd rather this than general being responsible for
|
||||
;; 50% of Doom's startup time.
|
||||
(defun doom*general-extended-def-:which-key (_state keymap key edef kargs)
|
||||
(with-eval-after-load 'which-key
|
||||
(let* ((wk (general--getf2 edef :which-key :wk))
|
||||
(major-modes (general--getf edef kargs :major-modes))
|
||||
(keymaps (plist-get kargs :keymaps))
|
||||
;; index of keymap in :keymaps
|
||||
(keymap-index (cl-dotimes (ind (length keymaps))
|
||||
(when (eq (nth ind keymaps) keymap)
|
||||
(cl-return ind))))
|
||||
(mode (let ((mode (if (and major-modes (listp major-modes))
|
||||
(nth keymap-index major-modes)
|
||||
major-modes)))
|
||||
(if (eq mode t)
|
||||
(general--remove-map keymap)
|
||||
mode)))
|
||||
(key (key-description key))
|
||||
(key-regexp (concat (if (general--getf edef kargs :wk-full-keys)
|
||||
"\\`"
|
||||
;; Modification begin
|
||||
(if (memq 'doom-leader-map keymaps)
|
||||
(concat "\\`" doom-which-key-leader-prefix-regexp " ")))
|
||||
;; Modification end
|
||||
(regexp-quote key)
|
||||
"\\'"))
|
||||
(prefix (plist-get kargs :prefix))
|
||||
(binding (or (when (and (plist-get edef :def)
|
||||
(not (plist-get edef :keymp)))
|
||||
(plist-get edef :def))
|
||||
(when (and prefix (string= key prefix))
|
||||
(plist-get kargs :prefix-command))))
|
||||
(replacement (cond ((stringp wk)
|
||||
(cons nil wk))
|
||||
(wk)))
|
||||
(match/replacement
|
||||
(cons
|
||||
(cons (when (general--getf edef kargs :wk-match-keys)
|
||||
key-regexp)
|
||||
(when (and (general--getf edef kargs :wk-match-binding)
|
||||
binding
|
||||
(symbolp binding))
|
||||
(symbol-name binding)))
|
||||
replacement)))
|
||||
(general--add-which-key-replacement mode match/replacement)
|
||||
(when (and (consp replacement) (not (functionp replacement)))
|
||||
(general--add-which-key-title-prefix mode key (cdr replacement))))))
|
||||
(advice-add #'general-extended-def-:which-key :override #'doom*general-extended-def-:which-key)
|
||||
|
||||
|
||||
;;
|
||||
;; Packages
|
||||
;;; Packages
|
||||
|
||||
(def-package! which-key
|
||||
:defer 1
|
||||
|
@ -111,11 +208,13 @@ If any hook returns non-nil, all hooks after it are ignored.")
|
|||
(which-key-mode +1))
|
||||
|
||||
|
||||
;; `hydra'
|
||||
;;;###package hydra
|
||||
(setq lv-use-seperator t)
|
||||
|
||||
|
||||
;;
|
||||
;;; `map!' macro
|
||||
|
||||
(defvar doom-evil-state-alist
|
||||
'((?n . normal)
|
||||
(?v . visual)
|
||||
|
|
137
core/core-lib.el
137
core/core-lib.el
|
@ -1,20 +1,7 @@
|
|||
;;; core-lib.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; Built-in packages we use a lot of
|
||||
(require 'subr-x)
|
||||
(require 'cl-lib)
|
||||
|
||||
(eval-and-compile
|
||||
(unless EMACS26+
|
||||
(with-no-warnings
|
||||
;; if-let and when-let were moved to (if|when)-let* in Emacs 26+ so we
|
||||
;; alias them for 25 users.
|
||||
(defalias 'if-let* #'if-let)
|
||||
(defalias 'when-let* #'when-let))))
|
||||
|
||||
|
||||
;;
|
||||
;; Helpers
|
||||
;;; Helpers
|
||||
|
||||
(defun doom--resolve-path-forms (spec &optional directory)
|
||||
"Converts a simple nested series of or/and forms into a series of
|
||||
|
@ -23,23 +10,27 @@
|
|||
For example
|
||||
|
||||
(doom--resolve-path-forms
|
||||
'(or \"some-file\" (and path-var \"/an/absolute/path\"))
|
||||
'(or A (and B C))
|
||||
\"~\")
|
||||
|
||||
Returns
|
||||
Returns (approximately):
|
||||
|
||||
'(let ((_directory \"~\"))
|
||||
(or (file-exists-p (expand-file-name \"some-file\" _directory))
|
||||
(and (file-exists-p (expand-file-name path-var _directory))
|
||||
(file-exists-p \"/an/absolute/path\"))))
|
||||
'(let* ((_directory \"~\")
|
||||
(A (expand-file-name A _directory))
|
||||
(B (expand-file-name B _directory))
|
||||
(C (expand-file-name C _directory)))
|
||||
(or (and (file-exists-p A) A)
|
||||
(and (if (file-exists-p B) B)
|
||||
(if (file-exists-p C) C))))
|
||||
|
||||
This is used by `associate!', `file-exists-p!' and `project-file-exists-p!'."
|
||||
(declare (pure t) (side-effect-free t))
|
||||
(cond ((stringp spec)
|
||||
`(file-exists-p
|
||||
,(if (file-name-absolute-p spec)
|
||||
spec
|
||||
`(expand-file-name ,spec ,directory))))
|
||||
`(let ((--file-- ,(if (file-name-absolute-p spec)
|
||||
spec
|
||||
`(expand-file-name ,spec ,directory))))
|
||||
(and (file-exists-p --file--)
|
||||
--file--)))
|
||||
((and (listp spec)
|
||||
(memq (car spec) '(or and)))
|
||||
`(,(car spec)
|
||||
|
@ -47,12 +38,14 @@ This is used by `associate!', `file-exists-p!' and `project-file-exists-p!'."
|
|||
collect (doom--resolve-path-forms i directory))))
|
||||
((or (symbolp spec)
|
||||
(listp spec))
|
||||
`(file-exists-p ,(if (and directory
|
||||
(or (not (stringp directory))
|
||||
(file-name-absolute-p directory)))
|
||||
`(expand-file-name ,spec ,directory)
|
||||
spec)))
|
||||
(t spec)))
|
||||
`(let ((--file-- ,(if (and directory
|
||||
(or (not (stringp directory))
|
||||
(file-name-absolute-p directory)))
|
||||
`(expand-file-name ,spec ,directory)
|
||||
spec)))
|
||||
(and (file-exists-p --file--)
|
||||
--file--)))
|
||||
(spec)))
|
||||
|
||||
(defun doom--resolve-hook-forms (hooks)
|
||||
(declare (pure t) (side-effect-free t))
|
||||
|
@ -76,7 +69,7 @@ This is used by `associate!', `file-exists-p!' and `project-file-exists-p!'."
|
|||
|
||||
|
||||
;;
|
||||
;; Public library
|
||||
;;; Public library
|
||||
|
||||
(defun doom-unquote (exp)
|
||||
"Return EXP unquoted."
|
||||
|
@ -102,6 +95,23 @@ This is used by `associate!', `file-exists-p!' and `project-file-exists-p!'."
|
|||
(cl-check-type :test keyword)
|
||||
(substring (symbol-name keyword) 1))
|
||||
|
||||
(defmacro doom-log (format-string &rest args)
|
||||
"Log to *Messages* if `doom-debug-mode' is on.
|
||||
Does not interrupt the minibuffer if it is in use, but still logs to *Messages*.
|
||||
Accepts the same arguments as `message'."
|
||||
`(when doom-debug-mode
|
||||
(let ((inhibit-message (active-minibuffer-window)))
|
||||
(message
|
||||
,(concat (propertize "DOOM " 'face 'font-lock-comment-face)
|
||||
format-string
|
||||
(when doom--current-module
|
||||
(propertize
|
||||
(format " [%s/%s]"
|
||||
(doom-keyword-name (car doom--current-module))
|
||||
(cdr doom--current-module))
|
||||
'face 'warning)))
|
||||
,@args))))
|
||||
|
||||
(defun FILE! ()
|
||||
"Return the emacs lisp file this macro is called from."
|
||||
(cond ((bound-and-true-p byte-compile-current-file))
|
||||
|
@ -143,20 +153,25 @@ serve as a predicated alternative to `after!'."
|
|||
(add-hook 'after-load-functions #',fun)))))
|
||||
|
||||
(defmacro defer-feature! (feature &optional mode)
|
||||
"TODO"
|
||||
"Pretend FEATURE hasn't been loaded yet, until FEATURE-hook is triggered.
|
||||
|
||||
Some packages (like `elisp-mode' and `lisp-mode') are loaded immediately at
|
||||
startup, which will prematurely trigger `after!' (and `with-eval-after-load')
|
||||
blocks. To get around this we make Emacs believe FEATURE hasn't been loaded yet,
|
||||
then wait until FEATURE-hook (or MODE-hook, if MODE is provided) is triggered to
|
||||
reverse this and trigger `after!' blocks at a more reasonable time."
|
||||
(let ((advice-fn (intern (format "doom|defer-feature-%s" feature)))
|
||||
(mode (or mode feature)))
|
||||
`(progn
|
||||
(delq ',feature features)
|
||||
(setq features (delq ',feature features))
|
||||
(advice-add #',mode :before #',advice-fn)
|
||||
(defun ,advice-fn (&rest _)
|
||||
;; Some plugins (like yasnippet) run `lisp-mode' early, to parse some
|
||||
;; elisp. This would prematurely trigger this function. In these cases,
|
||||
;; `lisp-mode-hook' is let-bound to nil or its hooks are delayed, so if
|
||||
;; we see either, keep pretending elisp-mode isn't loaded.
|
||||
;; Some plugins (like yasnippet) will invoke a mode early, e.g. to
|
||||
;; parse some code. This would prematurely trigger this function. This
|
||||
;; checks for that:
|
||||
(when (and ,(intern (format "%s-hook" mode))
|
||||
(not delay-mode-hooks))
|
||||
;; Otherwise, announce to the world elisp-mode has been loaded, so
|
||||
;; Otherwise, announce to the world this package has been loaded, so
|
||||
;; `after!' handlers can respond and configure elisp-mode as
|
||||
;; expected.
|
||||
(provide ',feature)
|
||||
|
@ -279,7 +294,9 @@ Examples:
|
|||
(add-hook! :append :local (one-mode second-mode) (setq v 5) (setq a 2))
|
||||
|
||||
Body forms can access the hook's arguments through the let-bound variable
|
||||
`args'."
|
||||
`args'.
|
||||
|
||||
\(fn [:append :local] HOOKS FUNCTIONS)"
|
||||
(declare (indent defun) (debug t))
|
||||
(let ((hook-fn 'add-hook)
|
||||
append-p local-p)
|
||||
|
@ -310,7 +327,9 @@ Body forms can access the hook's arguments through the let-bound variable
|
|||
|
||||
(defmacro remove-hook! (&rest args)
|
||||
"Convenience macro for `remove-hook'. Takes the same arguments as
|
||||
`add-hook!'."
|
||||
`add-hook!'.
|
||||
|
||||
\(fn [:append :local] HOOKS FUNCTIONS)"
|
||||
(declare (indent defun) (debug t))
|
||||
`(add-hook! :remove ,@args))
|
||||
|
||||
|
@ -331,6 +350,33 @@ Body forms can access the hook's arguments through the let-bound variable
|
|||
(push `(setq-local ,var ,val) forms)))
|
||||
(nreverse forms))))
|
||||
|
||||
(defun advice-add! (symbols where functions)
|
||||
"Variadic version of `advice-add'.
|
||||
|
||||
SYMBOLS and FUNCTIONS can be lists of functions."
|
||||
(let ((functions (if (functionp functions)
|
||||
(list functions)
|
||||
functions)))
|
||||
(dolist (s (doom-enlist symbols))
|
||||
(dolist (f (doom-enlist functions))
|
||||
(advice-add s where f)))))
|
||||
|
||||
(defun advice-remove! (symbols where-or-fns &optional functions)
|
||||
"Variadic version of `advice-remove'.
|
||||
|
||||
WHERE-OR-FNS is ignored if FUNCTIONS is provided. This lets you substitute
|
||||
advice-add with advice-remove and evaluate them without having to modify every
|
||||
statement."
|
||||
(unless functions
|
||||
(setq functions where-or-fns
|
||||
where-or-fns nil))
|
||||
(let ((functions (if (functionp functions)
|
||||
(list functions)
|
||||
functions)))
|
||||
(dolist (s (doom-enlist symbols))
|
||||
(dolist (f (doom-enlist functions))
|
||||
(advice-remove s f)))))
|
||||
|
||||
(cl-defmacro associate! (mode &key modes match files when)
|
||||
"Enables a minor mode if certain conditions are met.
|
||||
|
||||
|
@ -377,16 +423,15 @@ The available conditions are:
|
|||
mode modes match files when)))))
|
||||
|
||||
(defmacro file-exists-p! (spec &optional directory)
|
||||
"Returns t if the files in SPEC all exist.
|
||||
"Returns non-nil 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.
|
||||
Returns the last file found to meet the rules set by SPEC. 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.
|
||||
DIRECTORY is where to look for the files in SPEC if they aren't absolute.
|
||||
|
||||
For example:
|
||||
|
||||
(file-exists-p! (or doom-core-dir \"~/.config\" \"some-file\") \"~\")"
|
||||
(if directory
|
||||
`(let ((--directory-- ,directory))
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
(syntax-checker (:tools flycheck)))
|
||||
(:tools (rotate-text (:editor rotate-text)))
|
||||
(:emacs (electric-indent (:emacs electric))
|
||||
(hideshow (:editor fold))))
|
||||
(hideshow (:editor fold)))
|
||||
(:ui (doom-modeline (:ui modeline))))
|
||||
"An alist of deprecated modules, mapping deprecated modules to an optional new
|
||||
location (which will create an alias). Each CAR and CDR is a (CATEGORY .
|
||||
MODULES). E.g.
|
||||
|
@ -32,7 +33,24 @@ A warning will be put out if these deprecated modules are used.")
|
|||
|
||||
|
||||
;;
|
||||
;; Bootstrap API
|
||||
;;; Custom hooks
|
||||
|
||||
(defvar doom-before-init-modules-hook nil
|
||||
"A list of hooks to run before Doom's modules' config.el files are loaded, but
|
||||
after their init.el files are loaded.")
|
||||
|
||||
(defvar doom-init-modules-hook nil
|
||||
"A list of hooks to run after Doom's modules' config.el files have loaded, but
|
||||
before the user's private module.")
|
||||
|
||||
(defvaralias 'doom-after-init-modules-hook 'after-init-hook)
|
||||
|
||||
(define-obsolete-variable-alias 'doom-post-init-hook 'doom-init-modules-hook "2.1.0")
|
||||
(define-obsolete-variable-alias 'doom-init-hook 'doom-before-init-modules-hook "2.1.0")
|
||||
|
||||
|
||||
;;
|
||||
;;; Bootstrap API
|
||||
|
||||
(defun doom-initialize-modules (&optional force-p)
|
||||
"Loads the init.el in `doom-private-dir' and sets up hooks for a healthy
|
||||
|
@ -50,23 +68,23 @@ non-nil."
|
|||
(doom--current-flags (plist-get plist :flags)))
|
||||
(load! "init" (plist-get plist :path) t)))
|
||||
doom-modules)
|
||||
(run-hook-wrapped 'doom-init-hook #'doom-try-run-hook)
|
||||
(run-hook-wrapped 'doom-before-init-modules-hook #'doom-try-run-hook)
|
||||
(unless noninteractive
|
||||
(maphash (lambda (key plist)
|
||||
(let ((doom--current-module key)
|
||||
(doom--current-flags (plist-get plist :flags)))
|
||||
(load! "config" (plist-get plist :path) t)))
|
||||
doom-modules)
|
||||
(run-hook-wrapped 'doom-init-modules-hook #'doom-try-run-hook)
|
||||
(load! "config" doom-private-dir t)
|
||||
(unless custom-file
|
||||
(setq custom-file (concat doom-local-dir "custom.el")))
|
||||
(when (stringp custom-file)
|
||||
(load custom-file t t t))
|
||||
(run-hook-wrapped 'doom-post-init-hook #'doom-try-run-hook))))
|
||||
(load custom-file t t t)))))
|
||||
|
||||
|
||||
;;
|
||||
;; Module API
|
||||
;;; Module API
|
||||
|
||||
(defun doom-module-p (category module)
|
||||
"Returns t if CATEGORY MODULE is enabled (ie. present in `doom-modules')."
|
||||
|
@ -176,7 +194,6 @@ non-nil, return paths of possible modules, activated or otherwise."
|
|||
(let ((noninteractive t)
|
||||
doom-modules
|
||||
doom-init-modules-p)
|
||||
(message "Initializing modules")
|
||||
(load! "init" doom-private-dir t)
|
||||
(or doom-modules
|
||||
(make-hash-table :test 'equal
|
||||
|
@ -185,7 +202,7 @@ non-nil, return paths of possible modules, activated or otherwise."
|
|||
|
||||
|
||||
;;
|
||||
;; Use-package modifications
|
||||
;;; Use-package modifications
|
||||
|
||||
(autoload 'use-package "use-package-core" nil nil t)
|
||||
|
||||
|
@ -194,43 +211,24 @@ non-nil, return paths of possible modules, activated or otherwise."
|
|||
use-package-minimum-reported-time (if doom-debug-mode 0 0.1)
|
||||
use-package-expand-minimally (not noninteractive))
|
||||
|
||||
;; Adds two new keywords to `use-package' (and consequently, `def-package!'),
|
||||
;; they are:
|
||||
;; Adds two new keywords to `use-package' (and consequently, `def-package!') to
|
||||
;; expand its lazy-loading capabilities. They are:
|
||||
;;
|
||||
;; :after-call SYMBOL|LIST
|
||||
;; Takes a symbol or list of symbols representing functions or hook variables.
|
||||
;; The first time any of these functions or hooks are executed, the package is
|
||||
;; loaded. e.g.
|
||||
;;
|
||||
;; (def-package! projectile
|
||||
;; :after-call (pre-command-hook after-find-file dired-before-readin-hook)
|
||||
;; ...)
|
||||
;;
|
||||
;; :defer-incrementally SYMBOL|LIST|t
|
||||
;; Takes a symbol or list of symbols representing packages that will be loaded
|
||||
;; incrementally at startup before this one. This is helpful for large
|
||||
;; packages like magit or org, which load a lot of dependencies on first load.
|
||||
;; This lets you load them piece-meal, one at a time, during idle periods, so
|
||||
;; that when you finally do need the package, it'll loads much quicker. e.g.
|
||||
;;
|
||||
;; (def-package! magit
|
||||
;; ;; You do not need to include magit in this list!
|
||||
;; :defer-incrementally (dash f s with-editor git-commit package)
|
||||
;; ...)
|
||||
;;
|
||||
;; (def-package! x
|
||||
;; ;; This is equivalent to :defer-incrementally (x)
|
||||
;; :defer-incrementally t
|
||||
;; ...)
|
||||
;; Check out `def-package!'s documentation for more about these two.
|
||||
(defvar doom--deferred-packages-alist '(t))
|
||||
(after! use-package-core
|
||||
(add-to-list 'use-package-deferring-keywords :defer-incrementally nil #'eq)
|
||||
(add-to-list 'use-package-deferring-keywords :after-call nil #'eq)
|
||||
;; :ensure and :pin don't work well with Doom, so we forcibly remove them.
|
||||
(dolist (keyword '(:ensure :pin))
|
||||
(setq use-package-keywords (delq keyword use-package-keywords)))
|
||||
|
||||
(setq use-package-keywords
|
||||
(use-package-list-insert :defer-incrementally use-package-keywords :after))
|
||||
(setq use-package-keywords
|
||||
(use-package-list-insert :after-call use-package-keywords :after))
|
||||
;; Insert new deferring keywords
|
||||
(dolist (keyword '(:defer-incrementally :after-call))
|
||||
(add-to-list 'use-package-deferring-keywords keyword nil #'eq)
|
||||
(setq use-package-keywords
|
||||
(use-package-list-insert keyword use-package-keywords :after)))
|
||||
|
||||
(defalias 'use-package-normalize/:defer-incrementally 'use-package-normalize-symlist)
|
||||
(defun use-package-handler/:defer-incrementally (name _keyword targets rest state)
|
||||
|
@ -249,18 +247,18 @@ non-nil, return paths of possible modules, activated or otherwise."
|
|||
(use-package-concat
|
||||
`((fset ',fn
|
||||
(lambda (&rest _)
|
||||
(when doom-debug-mode
|
||||
(message "Loading deferred package %s from %s" ',name ',fn))
|
||||
(condition-case e (require ',name)
|
||||
(doom-log "Loading deferred package %s from %s" ',name ',fn)
|
||||
(condition-case e
|
||||
(require ',name)
|
||||
((debug error)
|
||||
(message "Failed to load deferred package %s: %s" ',name e)))
|
||||
(dolist (hook (cdr (assq ',name doom--deferred-packages-alist)))
|
||||
(if (functionp hook)
|
||||
(advice-remove hook #',fn)
|
||||
(remove-hook hook #',fn)))
|
||||
(delq (assq ',name doom--deferred-packages-alist)
|
||||
doom--deferred-packages-alist)
|
||||
(fmakunbound ',fn))))
|
||||
(when-let* ((deferral-list (assq ',name doom--deferred-packages-alist)))
|
||||
(dolist (hook (cdr deferral-list))
|
||||
(if (functionp hook)
|
||||
(advice-remove hook #',fn)
|
||||
(remove-hook hook #',fn)))
|
||||
(setq doom--deferred-packages-alist
|
||||
(delq deferral-list doom--deferred-packages-alist))))))
|
||||
(let (forms)
|
||||
(dolist (hook hooks forms)
|
||||
(push (if (functionp hook)
|
||||
|
@ -275,7 +273,7 @@ non-nil, return paths of possible modules, activated or otherwise."
|
|||
|
||||
|
||||
;;
|
||||
;; Module config macros
|
||||
;;; Module config macros
|
||||
|
||||
(defmacro doom! (&rest modules)
|
||||
"Bootstraps DOOM Emacs and its modules.
|
||||
|
@ -294,12 +292,14 @@ The overall load order of Doom is as follows:
|
|||
~/.emacs.d/core/core.el
|
||||
$DOOMDIR/init.el
|
||||
{$DOOMDIR,~/.emacs.d}/modules/*/*/init.el
|
||||
`doom-init-hook'
|
||||
`doom-before-init-modules-hook'
|
||||
{$DOOMDIR,~/.emacs.d}/modules/*/*/config.el
|
||||
`doom-init-modules-hook'
|
||||
$DOOMDIR/config.el
|
||||
`doom-after-init-modules-hook'
|
||||
`after-init-hook'
|
||||
`emacs-startup-hook'
|
||||
`doom-post-init-hook' (at end of `emacs-startup-hook')
|
||||
`window-setup-hook'
|
||||
|
||||
Module load order is determined by your `doom!' block. See `doom-modules-dirs'
|
||||
for a list of all recognized module trees. Order defines precedence (from most
|
||||
|
@ -335,10 +335,43 @@ to least)."
|
|||
|
||||
(defvar doom-disabled-packages)
|
||||
(defmacro def-package! (name &rest plist)
|
||||
"This is a thin wrapper around `use-package'."
|
||||
`(use-package ,name
|
||||
,@(if (memq name doom-disabled-packages) `(:disabled t))
|
||||
,@plist))
|
||||
"This is a thin wrapper around `use-package'.
|
||||
|
||||
It is ignored if the NAME package is disabled.
|
||||
|
||||
Supports two special properties over `use-package':
|
||||
|
||||
:after-call SYMBOL|LIST
|
||||
Takes a symbol or list of symbols representing functions or hook variables.
|
||||
The first time any of these functions or hooks are executed, the package is
|
||||
loaded. e.g.
|
||||
|
||||
(def-package! projectile
|
||||
:after-call (pre-command-hook after-find-file dired-before-readin-hook)
|
||||
...)
|
||||
|
||||
:defer-incrementally SYMBOL|LIST|t
|
||||
Takes a symbol or list of symbols representing packages that will be loaded
|
||||
incrementally at startup before this one. This is helpful for large packages
|
||||
like magit or org, which load a lot of dependencies on first load. This lets
|
||||
you load them piece-meal during idle periods, so that when you finally do need
|
||||
the package, it'll load quicker. e.g.
|
||||
|
||||
NAME is implicitly added if this property is present and non-nil. No need to
|
||||
specify it. A value of `t' implies NAME, e.g.
|
||||
|
||||
(def-package! x
|
||||
;; This is equivalent to :defer-incrementally (x)
|
||||
:defer-incrementally t
|
||||
...)"
|
||||
(unless (or (memq name doom-disabled-packages)
|
||||
;; At compile-time, use-package will forcibly load its package to
|
||||
;; prevent compile-time errors. However, Doom users can
|
||||
;; intentionally disable packages, resulting if file-missing
|
||||
;; package errors, so we preform this check at compile time:
|
||||
(and (bound-and-true-p byte-compile-current-file)
|
||||
(not (locate-library (symbol-name name)))))
|
||||
`(use-package ,name ,@plist)))
|
||||
|
||||
(defmacro def-package-hook! (package when &rest body)
|
||||
"Reconfigures a package's `def-package!' block.
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
;;; core-os.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; clipboard
|
||||
(setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING)
|
||||
;; Use a shared clipboard
|
||||
select-enable-clipboard t
|
||||
select-enable-primary t)
|
||||
(setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING))
|
||||
|
||||
;; fewer opts to process for systems that don't need them
|
||||
(unless IS-MAC (setq command-line-ns-option-alist nil))
|
||||
(unless IS-LINUX (setq command-line-x-option-alist nil))
|
||||
|
||||
;; Fix the clipboard in terminal or daemon Emacs (non-GUI)
|
||||
(defun doom|init-clipboard-in-tty-emacs ()
|
||||
(if IS-MAC
|
||||
(if (require 'osx-clipboard nil t) (osx-clipboard-mode))
|
||||
(if (require 'xclip nil t) (xclip-mode))))
|
||||
(add-hook 'tty-setup-hook #'doom|init-clipboard-in-tty-emacs)
|
||||
|
||||
;; stop copying each visual state move to the clipboard:
|
||||
;; https://bitbucket.org/lyro/evil/issue/336/osx-visual-state-copies-the-region-on
|
||||
|
@ -29,14 +37,11 @@
|
|||
;; than a new one
|
||||
ns-pop-up-frames nil)
|
||||
|
||||
;; Fix the clipboard in terminal or daemon Emacs (non-GUI)
|
||||
(when (or (daemonp) (not (display-graphic-p)))
|
||||
(add-hook 'doom-post-init-hook #'osx-clipboard-mode))
|
||||
|
||||
(when (or (daemonp) (display-graphic-p))
|
||||
;; Syncs ns frame parameters with theme (and fixes mismatching text
|
||||
;; colr in the frame title)
|
||||
(require 'ns-auto-titlebar nil t)
|
||||
(when (require 'ns-auto-titlebar nil t)
|
||||
(add-hook 'doom-load-theme-hook #'ns-auto-titlebar-mode))
|
||||
|
||||
;; A known problem with GUI Emacs on MacOS (or daemons started via
|
||||
;; launchctl or brew services): it runs in an isolated
|
||||
|
|
|
@ -87,52 +87,27 @@ If FORCE-P is 'internal, only (re)populate `doom-packages'.
|
|||
Use this before any of package.el, quelpa or Doom's package management's API to
|
||||
ensure all the necessary package metadata is initialized and available for
|
||||
them."
|
||||
(with-temp-buffer ; prevent buffer-local settings from propagating
|
||||
(let ((load-prefer-newer t)) ; reduce stale code issues
|
||||
;; package.el and quelpa handle themselves if their state changes during
|
||||
;; the current session, but if you change an packages.el file in a module,
|
||||
;; there's no non-trivial way to detect that, so we give you a way to
|
||||
;; reload only doom-packages (by passing 'internal as FORCE-P).
|
||||
(unless (eq force-p 'internal)
|
||||
;; `package-alist'
|
||||
(when (or force-p (not (bound-and-true-p package-alist)))
|
||||
(doom-ensure-packages-initialized 'force)
|
||||
(setq load-path (cl-remove-if-not #'file-directory-p load-path)))
|
||||
;; `quelpa-cache'
|
||||
(when (or force-p (not (bound-and-true-p quelpa-cache)))
|
||||
;; ensure un-byte-compiled version of quelpa is loaded
|
||||
(unless (featurep 'quelpa)
|
||||
(load (locate-library "quelpa.el") nil t t))
|
||||
(setq quelpa-initialized-p nil)
|
||||
(or (quelpa-setup-p)
|
||||
(error "Could not initialize quelpa"))))
|
||||
;; `doom-packages'
|
||||
(when (or force-p (not doom-packages))
|
||||
(cl-flet
|
||||
((_load
|
||||
(lambda (file &optional noerror)
|
||||
(condition-case e
|
||||
(load file noerror t t)
|
||||
((debug error)
|
||||
(signal 'doom-package-error
|
||||
(list (or (doom-module-from-path file)
|
||||
'(:private . packages))
|
||||
e)))))))
|
||||
(let ((doom-modules (doom-modules))
|
||||
(doom--stage 'packages)
|
||||
(noninteractive t))
|
||||
(setq doom-packages nil)
|
||||
(_load (expand-file-name "packages.el" doom-core-dir))
|
||||
;; We load the private packages file twice to ensure disabled
|
||||
;; packages are seen ASAP, and a second time to ensure privately
|
||||
;; overridden packages are properly overwritten.
|
||||
(let ((private-packages (expand-file-name "packages.el" doom-private-dir)))
|
||||
(_load private-packages t)
|
||||
(cl-loop for key being the hash-keys of doom-modules
|
||||
for path = (doom-module-path (car key) (cdr key) "packages.el")
|
||||
do (let ((doom--current-module key)) (_load path t)))
|
||||
(_load private-packages t)
|
||||
(setq doom-packages (reverse doom-packages)))))))))
|
||||
(let ((load-prefer-newer t)) ; reduce stale code issues
|
||||
;; package.el and quelpa handle themselves if their state changes during the
|
||||
;; current session, but if you change an packages.el file in a module,
|
||||
;; there's no non-trivial way to detect that, so to reload only
|
||||
;; doom-packages pass 'internal as FORCE-P or use `doom/reload-packages'.
|
||||
(unless (eq force-p 'internal)
|
||||
;; `package-alist'
|
||||
(when (or force-p (not (bound-and-true-p package-alist)))
|
||||
(doom-ensure-packages-initialized 'force)
|
||||
(setq load-path (cl-delete-if-not #'file-directory-p load-path)))
|
||||
;; `quelpa-cache'
|
||||
(when (or force-p (not (bound-and-true-p quelpa-cache)))
|
||||
;; ensure un-byte-compiled version of quelpa is loaded
|
||||
(unless (featurep 'quelpa)
|
||||
(load (locate-library "quelpa.el") nil t t))
|
||||
(setq quelpa-initialized-p nil)
|
||||
(or (quelpa-setup-p)
|
||||
(error "Could not initialize quelpa"))))
|
||||
;; `doom-packages'
|
||||
(when (or force-p (not doom-packages))
|
||||
(setq doom-packages (doom-package-list)))))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -169,7 +144,7 @@ them."
|
|||
;;
|
||||
;; Module package macros
|
||||
|
||||
(cl-defmacro package! (name &rest plist &key recipe pin disable _ignore _freeze)
|
||||
(cl-defmacro package! (name &rest plist &key built-in recipe pin disable _ignore _freeze)
|
||||
"Declares a package and how to install it (if applicable).
|
||||
|
||||
This macro is declarative and does not load nor install packages. It is used to
|
||||
|
@ -193,30 +168,48 @@ Accepts the following properties:
|
|||
Do not install this package.
|
||||
:freeze FORM
|
||||
Do not update this package if FORM is non-nil.
|
||||
:built-in BOOL
|
||||
Same as :ignore if the package is a built-in Emacs package.
|
||||
|
||||
Returns t if package is successfully registered, and nil if it was disabled
|
||||
elsewhere."
|
||||
(declare (indent defun))
|
||||
(doom--assert-stage-p 'packages #'package!)
|
||||
(let ((plist (append plist (cdr (assq name doom-packages)))))
|
||||
(let ((old-plist (cdr (assq name doom-packages))))
|
||||
(when recipe
|
||||
(when (cl-evenp (length recipe))
|
||||
(setq plist (plist-put plist :recipe (cons name recipe))))
|
||||
(setq pin nil
|
||||
plist (plist-put plist :pin nil)))
|
||||
(when (file-in-directory-p (FILE!) doom-private-dir)
|
||||
(setq plist (plist-put plist :private t)))
|
||||
(let (newplist)
|
||||
(while plist
|
||||
(unless (null (cadr plist))
|
||||
(push (cadr plist) newplist)
|
||||
(push (car plist) newplist))
|
||||
(pop plist)
|
||||
(pop plist))
|
||||
(setq plist newplist))
|
||||
(let ((module-list (plist-get old-plist :modules))
|
||||
(module (or doom--current-module
|
||||
(let ((file (FILE!)))
|
||||
(cond ((file-in-directory-p file doom-private-dir)
|
||||
(list :private))
|
||||
((file-in-directory-p file doom-core-dir)
|
||||
(list :core))
|
||||
((doom-module-from-path file)))))))
|
||||
(doom-log "Registered package '%s'%s"
|
||||
name (if recipe (format " with recipe %s" recipe) ""))
|
||||
(unless (member module module-list)
|
||||
(setq module-list (append module-list (list module) nil)
|
||||
plist (plist-put plist :modules module-list))))
|
||||
(when (and built-in (locate-library (symbol-name name) nil doom-site-load-path))
|
||||
(doom-log "Ignoring built-in package '%s'" name)
|
||||
(setq plist (plist-put plist :ignore t)))
|
||||
(while plist
|
||||
(unless (null (cadr plist))
|
||||
(setq old-plist (plist-put old-plist (car plist) (cadr plist))))
|
||||
(pop plist)
|
||||
(pop plist))
|
||||
(setq plist old-plist)
|
||||
(macroexp-progn
|
||||
(append (if disable `((add-to-list 'doom-disabled-packages ',name nil #'eq)))
|
||||
(if pin `((setf (alist-get ',name package-pinned-packages) ,pin)))
|
||||
(append (when disable
|
||||
(doom-log "Disabling package '%s'" name)
|
||||
`((add-to-list 'doom-disabled-packages ',name nil 'eq)))
|
||||
(when pin
|
||||
(doom-log "Pinning package '%s' to '%s'" name pin)
|
||||
`((setf (alist-get ',name package-pinned-packages) ,pin)))
|
||||
`((setf (alist-get ',name doom-packages) ',plist)
|
||||
(not (memq ',name doom-disabled-packages)))))))
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
;;; core-projects.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! projectile
|
||||
:after-call (pre-command-hook after-find-file dired-before-readin-hook)
|
||||
:after-call (after-find-file dired-before-readin-hook minibuffer-setup-hook)
|
||||
:commands (projectile-project-root projectile-project-name projectile-project-p)
|
||||
:init
|
||||
(setq projectile-cache-file (concat doom-cache-dir "projectile.cache")
|
||||
|
@ -15,9 +15,11 @@
|
|||
|
||||
:config
|
||||
(add-hook 'dired-before-readin-hook #'projectile-track-known-projects-find-file-hook)
|
||||
(add-hook 'find-file-hook #'doom|init-project-mode)
|
||||
(projectile-mode +1)
|
||||
|
||||
(global-set-key [remap evil-jump-to-tag] #'projectile-find-tag)
|
||||
(global-set-key [remap find-tag] #'projectile-find-tag)
|
||||
|
||||
;; a more generic project root file
|
||||
(push ".project" projectile-project-root-files-bottom-up)
|
||||
|
||||
|
@ -66,23 +68,10 @@
|
|||
;;
|
||||
;; Project-based minor modes
|
||||
|
||||
(defvar-local doom-project nil
|
||||
"Either the symbol or a list of project modes you want to enable. Available
|
||||
for .dir-locals.el.")
|
||||
|
||||
(defvar doom-project-hook nil
|
||||
"Hook run when a project is enabled. The name of the project's mode and its
|
||||
state are passed in.")
|
||||
|
||||
(defun doom|init-project-mode ()
|
||||
"Auto-enable the project(s) listed in `doom-project'."
|
||||
(when doom-project
|
||||
(if (symbolp doom-project)
|
||||
(funcall doom-project)
|
||||
(cl-loop for mode in doom-project
|
||||
unless (symbol-value mode)
|
||||
do (funcall mode)))))
|
||||
|
||||
(cl-defmacro def-project-mode! (name &key
|
||||
modes
|
||||
files
|
||||
|
@ -94,9 +83,9 @@ state are passed in.")
|
|||
on-exit)
|
||||
"Define a project minor-mode named NAME (a symbol) and declare where and how
|
||||
it is activated. Project modes allow you to configure 'sub-modes' for
|
||||
major-modes that are specific to a specific folder, certain project structure,
|
||||
framework or arbitrary context you define. These project modes can have their
|
||||
own settings, keymaps, hooks, snippets, etc.
|
||||
major-modes that are specific to a folder, project structure, framework or
|
||||
whatever arbitrary context you define. These project modes can have their own
|
||||
settings, keymaps, hooks, snippets, etc.
|
||||
|
||||
This creates NAME-hook and NAME-map as well.
|
||||
|
||||
|
|
473
core/core-ui.el
473
core/core-ui.el
|
@ -1,9 +1,12 @@
|
|||
;;; core-ui.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;
|
||||
;;; Variables
|
||||
|
||||
(defvar doom-theme nil
|
||||
"A symbol representing the Emacs theme to load at startup.
|
||||
|
||||
This is changed when `load-theme' is used as well.")
|
||||
This is changed by `load-theme'.")
|
||||
|
||||
(defvar doom-font nil
|
||||
"The default font to use.
|
||||
|
@ -48,15 +51,106 @@ Expects either a `font-spec', font object, a XFT font string or XLFD string. See
|
|||
It is recommended you don't set specify a font-size, as to inherit `doom-font's
|
||||
size.")
|
||||
|
||||
|
||||
;;
|
||||
(defvar doom-init-ui-hook nil
|
||||
"List of hooks to run when the UI has been initialized.")
|
||||
|
||||
(defvar doom--prefer-theme-elc nil
|
||||
"If non-nil, `load-theme' will prefer the compiled theme (unlike its default
|
||||
behavior). Do not set this directly, this is let-bound in `doom|init-theme'.")
|
||||
|
||||
|
||||
;;
|
||||
;;; Custom hooks
|
||||
|
||||
(defvar doom-init-ui-hook nil
|
||||
"List of hooks to run when the UI has been initialized.")
|
||||
|
||||
(defvar doom-load-theme-hook nil
|
||||
"Hook run after the theme is loaded with `load-theme' or reloaded with
|
||||
`doom/reload-theme'.")
|
||||
|
||||
(defvar doom-switch-buffer-hook nil
|
||||
"TODO")
|
||||
|
||||
(defvar doom-switch-window-hook nil
|
||||
"TODO")
|
||||
|
||||
(defvar doom-switch-frame-hook nil
|
||||
"TODO")
|
||||
|
||||
(defvar doom-inhibit-switch-buffer-hooks nil
|
||||
"Letvar for inhibiting `doom-switch-buffer-hook'. Do not set this directly.")
|
||||
(defvar doom-inhibit-switch-window-hooks nil
|
||||
"Letvar for inhibiting `doom-switch-window-hook'. Do not set this directly.")
|
||||
(defvar doom-inhibit-switch-frame-hooks nil
|
||||
"Letvar for inhibiting `doom-switch-frame-hook'. Do not set this directly.")
|
||||
|
||||
(defvar doom--last-window nil)
|
||||
(defvar doom--last-frame nil)
|
||||
|
||||
(defun doom|run-switch-window-hooks ()
|
||||
(unless (or doom-inhibit-switch-window-hooks
|
||||
(eq doom--last-window (selected-window))
|
||||
(minibufferp))
|
||||
(let ((doom-inhibit-switch-window-hooks t))
|
||||
(run-hooks 'doom-switch-window-hook)
|
||||
(doom-log "Window switched to %s" (selected-window))
|
||||
(setq doom--last-window (selected-window)))))
|
||||
|
||||
(defun doom|run-switch-frame-hooks (&rest _)
|
||||
(let ((selected-frame (selected-frame)))
|
||||
(unless (or doom-inhibit-switch-frame-hooks
|
||||
(eq doom--last-frame (selected-frame))
|
||||
(frame-parameter nil 'parent-frame))
|
||||
(let ((doom-inhibit-switch-frame-hooks t))
|
||||
(run-hooks 'doom-switch-frame-hook)
|
||||
(doom-log "Frame switched to %s" (selected-frame))
|
||||
(setq doom--last-frame (selected-frame))))))
|
||||
|
||||
(defun doom*run-switch-buffer-hooks (orig-fn buffer-or-name &rest args)
|
||||
(if (or doom-inhibit-switch-buffer-hooks
|
||||
(if (eq orig-fn 'switch-to-buffer)
|
||||
(car args) ; norecord
|
||||
(eq (get-buffer buffer-or-name) (current-buffer))))
|
||||
(apply orig-fn buffer-or-name args)
|
||||
(let ((doom-inhibit-switch-buffer-hooks t))
|
||||
(doom-log "Buffer switched in %s" (selected-window))
|
||||
(prog1 (apply orig-fn buffer-or-name args)
|
||||
(run-hooks 'doom-switch-buffer-hook)))))
|
||||
|
||||
(defun doom*run-load-theme-hooks (theme &optional _no-confirm no-enable)
|
||||
"Set up `doom-load-theme-hook' to run after `load-theme' is called."
|
||||
(unless no-enable
|
||||
(setq doom-theme theme)
|
||||
(run-hooks 'doom-load-theme-hook)))
|
||||
|
||||
(defun doom|protect-fallback-buffer ()
|
||||
"Don't kill the scratch buffer. Meant for `kill-buffer-query-functions'."
|
||||
(not (eq (current-buffer) (doom-fallback-buffer))))
|
||||
|
||||
(defun doom|highlight-non-default-indentation ()
|
||||
"Highlight whitespace that doesn't match your `indent-tabs-mode' setting.
|
||||
|
||||
e.g. If you indent with spaces by default, tabs will be highlighted. If you
|
||||
indent with tabs, spaces at BOL are highlighted.
|
||||
|
||||
Does nothing if `whitespace-mode' is already active or the current buffer is
|
||||
read-only or not file-visiting."
|
||||
(unless (or (bound-and-true-p global-whitespace-mode)
|
||||
(bound-and-true-p whitespace-mode)
|
||||
(eq major-mode 'fundamental-mode)
|
||||
buffer-read-only
|
||||
(null buffer-file-name))
|
||||
(require 'whitespace)
|
||||
(set (make-local-variable 'whitespace-style)
|
||||
(if (bound-and-true-p whitespace-newline-mode)
|
||||
(cl-union (if indent-tabs-mode '(indentation) '(tabs tab-mark))
|
||||
whitespace-style)
|
||||
`(face ,@(if indent-tabs-mode '(indentation) '(tabs tab-mark))
|
||||
trailing-lines tail)))
|
||||
(whitespace-mode +1)))
|
||||
|
||||
|
||||
;;
|
||||
;;; General configuration
|
||||
|
||||
(setq-default
|
||||
ansi-color-for-comint-mode t
|
||||
bidi-display-reordering nil ; disable bidirectional text for tiny performance boost
|
||||
|
@ -71,6 +165,7 @@ behavior). Do not set this directly, this is let-bound in `doom|init-theme'.")
|
|||
display-line-numbers-width 3
|
||||
enable-recursive-minibuffers nil
|
||||
frame-inhibit-implied-resize t
|
||||
frame-title-format '("%b – Doom Emacs") ; simple name in frame title
|
||||
;; remove continuation arrow on right fringe
|
||||
fringe-indicator-alist
|
||||
(delq (assq 'continuation fringe-indicator-alist)
|
||||
|
@ -86,7 +181,7 @@ behavior). Do not set this directly, this is let-bound in `doom|init-theme'.")
|
|||
resize-mini-windows 'grow-only ; Minibuffer resizing
|
||||
show-help-function nil ; hide :help-echo text
|
||||
split-width-threshold 160 ; favor horizontal splits
|
||||
uniquify-buffer-name-style 'forward
|
||||
uniquify-buffer-name-style nil ; custom modeline will show file paths anyway
|
||||
use-dialog-box nil ; always avoid GUI
|
||||
visible-cursor nil
|
||||
x-stretch-cursor nil
|
||||
|
@ -99,68 +194,41 @@ behavior). Do not set this directly, this is let-bound in `doom|init-theme'.")
|
|||
;; don't resize emacs in steps, it looks weird
|
||||
window-resize-pixelwise t
|
||||
frame-resize-pixelwise t)
|
||||
|
||||
;; y/n instead of yes/no
|
||||
(fset #'yes-or-no-p #'y-or-n-p)
|
||||
|
||||
;; Truly silence startup message
|
||||
(fset #'display-startup-echo-area-message #'ignore)
|
||||
;; relegate tooltips to echo area only
|
||||
(if (bound-and-true-p tooltip-mode) (tooltip-mode -1))
|
||||
;; enabled by default; no thanks, too distracting
|
||||
(blink-cursor-mode -1)
|
||||
;; Handle ansi codes in compilation buffer
|
||||
(add-hook 'compilation-filter-hook #'doom|apply-ansi-color-to-compilation-buffer)
|
||||
;; 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)
|
||||
;; Make `next-buffer', `other-buffer', etc. ignore unreal buffers.
|
||||
(add-to-list 'default-frame-alist '(buffer-predicate . doom-buffer-frame-predicate))
|
||||
;; Prevent the glimpse of un-styled Emacs by setting these early.
|
||||
(add-to-list 'default-frame-alist '(tool-bar-lines . 0))
|
||||
(add-to-list 'default-frame-alist '(menu-bar-lines . 0))
|
||||
(add-to-list 'default-frame-alist '(vertical-scroll-bars))
|
||||
;; prompts the user for confirmation when deleting a non-empty frame
|
||||
(global-set-key [remap delete-frame] #'doom/delete-frame)
|
||||
|
||||
|
||||
;;
|
||||
;; Third party packages
|
||||
;;; Built-in packages
|
||||
|
||||
;; `avy'
|
||||
(setq avy-all-windows nil
|
||||
avy-background t)
|
||||
;; Disable these because whitespace should be customized programmatically
|
||||
;; (through `whitespace-style'), and not through these commands.
|
||||
(put 'whitespace-toggle-options 'disabled t)
|
||||
(put 'global-whitespace-toggle-options 'disabled 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)
|
||||
:init
|
||||
(defun doom*disable-all-the-icons-in-tty (orig-fn &rest args)
|
||||
(if (display-graphic-p)
|
||||
(apply orig-fn args)
|
||||
""))
|
||||
:config
|
||||
;; all-the-icons doesn't work in the terminal, so we "disable" it.
|
||||
(dolist (fn '(all-the-icons-octicon all-the-icons-material
|
||||
all-the-icons-faicon all-the-icons-fileicon
|
||||
all-the-icons-wicon all-the-icons-alltheicon))
|
||||
(advice-add fn :around #'doom*disable-all-the-icons-in-tty)))
|
||||
|
||||
;; `hide-mode-line-mode'
|
||||
(add-hook 'completion-list-mode-hook #'hide-mode-line-mode)
|
||||
(add-hook 'Man-mode-hook #'hide-mode-line-mode)
|
||||
|
||||
;; `highlight-numbers' --- better number literal fontification in code
|
||||
(def-package! highlight-numbers
|
||||
:hook ((prog-mode conf-mode) . highlight-numbers-mode)
|
||||
:config (setq highlight-numbers-generic-regexp "\\_<[[:digit:]]+\\(?:\\.[0-9]*\\)?\\_>"))
|
||||
|
||||
;; `highlight-escape-sequences'
|
||||
(def-package! highlight-escape-sequences
|
||||
:hook ((prog-mode conf-mode) . highlight-escape-sequences-mode))
|
||||
|
||||
;; `rainbow-delimiters' --- helps us distinguish stacked delimiter pairs.
|
||||
;; Especially in parentheses-drunk languages like Lisp.
|
||||
(setq rainbow-delimiters-max-face-count 3)
|
||||
|
||||
;; `restart-emacs' --- provides a simple mechanism for restarting Emacs and
|
||||
;; daemons interactively.
|
||||
(setq restart-emacs--args (list "--restore"))
|
||||
|
||||
;; `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 EMACS26+ 6 0) fill-column))
|
||||
|
||||
|
||||
;;
|
||||
;; Built-in packages
|
||||
|
||||
(def-package! ediff
|
||||
:defer t
|
||||
|
@ -169,13 +237,15 @@ behavior). Do not set this directly, this is let-bound in `doom|init-theme'.")
|
|||
ediff-split-window-function #'split-window-horizontally
|
||||
ediff-window-setup-function #'ediff-setup-windows-plain)
|
||||
:config
|
||||
(defvar doom--ediff-saved-wconf nil)
|
||||
;; Restore window config after quitting ediff
|
||||
(defun doom|ediff-save-wconf ()
|
||||
(setq +ediff--saved-wconf (current-window-configuration)))
|
||||
(setq doom--ediff-saved-wconf (current-window-configuration)))
|
||||
(add-hook 'ediff-before-setup-hook #'doom|ediff-save-wconf)
|
||||
|
||||
(defun doom|ediff-restore-wconf ()
|
||||
(set-window-configuration +ediff--saved-wconf))
|
||||
(when (window-configuration-p doom--ediff-saved-wconf)
|
||||
(set-window-configuration doom--ediff-saved-wconf)))
|
||||
(add-hook 'ediff-quit-hook #'doom|ediff-restore-wconf 'append)
|
||||
(add-hook 'ediff-suspend-hook #'doom|ediff-restore-wconf 'append))
|
||||
|
||||
|
@ -189,21 +259,6 @@ behavior). Do not set this directly, this is let-bound in `doom|init-theme'.")
|
|||
(setq hl-line-sticky-flag nil
|
||||
global-hl-line-sticky-flag nil)
|
||||
|
||||
;; On Emacs 26+, when point is on the last line, hl-line highlights bleed into
|
||||
;; the rest of the window after eob. This is the fix.
|
||||
(when EMACS26+
|
||||
(defun doom--line-range ()
|
||||
(cons (line-beginning-position)
|
||||
(cond ((let ((eol (line-end-position)))
|
||||
(and (= eol (point-max))
|
||||
(/= eol (line-beginning-position))))
|
||||
(1- (line-end-position)))
|
||||
((or (eobp)
|
||||
(= (line-end-position 2) (point-max)))
|
||||
(line-end-position))
|
||||
((line-beginning-position 2)))))
|
||||
(setq hl-line-range-function #'doom--line-range))
|
||||
|
||||
;; Disable `hl-line' in evil-visual mode (temporarily). `hl-line' can make the
|
||||
;; selection region harder to see while in evil visual mode.
|
||||
(after! evil
|
||||
|
@ -220,14 +275,14 @@ behavior). Do not set this directly, this is let-bound in `doom|init-theme'.")
|
|||
|
||||
(def-package! winner
|
||||
;; undo/redo changes to Emacs' window layout
|
||||
:after-call doom-exit-window-hook
|
||||
:preface (defvar winner-dont-bind-my-keys t) ; I'll bind keys myself
|
||||
:config (winner-mode +1))
|
||||
:after-call (after-find-file doom-switch-window-hook)
|
||||
:preface (defvar winner-dont-bind-my-keys t)
|
||||
:config (winner-mode +1)) ; I'll bind keys myself
|
||||
|
||||
|
||||
(def-package! paren
|
||||
;; highlight matching delimiters
|
||||
:after-call (after-find-file doom-exit-buffer-hook)
|
||||
:after-call (after-find-file doom-switch-buffer-hook)
|
||||
:init
|
||||
(defun doom|disable-show-paren-mode ()
|
||||
"Turn off `show-paren-mode' buffer-locally."
|
||||
|
@ -259,7 +314,56 @@ behavior). Do not set this directly, this is let-bound in `doom|init-theme'.")
|
|||
|
||||
|
||||
;;
|
||||
;; Line numbers
|
||||
;;; Third party packages
|
||||
|
||||
;;;###package avy
|
||||
(setq avy-all-windows nil
|
||||
avy-background t)
|
||||
|
||||
(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)
|
||||
:init
|
||||
(defun doom*disable-all-the-icons-in-tty (orig-fn &rest args)
|
||||
(if (display-graphic-p)
|
||||
(apply orig-fn args)
|
||||
""))
|
||||
:config
|
||||
;; all-the-icons doesn't work in the terminal, so we "disable" it.
|
||||
(dolist (fn '(all-the-icons-octicon all-the-icons-material
|
||||
all-the-icons-faicon all-the-icons-fileicon
|
||||
all-the-icons-wicon all-the-icons-alltheicon))
|
||||
(advice-add fn :around #'doom*disable-all-the-icons-in-tty)))
|
||||
|
||||
;;;###package hide-mode-line-mode
|
||||
(add-hook 'completion-list-mode-hook #'hide-mode-line-mode)
|
||||
(add-hook 'Man-mode-hook #'hide-mode-line-mode)
|
||||
|
||||
;; Better fontification of number literals in code
|
||||
(def-package! highlight-numbers
|
||||
:hook ((prog-mode conf-mode) . highlight-numbers-mode)
|
||||
:config (setq highlight-numbers-generic-regexp "\\_<[[:digit:]]+\\(?:\\.[0-9]*\\)?\\_>"))
|
||||
|
||||
;;;###package highlight-escape-sequences
|
||||
(def-package! highlight-escape-sequences
|
||||
:hook ((prog-mode conf-mode) . highlight-escape-sequences-mode))
|
||||
|
||||
;;;###package rainbow-delimiters
|
||||
;; Helps us distinguish stacked delimiter pairs, especially in parentheses-drunk
|
||||
;; languages like Lisp.
|
||||
(setq rainbow-delimiters-max-face-count 3)
|
||||
|
||||
;;;###package 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 EMACS26+ 6 0) fill-column))
|
||||
|
||||
|
||||
;;
|
||||
;;; Line numbers
|
||||
|
||||
;; line numbers in most modes
|
||||
(add-hook! (prog-mode text-mode conf-mode) #'display-line-numbers-mode)
|
||||
|
@ -267,8 +371,7 @@ behavior). Do not set this directly, this is let-bound in `doom|init-theme'.")
|
|||
(defun doom|enable-line-numbers () (display-line-numbers-mode +1))
|
||||
(defun doom|disable-line-numbers () (display-line-numbers-mode -1))
|
||||
|
||||
;; Emacs 26+ has native line number support, and will ignore nlinum. This is for
|
||||
;; Emacs 25 users:
|
||||
;; `nlinum' is used for Emacs 25 users, as Emacs 26+ has native line numbers.
|
||||
(def-package! nlinum
|
||||
;; Line number column. A faster (or equivalent, in the worst case) line number
|
||||
;; plugin than `linum-mode'.
|
||||
|
@ -332,18 +435,18 @@ character that looks like a space that `whitespace-mode' won't affect.")
|
|||
(advice-add #'web-mode-fold-or-unfold :after #'nlinum-hl-do-generic-flush)
|
||||
;; Changing fonts can leave nlinum line numbers in their original size; this
|
||||
;; forces them to resize.
|
||||
(advice-add #'set-frame-font :after #'nlinum-hl-flush-all-windows))
|
||||
(add-hook 'after-setting-font-hook #'nlinum-hl-flush-all-windows))
|
||||
|
||||
(def-package! nlinum-relative
|
||||
:unless EMACS26+
|
||||
:defer t
|
||||
:config
|
||||
(setq nlinum-format " %d ")
|
||||
(add-hook 'evil-mode #'nlinum-relative-setup-evil))
|
||||
(add-hook 'evil-mode-hook #'nlinum-relative-setup-evil))
|
||||
|
||||
|
||||
;;
|
||||
;; Theme & font
|
||||
;;; Theme & font
|
||||
|
||||
(defvar doom-last-window-system
|
||||
(if (daemonp) 'daemon initial-window-system)
|
||||
|
@ -351,12 +454,13 @@ character that looks like a space that `whitespace-mode' won't affect.")
|
|||
frame's window-system, the theme will be reloaded.")
|
||||
|
||||
(defun doom|init-fonts ()
|
||||
"Initialize fonts."
|
||||
"Loads fonts.
|
||||
|
||||
Fonts are specified by `doom-font', `doom-variable-pitch-font',
|
||||
`doom-serif-font' and `doom-unicode-font'."
|
||||
(condition-case e
|
||||
(progn
|
||||
(cond (doom-font
|
||||
;; We avoid `set-frame-font' for performance reasons.
|
||||
;; Manipulating `default-frame-alist' is effective enough.
|
||||
(add-to-list
|
||||
'default-frame-alist
|
||||
(cons 'font
|
||||
|
@ -380,20 +484,27 @@ frame's window-system, the theme will be reloaded.")
|
|||
(signal 'doom-error e)))))
|
||||
|
||||
(defun doom|init-theme ()
|
||||
"Set the theme and load the font, in that order."
|
||||
"Load the theme specified by `doom-theme'."
|
||||
(when (and doom-theme (not (memq doom-theme custom-enabled-themes)))
|
||||
(let ((doom--prefer-theme-elc t))
|
||||
(load-theme doom-theme t))))
|
||||
|
||||
;; Getting themes to remain consistent across GUI Emacs, terminal Emacs and
|
||||
;; daemon Emacs is hairy. `doom|init-theme' sorts out the initial GUI frame.
|
||||
;; Attaching `doom|init-theme-in-frame' to `after-make-frame-functions' sorts
|
||||
;; out daemon and emacsclient frames.
|
||||
;;
|
||||
;; There will still be issues with simultaneous gui and terminal (emacsclient)
|
||||
;; frames, however. There's always `doom/reload-theme' if you need it!
|
||||
(defun doom|reload-theme-maybe (_frame)
|
||||
"Reloads the theme if the display device has changed."
|
||||
(unless (cl-find doom-last-window-system (frame-list) :key #'framep-on-display)
|
||||
(setq doom-last-window-system nil)
|
||||
(doom|reload-theme-in-frame-maybe (selected-frame))))
|
||||
|
||||
(defun doom|reload-theme-in-frame-maybe (frame)
|
||||
"Reloads the theme in new daemon or tty frames."
|
||||
"Reloads the theme if the display device has changed.
|
||||
|
||||
Getting themes to remain consistent across GUI Emacs, terminal Emacs and daemon
|
||||
Emacs is hairy. `doom|init-theme' sorts out the initial GUI frame. Attaching
|
||||
`doom|reload-theme-in-frame-maybe' to `after-make-frame-functions' sorts out
|
||||
daemon and emacsclient frames.
|
||||
|
||||
There will still be issues with simultaneous gui and terminal (emacsclient)
|
||||
frames, however. There's always `doom/reload-theme' if you need it!"
|
||||
(when (and doom-theme
|
||||
(framep frame)
|
||||
(not (eq doom-last-window-system (framep-on-display frame))))
|
||||
|
@ -401,109 +512,47 @@ frame's window-system, the theme will be reloaded.")
|
|||
(load-theme doom-theme t))
|
||||
(setq doom-last-window-system (framep-on-display frame))))
|
||||
|
||||
(defun doom|reload-theme-maybe (_frame)
|
||||
"Reloads the theme after closing the last frame of a type."
|
||||
(unless (cl-find doom-last-window-system (frame-list) :key #'framep-on-display)
|
||||
(setq doom-last-window-system nil)
|
||||
(doom|reload-theme-in-frame (selected-frame))))
|
||||
|
||||
;; fonts
|
||||
(add-hook 'doom-init-ui-hook #'doom|init-fonts)
|
||||
;; themes
|
||||
(unless (daemonp)
|
||||
(add-hook 'doom-init-ui-hook #'doom|init-theme))
|
||||
(add-hook 'after-make-frame-functions #'doom|reload-theme-in-frame-maybe)
|
||||
(add-hook 'after-delete-frame-functions #'doom|reload-theme-maybe)
|
||||
|
||||
|
||||
;;
|
||||
;; Bootstrap
|
||||
|
||||
;; simple name in frame title
|
||||
(setq frame-title-format '("%b – Doom Emacs"))
|
||||
|
||||
;; relegate tooltips to echo area only
|
||||
(if (boundp 'tooltip-mode) (tooltip-mode -1))
|
||||
|
||||
;; enabled by default; no thanks, too distracting
|
||||
(blink-cursor-mode -1)
|
||||
|
||||
;; Handle ansi codes in compilation buffer
|
||||
(add-hook 'compilation-filter-hook #'doom|apply-ansi-color-to-compilation-buffer)
|
||||
|
||||
;; 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)
|
||||
|
||||
;; Make `next-buffer', `other-buffer', etc. ignore unreal buffers.
|
||||
(add-to-list 'default-frame-alist '(buffer-predicate . doom-buffer-frame-predicate))
|
||||
;; Prevent the glimpse of un-styled Emacs by setting these early.
|
||||
(add-to-list 'default-frame-alist '(tool-bar-lines . 0))
|
||||
(add-to-list 'default-frame-alist '(menu-bar-lines . 0))
|
||||
(add-to-list 'default-frame-alist '(vertical-scroll-bars))
|
||||
;; prompts the user for confirmation when deleting a non-empty frame
|
||||
(global-set-key [remap delete-frame] #'doom/delete-frame)
|
||||
|
||||
(defun doom|protect-visible-buffer ()
|
||||
"Don't kill the current buffer if it is visible in another window (bury it
|
||||
instead). Meant for `kill-buffer-query-functions'."
|
||||
(not (and (delq (selected-window) (get-buffer-window-list nil nil t))
|
||||
(not (member (substring (buffer-name) 0 1) '(" " "*"))))))
|
||||
|
||||
(defun doom|protect-fallback-buffer ()
|
||||
"Don't kill the scratch buffer. Meant for `kill-buffer-query-functions'."
|
||||
(not (eq (current-buffer) (doom-fallback-buffer))))
|
||||
|
||||
(defun doom|highlight-non-default-indentation ()
|
||||
"Highlight whitespace that doesn't match your `indent-tabs-mode' setting.
|
||||
|
||||
e.g. If you indent with spaces by default, tabs will be highlighted. If you
|
||||
indent with tabs, spaces at BOL are highlighted.
|
||||
|
||||
Does nothing if `whitespace-mode' is already active or the current buffer is
|
||||
read-only or not file-visiting."
|
||||
(unless (or (bound-and-true-p global-whitespace-mode)
|
||||
(bound-and-true-p whitespace-mode)
|
||||
(eq major-mode 'fundamental-mode)
|
||||
buffer-read-only
|
||||
(null buffer-file-name))
|
||||
(require 'whitespace)
|
||||
(set (make-local-variable 'whitespace-style)
|
||||
(if (bound-and-true-p whitespace-newline-mode)
|
||||
(cl-union (if indent-tabs-mode '(indentation) '(tabs tab-mark))
|
||||
whitespace-style)
|
||||
`(face ,@(if indent-tabs-mode '(indentation) '(tabs tab-mark))
|
||||
trailing-lines tail)))
|
||||
(whitespace-mode +1)))
|
||||
;;; Bootstrap
|
||||
|
||||
(defun doom|init-ui ()
|
||||
"Initialize Doom's user interface by applying all its advice and hooks."
|
||||
(add-to-list 'kill-buffer-query-functions #'doom|protect-fallback-buffer nil #'eq)
|
||||
(add-to-list 'kill-buffer-query-functions #'doom|protect-visible-buffer nil #'eq)
|
||||
(add-hook 'after-change-major-mode-hook #'doom|highlight-non-default-indentation)
|
||||
(run-hook-wrapped 'doom-init-ui-hook #'doom-try-run-hook))
|
||||
(run-hook-wrapped 'doom-init-ui-hook #'doom-try-run-hook)
|
||||
|
||||
(add-hook 'emacs-startup-hook #'doom|init-ui)
|
||||
(add-to-list 'kill-buffer-query-functions #'doom|protect-fallback-buffer nil 'eq)
|
||||
(add-hook 'after-change-major-mode-hook #'doom|highlight-non-default-indentation)
|
||||
|
||||
;; Reload theme if the display device has changed
|
||||
(add-hook 'after-make-frame-functions #'doom|reload-theme-in-frame-maybe)
|
||||
(add-hook 'after-delete-frame-functions #'doom|reload-theme-maybe)
|
||||
|
||||
;; Initialize custom switch-{buffer,window,frame} hooks:
|
||||
;; + `doom-switch-buffer-hook'
|
||||
;; + `doom-switch-window-hook'
|
||||
;; + `doom-switch-frame-hook'
|
||||
(add-hook 'buffer-list-update-hook #'doom|run-switch-window-hooks)
|
||||
(add-hook 'focus-in-hook #'doom|run-switch-frame-hooks)
|
||||
(advice-add! '(switch-to-buffer display-buffer) :around #'doom*run-switch-buffer-hooks))
|
||||
|
||||
;; Apply `doom-theme'
|
||||
(unless (daemonp)
|
||||
(add-hook 'doom-init-ui-hook #'doom|init-theme))
|
||||
;; Apply `doom-font' et co
|
||||
(add-hook 'doom-after-init-modules-hook #'doom|init-fonts)
|
||||
;; Setup `doom-load-theme-hook'
|
||||
(advice-add #'load-theme :after #'doom*run-load-theme-hooks)
|
||||
|
||||
(add-hook 'window-setup-hook #'doom|init-ui)
|
||||
|
||||
|
||||
;;
|
||||
;; Fixes/hacks
|
||||
;;; Fixes/hacks
|
||||
|
||||
;; doesn't exist in terminal Emacs; we define it to prevent errors
|
||||
(unless (fboundp 'define-fringe-bitmap)
|
||||
(defun define-fringe-bitmap (&rest _)))
|
||||
|
||||
(defun doom*disable-old-themes-first (orig-fn &rest args)
|
||||
(mapc #'disable-theme custom-enabled-themes)
|
||||
(apply orig-fn args)
|
||||
(when (fboundp 'powerline-reset)
|
||||
(powerline-reset)))
|
||||
(advice-add #'load-theme :around #'doom*disable-old-themes-first)
|
||||
|
||||
(defun doom*prefer-compiled-theme (orig-fn &rest args)
|
||||
"Make `load-theme' prioritize the byte-compiled theme for a moderate boost in
|
||||
startup (or theme switch) time, so long as `doom--prefer-theme-elc' is non-nil."
|
||||
|
@ -517,27 +566,37 @@ startup (or theme switch) time, so long as `doom--prefer-theme-elc' is non-nil."
|
|||
(apply orig-fn args)))
|
||||
(advice-add #'load-theme :around #'doom*prefer-compiled-theme)
|
||||
|
||||
(defun doom|disable-whitespace-mode-in-childframes (frame)
|
||||
"`whitespace-mode' inundates child frames with whitspace markers, so disable
|
||||
(after! whitespace
|
||||
(defun doom*disable-whitespace-mode-in-childframes (orig-fn)
|
||||
"`whitespace-mode' inundates child frames with whitspace markers, so disable
|
||||
it to fix all that visual noise."
|
||||
(when (frame-parameter frame 'parent-frame)
|
||||
(with-selected-frame frame
|
||||
(setq-local whitespace-style nil)
|
||||
frame)))
|
||||
(add-hook 'after-make-frame-functions #'doom|disable-whitespace-mode-in-childframes)
|
||||
(unless (frame-parameter nil 'parent-frame)
|
||||
(funcall orig-fn)))
|
||||
(add-function :around whitespace-enable-predicate #'doom*disable-whitespace-mode-in-childframes)
|
||||
|
||||
(defun doom*silence-motion-errors (orig-fn &rest args)
|
||||
"Prevent disruptive motion errors taking over the minibuffer while we're in
|
||||
it."
|
||||
(if (not (minibufferp))
|
||||
(apply orig-fn args)
|
||||
(ignore-errors (apply orig-fn args))
|
||||
(when (<= (point) (minibuffer-prompt-end))
|
||||
(goto-char (minibuffer-prompt-end)))))
|
||||
(advice-add #'left-char :around #'doom*silence-motion-errors)
|
||||
(advice-add #'right-char :around #'doom*silence-motion-errors)
|
||||
(advice-add #'delete-backward-char :around #'doom*silence-motion-errors)
|
||||
(advice-add #'backward-kill-sentence :around #'doom*silence-motion-errors)
|
||||
(defun doom|disable-whitespace-mode-in-childframes (frame)
|
||||
"`whitespace-mode' inundates child frames with whitspace markers, so disable
|
||||
it to fix all that visual noise."
|
||||
(when (frame-parameter frame 'parent-frame)
|
||||
(with-selected-frame frame
|
||||
(setq-local whitespace-style nil)
|
||||
frame)))
|
||||
(add-hook 'after-make-frame-functions #'doom|disable-whitespace-mode-in-childframes))
|
||||
|
||||
;; Don't allow cursor to enter the prompt
|
||||
(setq minibuffer-prompt-properties '(read-only t intangible t cursor-intangible t face minibuffer-prompt))
|
||||
(add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)
|
||||
|
||||
;; Don't display messages in the minibuffer when using the minibuffer
|
||||
(defmacro doom-silence-motion-key (command key)
|
||||
(let ((key-command (intern (format "doom/silent-%s" command))))
|
||||
`(progn
|
||||
(defun ,key-command ()
|
||||
(interactive)
|
||||
(ignore-errors (call-interactively ',command)))
|
||||
(define-key minibuffer-local-map (kbd ,key) #',key-command))))
|
||||
(doom-silence-motion-key backward-delete-char "<backspace>")
|
||||
(doom-silence-motion-key delete-char "<delete>")
|
||||
|
||||
;; Switch to `doom-fallback-buffer' if on last real buffer
|
||||
(advice-add #'kill-this-buffer :around #'doom*switch-to-fallback-buffer-maybe)
|
||||
|
|
199
core/core.el
199
core/core.el
|
@ -113,94 +113,9 @@ Doom was setup, which can cause problems.")
|
|||
;;
|
||||
;; Custom hooks
|
||||
|
||||
(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 near the end of
|
||||
`emacs-startup-hook', as late as possible. Guaranteed to run after everything
|
||||
else (except for `window-setup-hook').")
|
||||
|
||||
(defvar doom-reload-hook nil
|
||||
"A list of hooks to run when `doom/reload' is called.")
|
||||
|
||||
(defvar doom-load-theme-hook nil
|
||||
"Hook run after the theme is loaded with `load-theme' or reloaded with
|
||||
`doom/reload-theme'.")
|
||||
|
||||
(defvar doom-exit-window-hook nil
|
||||
"Hook run before `switch-window' or `switch-frame' are called.
|
||||
|
||||
Also see `doom-enter-window-hook'.")
|
||||
|
||||
(defvar doom-enter-window-hook nil
|
||||
"Hook run after `switch-window' or `switch-frame' are called.
|
||||
|
||||
Also see `doom-exit-window-hook'.")
|
||||
|
||||
(defvar doom-exit-buffer-hook nil
|
||||
"Hook run after `switch-to-buffer', `pop-to-buffer' or `display-buffer' are
|
||||
called. The buffer to be switched to is current when these hooks run.
|
||||
|
||||
Also see `doom-enter-buffer-hook'.")
|
||||
|
||||
(defvar doom-enter-buffer-hook nil
|
||||
"Hook run before `switch-to-buffer', `pop-to-buffer' or `display-buffer' are
|
||||
called. The buffer to be switched to is current when these hooks run.
|
||||
|
||||
Also see `doom-exit-buffer-hook'.")
|
||||
|
||||
(defvar doom-inhibit-switch-buffer-hooks nil
|
||||
"Letvar for inhibiting `doom-enter-buffer-hook' and `doom-exit-buffer-hook'.
|
||||
Do not set this directly.")
|
||||
(defvar doom-inhibit-switch-window-hooks nil
|
||||
"Letvar for inhibiting `doom-enter-window-hook' and `doom-exit-window-hook'.
|
||||
Do not set this directly.")
|
||||
|
||||
(defun doom*switch-window-hooks (orig-fn window &optional norecord)
|
||||
(if (or doom-inhibit-switch-window-hooks
|
||||
(null window)
|
||||
(eq window (selected-window))
|
||||
(window-minibuffer-p)
|
||||
(window-minibuffer-p window))
|
||||
(funcall orig-fn window norecord)
|
||||
(let ((doom-inhibit-switch-window-hooks t))
|
||||
(run-hooks 'doom-exit-window-hook)
|
||||
(prog1 (funcall orig-fn window norecord)
|
||||
(with-selected-window window
|
||||
(run-hooks 'doom-enter-window-hook))))))
|
||||
|
||||
(defun doom*switch-buffer-hooks (orig-fn buffer-or-name &rest args)
|
||||
(if (or doom-inhibit-switch-buffer-hooks
|
||||
(eq (get-buffer buffer-or-name) (current-buffer)))
|
||||
(apply orig-fn buffer-or-name args)
|
||||
(let ((doom-inhibit-switch-buffer-hooks t))
|
||||
(run-hooks 'doom-exit-buffer-hook)
|
||||
(prog1 (apply orig-fn buffer-or-name args)
|
||||
(when (buffer-live-p (get-buffer buffer-or-name))
|
||||
(with-current-buffer buffer-or-name
|
||||
(run-hooks 'doom-enter-buffer-hook)))))))
|
||||
|
||||
(defun doom|init-switch-hooks (&optional disable)
|
||||
"Set up enter/exit hooks for windows and buffers.
|
||||
|
||||
See `doom-enter-buffer-hook', `doom-enter-window-hook', `doom-exit-buffer-hook'
|
||||
and `doom-exit-window-hook'."
|
||||
(dolist (spec '((select-window . doom*switch-window-hooks)
|
||||
(switch-to-buffer . doom*switch-buffer-hooks)
|
||||
(display-buffer . doom*switch-buffer-hooks)
|
||||
(pop-to-buffer . doom*switch-buffer-hooks)))
|
||||
(if disable
|
||||
(advice-remove (car spec) (cdr spec))
|
||||
(advice-add (car spec) :around (cdr spec)))))
|
||||
|
||||
(defun doom*load-theme-hooks (theme &rest _)
|
||||
"Set up `doom-load-theme-hook' to run after `load-theme' is called."
|
||||
(setq doom-theme theme)
|
||||
(run-hooks 'doom-load-theme-hook))
|
||||
(advice-add #'load-theme :after #'doom*load-theme-hooks)
|
||||
|
||||
|
||||
;;
|
||||
;; Emacs core configuration
|
||||
|
@ -208,12 +123,10 @@ and `doom-exit-window-hook'."
|
|||
;; UTF-8 as the default coding system
|
||||
(when (fboundp 'set-charset-priority)
|
||||
(set-charset-priority 'unicode)) ; pretty
|
||||
(prefer-coding-system 'utf-8) ; pretty
|
||||
(set-terminal-coding-system 'utf-8) ; pretty
|
||||
(set-keyboard-coding-system 'utf-8) ; pretty
|
||||
(set-selection-coding-system 'utf-8) ; perdy
|
||||
(setq locale-coding-system 'utf-8) ; please
|
||||
(setq-default buffer-file-coding-system 'utf-8) ; with sugar on top
|
||||
(prefer-coding-system 'utf-8) ; pretty
|
||||
(setq selection-coding-system 'utf-8) ; pretty
|
||||
(setq locale-coding-system 'utf-8) ; please
|
||||
(if IS-WINDOWS (set-w32-system-coding-system 'utf-8)) ; with sugar on top
|
||||
|
||||
(setq-default
|
||||
ad-redefinition-action 'accept ; silence advised function warnings
|
||||
|
@ -230,8 +143,6 @@ and `doom-exit-window-hook'."
|
|||
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)
|
||||
auto-save-default nil
|
||||
create-lockfiles nil
|
||||
|
@ -255,6 +166,9 @@ and `doom-exit-window-hook'."
|
|||
async-byte-compile-log-file (concat doom-etc-dir "async-bytecomp.log")
|
||||
auto-save-list-file-name (concat doom-cache-dir "autosave")
|
||||
backup-directory-alist (list (cons "." (concat doom-cache-dir "backup/")))
|
||||
desktop-dirname (concat doom-etc-dir "desktop")
|
||||
desktop-base-file-name "autosave"
|
||||
desktop-base-lock-name "autosave-lock"
|
||||
pcache-directory (concat doom-cache-dir "pcache/")
|
||||
request-storage-directory (concat doom-cache-dir "request")
|
||||
server-auth-dir (concat doom-cache-dir "server/")
|
||||
|
@ -315,6 +229,13 @@ original value of `symbol-file'."
|
|||
#'doom-try-run-hook))
|
||||
(add-hook 'hack-local-variables-hook #'doom|run-local-var-hooks)
|
||||
|
||||
(defun doom|run-local-var-hooks-if-necessary ()
|
||||
"If `enable-local-variables' is disabled, then `hack-local-variables-hook' is
|
||||
never triggered."
|
||||
(unless enable-local-variables
|
||||
(doom|run-local-var-hooks)))
|
||||
(add-hook 'after-change-major-mode-hook #'doom|run-local-var-hooks-if-necessary)
|
||||
|
||||
|
||||
;;
|
||||
;; Incremental lazy-loading
|
||||
|
@ -357,17 +278,17 @@ intervals."
|
|||
(let* ((reqs (cl-delete-if #'featurep packages))
|
||||
(req (ignore-errors (pop reqs))))
|
||||
(when req
|
||||
(when doom-debug-mode
|
||||
(message "Incrementally loading %s" req))
|
||||
(doom-log "Incrementally loading %s" req)
|
||||
(condition-case e
|
||||
(require req nil t)
|
||||
(error
|
||||
((error debug)
|
||||
(message "Failed to load '%s' package incrementally, because: %s"
|
||||
req e)))
|
||||
(when reqs
|
||||
(run-with-idle-timer doom-incremental-idle-timer
|
||||
nil #'doom-load-packages-incrementally
|
||||
reqs t))))))))
|
||||
(if reqs
|
||||
(run-with-idle-timer doom-incremental-idle-timer
|
||||
nil #'doom-load-packages-incrementally
|
||||
reqs t)
|
||||
(doom-log "Finished incremental loading"))))))))
|
||||
|
||||
(defun doom|load-packages-incrementally ()
|
||||
"Begin incrementally loading packages in `doom-incremental-packages'.
|
||||
|
@ -380,7 +301,7 @@ If this is a daemon session, load them all immediately instead."
|
|||
nil #'doom-load-packages-incrementally
|
||||
(cdr doom-incremental-packages) t))))
|
||||
|
||||
(add-hook 'emacs-startup-hook #'doom|load-packages-incrementally)
|
||||
(add-hook 'window-setup-hook #'doom|load-packages-incrementally)
|
||||
|
||||
|
||||
;;
|
||||
|
@ -391,8 +312,7 @@ If this is a daemon session, load them all immediately instead."
|
|||
issues easier.
|
||||
|
||||
Meant to be used with `run-hook-wrapped'."
|
||||
(when doom-debug-mode
|
||||
(message "Running doom hook: %s" hook))
|
||||
(doom-log "Running doom hook: %s" hook)
|
||||
(condition-case e
|
||||
(funcall hook)
|
||||
((debug error)
|
||||
|
@ -457,11 +377,18 @@ If RETURN-P, return the message as a string instead of displaying it."
|
|||
;;
|
||||
;; Bootstrap functions
|
||||
|
||||
(defun doom-initialize (&optional force-p force-load-core-p)
|
||||
"Bootstrap Doom, if it hasn't already (or if FORCE-P is non-nil).
|
||||
(defun doom-initialize-autoloads (file)
|
||||
"Tries to load FILE (an autoloads file). Return t on success, throws an error
|
||||
in interactive sessions, nil otherwise (but logs a warning)."
|
||||
(condition-case e
|
||||
(load (file-name-sans-extension file) 'noerror 'nomessage)
|
||||
((debug error)
|
||||
(if noninteractive
|
||||
(message "Autoload file warning: %s -> %s" (car e) (error-message-string e))
|
||||
(signal 'doom-autoload-error (list (file-name-nondirectory file) e))))))
|
||||
|
||||
Loads Doom core files if in an interactive session or FORCE-LOAD-CORE-P is
|
||||
non-nil.
|
||||
(defun doom-initialize (&optional force-p)
|
||||
"Bootstrap Doom, if it hasn't already (or if FORCE-P is non-nil).
|
||||
|
||||
The bootstrap process involves making sure 1) the essential directories exist,
|
||||
2) the core packages are installed, 3) `doom-autoload-file' and
|
||||
|
@ -477,12 +404,14 @@ The overall load order of Doom is as follows:
|
|||
~/.emacs.d/core/core.el
|
||||
~/.doom.d/init.el
|
||||
Module init.el files
|
||||
`doom-init-hook'
|
||||
`doom-before-init-modules-hook'
|
||||
Module config.el files
|
||||
~/.doom.d/config.el
|
||||
`doom-post-init-hook'
|
||||
`doom-init-modules-hook'
|
||||
`after-init-hook'
|
||||
`emacs-startup-hook'
|
||||
`doom-init-ui-hook'
|
||||
`window-setup-hook'
|
||||
|
||||
Module load order is determined by your `doom!' block. See `doom-modules-dirs'
|
||||
for a list of all recognized module trees. Order defines precedence (from most
|
||||
|
@ -508,47 +437,45 @@ to least)."
|
|||
;; autoloads file and caches `load-path', `auto-mode-alist',
|
||||
;; `Info-directory-list', `doom-disabled-packages' and
|
||||
;; `package-activated-list'. A big reduction in startup time.
|
||||
(unless (or force-p
|
||||
(doom-initialize-autoloads doom-package-autoload-file)
|
||||
noninteractive)
|
||||
(user-error "Your package autoloads are missing! Run `bin/doom refresh' to regenerate them")))
|
||||
(let (command-switch-alist)
|
||||
(unless (or force-p
|
||||
(doom-initialize-autoloads doom-package-autoload-file)
|
||||
noninteractive)
|
||||
(user-error "Your package autoloads are missing! Run `bin/doom refresh' to regenerate them"))))
|
||||
|
||||
(require 'core-lib)
|
||||
(require 'core-modules)
|
||||
(require 'core-os)
|
||||
(when (or force-load-core-p (not noninteractive))
|
||||
(add-hook! 'emacs-startup-hook
|
||||
#'(doom|init-switch-hooks doom|display-benchmark))
|
||||
|
||||
(if noninteractive
|
||||
(require 'core-cli)
|
||||
(add-hook 'window-setup-hook #'doom|display-benchmark)
|
||||
(require 'core-keybinds)
|
||||
(require 'core-ui)
|
||||
(require 'core-editor)
|
||||
(require 'core-projects)
|
||||
(require 'core-keybinds)))
|
||||
|
||||
(defun doom-initialize-autoloads (file)
|
||||
"Tries to load FILE (an autoloads file). Return t on success, throws an error
|
||||
in interactive sessions, nil otherwise (but logs a warning)."
|
||||
(condition-case e
|
||||
(load (file-name-sans-extension file) 'noerror 'nomessage)
|
||||
((debug error)
|
||||
(if noninteractive
|
||||
(message "Autoload file warning: %s -> %s" (car e) (error-message-string e))
|
||||
(signal 'doom-autoload-error (list (file-name-nondirectory file) e))))))
|
||||
(require 'core-editor)))
|
||||
|
||||
|
||||
;;
|
||||
;; Bootstrap Doom
|
||||
|
||||
(add-to-list 'load-path doom-core-dir)
|
||||
(eval-and-compile
|
||||
(require 'subr-x)
|
||||
(require 'cl-lib)
|
||||
(unless EMACS26+
|
||||
(with-no-warnings
|
||||
;; if-let and when-let were moved to (if|when)-let* in Emacs 26+ so we
|
||||
;; alias them for 25 users.
|
||||
(defalias 'if-let* #'if-let)
|
||||
(defalias 'when-let* #'when-let))))
|
||||
|
||||
(require 'core-lib)
|
||||
(require 'core-modules)
|
||||
(when noninteractive
|
||||
(require 'core-cli))
|
||||
(after! package
|
||||
(require 'core-packages))
|
||||
(add-to-list 'load-path doom-core-dir)
|
||||
|
||||
(doom-initialize noninteractive)
|
||||
(unless noninteractive
|
||||
(doom-initialize-modules))
|
||||
(after! package
|
||||
(require 'core-packages)
|
||||
(doom-initialize-packages))
|
||||
|
||||
(provide 'core)
|
||||
;;; core.el ends here
|
||||
|
|
29
core/doctor.el
Normal file
29
core/doctor.el
Normal file
|
@ -0,0 +1,29 @@
|
|||
;;; core/doctor.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defun file-size (file &optional dir)
|
||||
(setq file (expand-file-name file dir))
|
||||
(when (file-exists-p file)
|
||||
(/ (nth 7 (file-attributes file))
|
||||
1024.0)))
|
||||
|
||||
;; Check for oversized problem files in cache that may cause unusual/tremendous
|
||||
;; delays or freezing. This shouldn't happen often.
|
||||
(dolist (file (list "savehist"
|
||||
"projectile.cache"))
|
||||
(let* ((path (expand-file-name file doom-core-dir))
|
||||
(size (file-size path)))
|
||||
(when (and (numberp size) (> size 2000))
|
||||
(warn! "%s is too large (%.02fmb). This may cause freezes or odd startup delays"
|
||||
(file-relative-name path doom-core-dir)
|
||||
(/ size 1024))
|
||||
(explain! "Consider deleting it from your system (manually)"))))
|
||||
|
||||
(when! (not (executable-find "fd"))
|
||||
(warn! "Couldn't find the `fd' binary; project file searches will be slightly slower"))
|
||||
|
||||
(let ((default-directory "~"))
|
||||
(require 'projectile)
|
||||
(when! (cl-find-if #'projectile-file-exists-p projectile-project-root-files-bottom-up)
|
||||
(warn! "Your $HOME is recognized as a project root")
|
||||
(explain! "Doom will disable bottom-up root search, which may reduce the accuracy of project\n"
|
||||
"detection.")))
|
|
@ -2,6 +2,7 @@
|
|||
;;; core/packages.el
|
||||
|
||||
;; core-os.el
|
||||
(package! xclip)
|
||||
(when IS-MAC
|
||||
(package! exec-path-from-shell)
|
||||
(package! osx-clipboard)
|
||||
|
@ -10,7 +11,6 @@
|
|||
;; core-ui.el
|
||||
(package! all-the-icons)
|
||||
(package! hide-mode-line)
|
||||
(package! highlight-indentation)
|
||||
(package! highlight-numbers)
|
||||
(package! highlight-escape-sequences
|
||||
:recipe (:fetcher github :repo "hlissner/highlight-escape-sequences"))
|
||||
|
@ -28,7 +28,6 @@
|
|||
(package! avy)
|
||||
(package! command-log-mode)
|
||||
(package! dtrt-indent)
|
||||
(package! expand-region)
|
||||
(package! helpful)
|
||||
(package! pcre2el)
|
||||
(package! smartparens)
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
;; Welcome to the vanilla sandbox!
|
||||
;;
|
||||
;; This is a test bed for running Emacs Lisp in either a vanilla Emacs session
|
||||
;; free of Doom's clutches (C-c C-c), or in a vanilla Doom session free of your
|
||||
;; private config (C-c C-d).
|
||||
|
||||
;; This is a test bed for running Emacs Lisp in an instance of Emacs with varying
|
||||
;; amounts of Doom loaded:
|
||||
;;
|
||||
;; a) vanilla Emacs (nothing loaded) \\[doom--run-vanilla-emacs]
|
||||
;; b) vanilla Doom (only Doom core) \\[doom--run-vanilla-doom]
|
||||
;; c) Doom + modules - your private config \\[doom--run-vanilla-doom+]
|
||||
;; d) Doom (normal) \\[doom--run-full-doom]
|
||||
;;
|
||||
;; This is done without sacrificing access to installed packages. Use the sandbox
|
||||
;; to reproduce bugs and determine if Doom is to blame.
|
||||
|
|
|
@ -1,31 +1,10 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; core/test/test-autoload-help.el
|
||||
|
||||
(load! "autoload/help" doom-core-dir)
|
||||
;; (load! "autoload/help" doom-core-dir)
|
||||
|
||||
;;
|
||||
(describe "core/autoload/help"
|
||||
:var (a)
|
||||
(before-each (setq a (switch-to-buffer (get-buffer-create "a"))))
|
||||
(after-each (kill-buffer a))
|
||||
|
||||
(describe "what-face"
|
||||
(before-each
|
||||
(insert (propertize "Hello " 'face 'font-lock-keyword-face))
|
||||
(insert "world"))
|
||||
(it "returns list of faces at point"
|
||||
(expect (doom/what-face nil (point-min)) :to-equal '((font-lock-keyword-face) ())))
|
||||
(it "returns nil if no faces at point"
|
||||
(expect (doom/what-face nil (point-max)) :to-be nil)))
|
||||
|
||||
(describe "what-face overlays"
|
||||
(before-each
|
||||
(insert "Hello world")
|
||||
(let ((ov (make-overlay 1 6)))
|
||||
(overlay-put ov 'face 'font-lock-keyword-face)))
|
||||
|
||||
(it "returns list of overlays at point"
|
||||
(expect (doom/what-face nil (point-min)) :to-equal '(() (font-lock-keyword-face))))
|
||||
(it "returns nil if no overlays at point"
|
||||
(expect (doom/what-face nil (point-max)) :to-be nil))))
|
||||
|
||||
;; (describe "core/autoload/help"
|
||||
;; :var (a)
|
||||
;; (before-each (setq a (switch-to-buffer (get-buffer-create "a"))))
|
||||
;; (after-each (kill-buffer a)))
|
||||
|
|
|
@ -55,8 +55,8 @@
|
|||
(doom-missing-dummy)
|
||||
(doom-noquelpa-dummy)
|
||||
(doom-disabled-dummy :disable t)
|
||||
(doom-private-dummy :private t)
|
||||
(doom-disabled-private-dummy :private t :disable t)
|
||||
(doom-private-dummy :modules ((:private)))
|
||||
(doom-disabled-private-dummy :modules ((:private)) :disable t)
|
||||
(doom-quelpa-dummy :recipe (doom-quelpa-dummy :fetcher github :repo "hlissner/does-not-exist")))
|
||||
quelpa-cache
|
||||
'((doom-quelpa-dummy :fetcher github :repo "hlissner/does-not-exist")
|
||||
|
@ -95,31 +95,31 @@
|
|||
(spy-on #'doom-package-installed-p :and-call-fake #'package-installed-p))
|
||||
|
||||
(it "returns all packages"
|
||||
(expect (mapcar #'car (doom-get-packages))
|
||||
(expect (mapcar #'car (doom-find-packages))
|
||||
:to-have-same-items-as
|
||||
(mapcar #'car doom-packages)))
|
||||
(it "returns only disabled packages"
|
||||
(expect (mapcar #'car (doom-get-packages :disabled t))
|
||||
(expect (mapcar #'car (doom-find-packages :disabled t))
|
||||
:to-have-same-items-as
|
||||
'(doom-disabled-dummy doom-disabled-private-dummy)))
|
||||
(it "returns only non-disabled packages"
|
||||
(expect (mapcar #'car (doom-get-packages :disabled nil))
|
||||
(expect (mapcar #'car (doom-find-packages :disabled nil))
|
||||
:to-have-same-items-as
|
||||
'(doom-dummy doom-uptodate-dummy doom-quelpa-dummy doom-missing-dummy doom-noquelpa-dummy doom-private-dummy)))
|
||||
(it "returns only installed packages"
|
||||
(expect (mapcar #'car (doom-get-packages :disabled nil :installed t))
|
||||
(expect (mapcar #'car (doom-find-packages :disabled nil :installed t))
|
||||
:to-have-same-items-as
|
||||
'(doom-dummy doom-uptodate-dummy doom-quelpa-dummy doom-noquelpa-dummy)))
|
||||
(it "returns only non-installed packages"
|
||||
(expect (mapcar #'car (doom-get-packages :disabled nil :installed nil))
|
||||
(expect (mapcar #'car (doom-find-packages :disabled nil :installed nil))
|
||||
:to-have-same-items-as
|
||||
'(doom-missing-dummy doom-private-dummy)))
|
||||
(it "returns only private packages"
|
||||
(expect (mapcar #'car (doom-get-packages :private t))
|
||||
(expect (mapcar #'car (doom-find-packages :private t))
|
||||
:to-have-same-items-as
|
||||
'(doom-private-dummy doom-disabled-private-dummy)))
|
||||
(it "returns only disabled and private packages"
|
||||
(expect (mapcar #'car (doom-get-packages :disabled t :private t))
|
||||
(expect (mapcar #'car (doom-find-packages :disabled t :private t))
|
||||
:to-have-same-items-as
|
||||
'(doom-disabled-private-dummy))))
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; core/test/test-core-keybinds.el
|
||||
|
||||
(require 'core-keybinds)
|
||||
|
||||
(buttercup-define-matcher :to-expand-into (src result)
|
||||
(let ((src (funcall src))
|
||||
(result (funcall result)))
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; core/test/test-core-lib.el
|
||||
|
||||
(require 'core-lib)
|
||||
|
||||
(describe "core/lib"
|
||||
;; --- Helpers ----------------------------
|
||||
(describe "doom-unquote"
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; core/test/test-core-modules.el
|
||||
|
||||
;; (require 'core-modules)
|
||||
|
||||
(describe "core-modules")
|
||||
|
|
|
@ -1,33 +1,9 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; ../core/test/test-core-ui.el
|
||||
|
||||
(require 'core-ui)
|
||||
|
||||
(describe "core/ui"
|
||||
(describe "doom|protect-visible-buffer"
|
||||
:var (kill-buffer-query-functions wconf a b)
|
||||
(before-each
|
||||
(setq a (switch-to-buffer (get-buffer-create "a"))
|
||||
b (get-buffer-create "b")
|
||||
kill-buffer-query-functions '(doom|protect-visible-buffer)
|
||||
wconf (current-window-configuration))
|
||||
(delete-other-windows))
|
||||
|
||||
(after-each
|
||||
(let (kill-buffer-query-functions kill-buffer-hook)
|
||||
(kill-buffer a)
|
||||
(kill-buffer b))
|
||||
(set-window-configuration wconf))
|
||||
|
||||
(it "shouldn't kill buffers that are visible in more than one window"
|
||||
(with-temp-buffer-window
|
||||
(switch-to-buffer a) (split-window)
|
||||
(switch-to-buffer b) (split-window)
|
||||
(switch-to-buffer a)
|
||||
(expect (kill-buffer) :to-be nil)
|
||||
|
||||
(select-window (get-buffer-window b))
|
||||
(expect (kill-buffer)))))
|
||||
|
||||
|
||||
(describe "doom|protect-fallback-buffer"
|
||||
:var (kill-buffer-query-functions a b)
|
||||
(before-all
|
||||
|
|
|
@ -61,43 +61,39 @@
|
|||
(before-each
|
||||
(setq a (switch-to-buffer (get-buffer-create "a"))
|
||||
b (get-buffer-create "b"))
|
||||
(spy-on 'before-hook)
|
||||
(spy-on 'after-hook)
|
||||
(doom|init-switch-hooks))
|
||||
(spy-on 'hook)
|
||||
(add-hook 'buffer-list-update-hook #'doom|run-switch-window-hooks)
|
||||
(add-hook 'focus-in-hook #'doom|run-switch-frame-hooks)
|
||||
(advice-add! '(switch-to-buffer display-buffer) :around #'doom*run-switch-buffer-hooks))
|
||||
(after-each
|
||||
(doom|init-switch-hooks 'disable)
|
||||
(remove-hook 'buffer-list-update-hook #'doom|run-switch-window-hooks)
|
||||
(remove-hook 'focus-in-hook #'doom|run-switch-frame-hooks)
|
||||
(advice-remove! '(switch-to-buffer display-buffer) #'doom*run-switch-buffer-hooks)
|
||||
(kill-buffer a)
|
||||
(kill-buffer b))
|
||||
|
||||
(describe "switch-buffer"
|
||||
:var (doom-exit-buffer-hook
|
||||
doom-enter-buffer-hook)
|
||||
:var (doom-switch-buffer-hook)
|
||||
(before-each
|
||||
(setq doom-exit-buffer-hook '(before-hook)
|
||||
doom-enter-buffer-hook '(after-hook)))
|
||||
(setq doom-switch-buffer-hook '(hook)))
|
||||
(after-each
|
||||
(setq doom-exit-buffer-hook nil
|
||||
doom-enter-buffer-hook nil))
|
||||
(setq doom-switch-buffer-hook nil))
|
||||
|
||||
(it "should trigger when switching buffers"
|
||||
(switch-to-buffer b)
|
||||
(switch-to-buffer a)
|
||||
(switch-to-buffer b)
|
||||
(expect 'before-hook :to-have-been-called-times 3)
|
||||
(expect 'after-hook :to-have-been-called-times 3))
|
||||
(expect 'hook :to-have-been-called-times 3))
|
||||
|
||||
(it "should trigger only once on the same buffer"
|
||||
(switch-to-buffer b)
|
||||
(switch-to-buffer b)
|
||||
(switch-to-buffer a)
|
||||
(expect 'before-hook :to-have-been-called-times 2)
|
||||
(expect 'after-hook :to-have-been-called-times 2)))
|
||||
(expect 'hook :to-have-been-called-times 2)))
|
||||
|
||||
|
||||
(describe "switch-window"
|
||||
:var (doom-exit-window-hook
|
||||
doom-enter-window-hook
|
||||
x y)
|
||||
:var (doom-switch-window-hook x y)
|
||||
(before-each
|
||||
(delete-other-windows)
|
||||
(setq x (get-buffer-window a)
|
||||
|
@ -105,21 +101,17 @@
|
|||
(with-selected-window y
|
||||
(switch-to-buffer b))
|
||||
(select-window x)
|
||||
(spy-calls-reset 'before-hook)
|
||||
(spy-calls-reset 'after-hook)
|
||||
(setq doom-exit-window-hook '(before-hook)
|
||||
doom-enter-window-hook '(after-hook)))
|
||||
(spy-calls-reset 'hook)
|
||||
(setq doom-switch-window-hook '(hook)))
|
||||
|
||||
(it "should trigger when switching windows"
|
||||
(select-window y)
|
||||
(select-window x)
|
||||
(select-window y)
|
||||
(expect 'before-hook :to-have-been-called-times 3)
|
||||
(expect 'after-hook :to-have-been-called-times 3))
|
||||
(expect 'hook :to-have-been-called-times 3))
|
||||
|
||||
(it "should trigger only once on the same window"
|
||||
(select-window y)
|
||||
(select-window y)
|
||||
(select-window x)
|
||||
(expect 'before-hook :to-have-been-called-times 2)
|
||||
(expect 'after-hook :to-have-been-called-times 2))))))
|
||||
(expect 'hook :to-have-been-called-times 2))))))
|
||||
|
|
|
@ -15,3 +15,6 @@
|
|||
(add-to-list 'default-frame-alist '(tool-bar-lines . 0))
|
||||
(add-to-list 'default-frame-alist '(menu-bar-lines . 0))
|
||||
(add-to-list 'default-frame-alist '(vertical-scroll-bars))
|
||||
|
||||
;; One less file to load at startup
|
||||
(setq site-run-file nil)
|
||||
|
|
|
@ -13,20 +13,20 @@
|
|||
|
||||
:completion
|
||||
company ; the ultimate code completion backend
|
||||
helm ; the *other* search engine for love and life
|
||||
;;helm ; the *other* search engine for love and life
|
||||
;;ido ; the other *other* search engine...
|
||||
;;ivy ; a search engine for love and life
|
||||
ivy ; a search engine for love and life
|
||||
|
||||
:ui
|
||||
;;deft ; notational velocity for Emacs
|
||||
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
|
||||
doom-quit ; DOOM quit-message prompts when you quit Emacs
|
||||
evil-goggles ; display visual hints when editing in evil
|
||||
;;fci ; a `fill-column' indicator
|
||||
hl-todo ; highlight TODO/FIXME/NOTE tags
|
||||
;;modeline ; snazzy, Atom-inspired modeline, plus API
|
||||
;;indent-guides ; highlighted indent columns
|
||||
modeline ; snazzy, Atom-inspired modeline, plus API
|
||||
nav-flash ; blink the current line after jumping
|
||||
;;neotree ; a project drawer, like NERDTree for vim
|
||||
treemacs ; a project drawer, like neotree but cooler
|
||||
|
@ -69,7 +69,7 @@
|
|||
;;gist ; interacting with github gists
|
||||
;;lsp
|
||||
;;macos ; MacOS-specific commands
|
||||
;;magit ; a git porcelain for Emacs
|
||||
magit ; a git porcelain for Emacs
|
||||
;;make ; run make tasks from Emacs
|
||||
;;password-store ; password manager for nerds
|
||||
;;pdf ; pdf enhancements
|
||||
|
|
171
modules/README.org
Normal file
171
modules/README.org
Normal file
|
@ -0,0 +1,171 @@
|
|||
#+TITLE: Doom Modules
|
||||
|
||||
* Table of Contents :TOC:noexport:
|
||||
- [[#feature][:feature]]
|
||||
- [[#completion][:completion]]
|
||||
- [[#ui][:ui]]
|
||||
- [[#editor][:editor]]
|
||||
- [[#emacs][:emacs]]
|
||||
- [[#tools][:tools]]
|
||||
- [[#lang][:lang]]
|
||||
- [[#app][:app]]
|
||||
- [[#collab][:collab]]
|
||||
- [[#config][:config]]
|
||||
|
||||
* :feature
|
||||
Broad modules that bring essential IDE functionality to Emacs.
|
||||
|
||||
+ debugger: A (nigh-)universal debugger in Emacs
|
||||
+ [[file:feature/eval/README.org][eval]]: REPL & code evaluation support for a variety of languages
|
||||
+ [[file:feature/evil/README.org][evil]] =+everywhere=: Vim in Emacs
|
||||
+ [[file:feature/file-templates/README.org][file-templates]]: Auto-inserted templates in blank new files
|
||||
+ [[file:feature/lookup/README.org][lookup]] =+docsets=: Universal jump-to & documentation lookup backend
|
||||
+ [[file:feature/snippets/README.org][snippets]]: A templating system for Emacs for lazy typers (aka programmers)
|
||||
+ [[file:feature/workspaces/README.org][workspaces]]: Isolated workspaces
|
||||
|
||||
* :completion
|
||||
Swappable completion modules for quickly narrowing down lists of candidates.
|
||||
|
||||
+ [[file:completion/company/README.org][company]] =+auto +childframe=: The ultimate code completion backend
|
||||
+ helm =+fuzzy +childframe=: *Another* search engine for love and life
|
||||
+ ido: The /other/ *other* search engine for love and life
|
||||
+ [[file:completion/ivy/README.org][ivy]] =+fuzzy +childframe=: /The/ search engine for love and life
|
||||
|
||||
* :ui
|
||||
Aesthetic modules that affect the Emacs interface or user experience.
|
||||
|
||||
+ [[file:ui/deft/README.org][deft]]:
|
||||
+ [[file:ui/doom/README.org][doom]]:
|
||||
+ [[file:ui/doom-dashboard/README.org][doom-dashboard]]:
|
||||
+ [[file:ui/doom-quit/README.org][doom-quit]]:
|
||||
+ [[file:ui/evil-goggles/README.org][evil-goggles]]:
|
||||
+ fci:
|
||||
+ [[file:ui/hl-todo/README.org][hl-todo]]:
|
||||
+ [[file:ui/modeline/README.org][modeline]]:
|
||||
+ [[file:ui/nav-flash/README.org][nav-flash]]:
|
||||
+ [[file:ui/neotree/README.org][neotree]]:
|
||||
+ treemacs:
|
||||
+ [[file:ui/popup/README.org][popup]] =+all +defaults=: Makes temporary/disposable windows less intrusive
|
||||
+ pretty-code:
|
||||
+ [[file:ui/tabbar/README.org][tabbar]]:
|
||||
+ [[file:ui/unicode/README.org][unicode]]:
|
||||
+ vc-gutter:
|
||||
+ vi-tilde-fringe:
|
||||
+ [[file:ui/window-select/README.org][window-select]]:
|
||||
|
||||
* :editor
|
||||
Modules that affect and augment your ability to write and edit text.
|
||||
|
||||
+ [[file:editor/fold/README.org][fold]]: universal code folding
|
||||
+ [[file:editor/format/README.org][format]] =+onsave=:
|
||||
+ [[file:editor/lispy/README.org][lispy]]:
|
||||
+ multiple-cursors:
|
||||
+ [[file:editor/parinfer/README.org][parinfer]]:
|
||||
+ rotate-text:
|
||||
|
||||
* :emacs
|
||||
Modules that reconfigure packages or features built into Emacs
|
||||
|
||||
+ dired =+ranger +icons=:
|
||||
+ electric:
|
||||
+ eshell:
|
||||
+ imenu:
|
||||
+ term:
|
||||
+ vc:
|
||||
|
||||
* :tools
|
||||
Small modules that give Emacs access to external tools & services.
|
||||
|
||||
+ ansible:
|
||||
+ docker:
|
||||
+ [[file:tools/editorconfig/README.org][editorconfig]]:
|
||||
+ [[file:tools/ein/README.org][ein]]:
|
||||
+ flyspell: Spell checking
|
||||
+ flycheck: Live error/warning highlights
|
||||
+ gist:
|
||||
+ [[file:tools/lsp/README.org][lsp]]:
|
||||
+ macos:
|
||||
+ make:
|
||||
+ magit:
|
||||
+ password-store:
|
||||
+ pdf:
|
||||
+ prodigy:
|
||||
+ rgb:
|
||||
+ terraform:
|
||||
+ tmux:
|
||||
+ upload:
|
||||
+ [[file:tools/wakatime/README.org][wakatime]]:
|
||||
+ vterm:
|
||||
|
||||
* :lang
|
||||
Modules that bring support for a language or group of languages to Emacs.
|
||||
|
||||
+ assembly:
|
||||
+ [[file:lang/cc/README.org][cc]] =+lsp=:
|
||||
+ clojure:
|
||||
+ common-lisp:
|
||||
+ [[file:lang/coq/README.org][coq]]:
|
||||
+ crystal:
|
||||
+ [[file:lang/csharp/README.org][csharp]]:
|
||||
+ data:
|
||||
+ erlang:
|
||||
+ elixir:
|
||||
+ elm:
|
||||
+ emacs-lisp:
|
||||
+ [[file:lang/ess/README.org][ess]]:
|
||||
+ [[file:lang/go/README.org][go]] =+lsp=:
|
||||
+ [[file:lang/haskell/README.org][haskell]] =+intero +dante=:
|
||||
+ hy:
|
||||
+ [[file:lang/idris/README.org][idris]]:
|
||||
+ java =+meghanada=:
|
||||
+ [[file:lang/javascript/README.org][javascript]] =+lsp=:
|
||||
+ julia:
|
||||
+ [[file:lang/latex/README.org][latex]]:
|
||||
+ ledger:
|
||||
+ lua:
|
||||
+ markdown:
|
||||
+ [[file:lang/nim/README.org][nim]]:
|
||||
+ nix:
|
||||
+ [[file:lang/ocaml/README.org][ocaml]] =+lsp=:
|
||||
+ [[file:lang/org/README.org][org]] =+attach +babel +capture +export +present +ipython=:
|
||||
+ [[file:lang/perl/README.org][perl]]:
|
||||
+ [[file:lang/php/README.org][php]] =+lsp=:
|
||||
+ plantuml:
|
||||
+ purescript:
|
||||
+ python =+lsp=:
|
||||
+ qt:
|
||||
+ racket:
|
||||
+ [[file:lang/rest/README.org][rest]]:
|
||||
+ ruby =+lsp=:
|
||||
+ [[file:lang/rust/README.org][rust]] =+lsp=:
|
||||
+ scala:
|
||||
+ [[file:lang/sh/README.org][sh]] =+fish +lsp=:
|
||||
+ [[file:lang/solidity/README.org][solidity]]:
|
||||
+ swift:
|
||||
+ web =+lsp=:
|
||||
+ vala:
|
||||
|
||||
* :app
|
||||
Large, opinionated modules that transform and take over Emacs, i.e.
|
||||
Doom-specific porcelains.
|
||||
|
||||
+ calendar:
|
||||
+ [[file:app/email/README.org][email]] =+gmail=:
|
||||
+ [[file:app/irc/README.org][irc]]:
|
||||
+ regex:
|
||||
+ rss =+org=:
|
||||
+ twitter:
|
||||
+ [[file:app/write/README.org][write]] =+wordnut +langtool=:
|
||||
|
||||
* :collab
|
||||
Modules that enable collaborative programming over the internet.
|
||||
|
||||
+ floobits:
|
||||
+ impatient-mode:
|
||||
|
||||
* :config
|
||||
Modules that configure Emacs one way or another, or focus on making it easier
|
||||
for you to customize it yourself.
|
||||
|
||||
+ literate:
|
||||
+ [[file:config/default/README.org][default]] =+bindings +smartparens=:
|
|
@ -28,8 +28,7 @@
|
|||
|
||||
(define-key cfw:calendar-mode-map "q" #'+calendar/quit)
|
||||
|
||||
(when (featurep 'solaire-mode)
|
||||
(add-hook 'cfw:calendar-mode-hook #'solaire-mode))
|
||||
(add-hook 'cfw:calendar-mode-hook #'doom|mark-buffer-as-real)
|
||||
(add-hook 'cfw:calendar-mode-hook 'hide-mode-line-mode)
|
||||
|
||||
(advice-add #'cfw:render-button :override #'+calendar*cfw:render-button))
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
company-echo-metadata-frontend))
|
||||
:config
|
||||
(add-hook 'company-mode-hook #'+company|init-backends)
|
||||
(when (featurep! :feature evil)
|
||||
(add-hook 'company-mode-hook #'evil-normalize-keymaps))
|
||||
(global-company-mode +1))
|
||||
|
||||
|
||||
|
@ -36,10 +38,7 @@
|
|||
(add-to-list 'company-frontends 'company-tng-frontend)
|
||||
(define-key! company-active-map
|
||||
"RET" nil
|
||||
[return] nil
|
||||
"TAB" #'company-select-next
|
||||
[tab] #'company-select-next
|
||||
"<backtab>" #'company-select-previous
|
||||
[backtab] #'company-select-previous))
|
||||
|
||||
|
||||
|
@ -60,44 +59,60 @@
|
|||
(setq company-box-show-single-candidate t
|
||||
company-box-backends-colors nil
|
||||
company-box-max-candidates 50
|
||||
company-box-icons-yasnippet (all-the-icons-material "short_text" :height 0.8 :face 'all-the-icons-green)
|
||||
company-box-icons-unknown (all-the-icons-material "find_in_page" :height 0.8 :face 'all-the-icons-purple)
|
||||
company-box-icons-elisp
|
||||
(list (all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red)
|
||||
(all-the-icons-material "check_circle" :height 0.8 :face 'all-the-icons-blue)
|
||||
(all-the-icons-material "stars" :height 0.8 :face 'all-the-icons-orange)
|
||||
(all-the-icons-material "format_paint" :height 0.8 :face 'all-the-icons-pink))
|
||||
company-box-icons-lsp
|
||||
`((1 . ,(all-the-icons-material "text_fields" :height 0.8 :face 'all-the-icons-green)) ; text
|
||||
(2 . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red)) ; method
|
||||
(3 . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red)) ; function
|
||||
(4 . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red)) ; constructor
|
||||
(5 . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red)) ; field
|
||||
(6 . ,(all-the-icons-material "adjust" :height 0.8 :face 'all-the-icons-blue)) ; variable
|
||||
(7 . ,(all-the-icons-material "class" :height 0.8 :face 'all-the-icons-red)) ; class
|
||||
(8 . ,(all-the-icons-material "settings_input_component" :height 0.8 :face 'all-the-icons-red)) ; interface
|
||||
(9 . ,(all-the-icons-material "view_module" :height 0.8 :face 'all-the-icons-red)) ; module
|
||||
(10 . ,(all-the-icons-material "settings" :height 0.8 :face 'all-the-icons-red)) ; property
|
||||
(11 . ,(all-the-icons-material "straighten" :height 0.8 :face 'all-the-icons-red)) ; unit
|
||||
(12 . ,(all-the-icons-material "filter_1" :height 0.8 :face 'all-the-icons-red)) ; value
|
||||
(13 . ,(all-the-icons-material "plus_one" :height 0.8 :face 'all-the-icons-red)) ; enum
|
||||
(14 . ,(all-the-icons-material "filter_center_focus" :height 0.8 :face 'all-the-icons-red)) ; keyword
|
||||
(15 . ,(all-the-icons-material "short_text" :height 0.8 :face 'all-the-icons-red)) ; snippet
|
||||
(16 . ,(all-the-icons-material "color_lens" :height 0.8 :face 'all-the-icons-red)) ; color
|
||||
(17 . ,(all-the-icons-material "insert_drive_file" :height 0.8 :face 'all-the-icons-red)) ; file
|
||||
(18 . ,(all-the-icons-material "collections_bookmark" :height 0.8 :face 'all-the-icons-red)) ; reference
|
||||
(19 . ,(all-the-icons-material "folder" :height 0.8 :face 'all-the-icons-red)) ; folder
|
||||
(20 . ,(all-the-icons-material "people" :height 0.8 :face 'all-the-icons-red)) ; enumMember
|
||||
(21 . ,(all-the-icons-material "pause_circle_filled" :height 0.8 :face 'all-the-icons-red)) ; constant
|
||||
(22 . ,(all-the-icons-material "streetview" :height 0.8 :face 'all-the-icons-red)) ; struct
|
||||
(23 . ,(all-the-icons-material "event" :height 0.8 :face 'all-the-icons-red)) ; event
|
||||
(24 . ,(all-the-icons-material "control_point" :height 0.8 :face 'all-the-icons-red)) ; operator
|
||||
(25 . ,(all-the-icons-material "class" :height 0.8 :face 'all-the-icons-red)))))
|
||||
company-box-icons-alist 'company-box-icons-all-the-icons
|
||||
company-box-icons-functions
|
||||
'(+company-box-icons--yasnippet company-box-icons--lsp +company-box-icons--elisp company-box-icons--acphp)
|
||||
company-box-icons-all-the-icons
|
||||
`((Unknown . ,(all-the-icons-material "find_in_page" :height 0.8 :face 'all-the-icons-purple))
|
||||
(Text . ,(all-the-icons-material "text_fields" :height 0.8 :face 'all-the-icons-green))
|
||||
(Method . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red))
|
||||
(Function . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red))
|
||||
(Constructor . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red))
|
||||
(Field . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red))
|
||||
(Variable . ,(all-the-icons-material "adjust" :height 0.8 :face 'all-the-icons-blue))
|
||||
(Class . ,(all-the-icons-material "class" :height 0.8 :face 'all-the-icons-red))
|
||||
(Interface . ,(all-the-icons-material "settings_input_component" :height 0.8 :face 'all-the-icons-red))
|
||||
(Module . ,(all-the-icons-material "view_module" :height 0.8 :face 'all-the-icons-red))
|
||||
(Property . ,(all-the-icons-material "settings" :height 0.8 :face 'all-the-icons-red))
|
||||
(Unit . ,(all-the-icons-material "straighten" :height 0.8 :face 'all-the-icons-red))
|
||||
(Value . ,(all-the-icons-material "filter_1" :height 0.8 :face 'all-the-icons-red))
|
||||
(Enum . ,(all-the-icons-material "plus_one" :height 0.8 :face 'all-the-icons-red))
|
||||
(Keyword . ,(all-the-icons-material "filter_center_focus" :height 0.8 :face 'all-the-icons-red))
|
||||
(Snippet . ,(all-the-icons-material "short_text" :height 0.8 :face 'all-the-icons-red))
|
||||
(Color . ,(all-the-icons-material "color_lens" :height 0.8 :face 'all-the-icons-red))
|
||||
(File . ,(all-the-icons-material "insert_drive_file" :height 0.8 :face 'all-the-icons-red))
|
||||
(Reference . ,(all-the-icons-material "collections_bookmark" :height 0.8 :face 'all-the-icons-red))
|
||||
(Folder . ,(all-the-icons-material "folder" :height 0.8 :face 'all-the-icons-red))
|
||||
(EnumMember . ,(all-the-icons-material "people" :height 0.8 :face 'all-the-icons-red))
|
||||
(Constant . ,(all-the-icons-material "pause_circle_filled" :height 0.8 :face 'all-the-icons-red))
|
||||
(Struct . ,(all-the-icons-material "streetview" :height 0.8 :face 'all-the-icons-red))
|
||||
(Event . ,(all-the-icons-material "event" :height 0.8 :face 'all-the-icons-red))
|
||||
(Operator . ,(all-the-icons-material "control_point" :height 0.8 :face 'all-the-icons-red))
|
||||
(TypeParameter . ,(all-the-icons-material "class" :height 0.8 :face 'all-the-icons-red))
|
||||
;; (Template . ,(company-box-icons-image "Template.png"))))
|
||||
(Yasnippet . ,(all-the-icons-material "short_text" :height 0.8 :face 'all-the-icons-green))
|
||||
(ElispFunction . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red))
|
||||
(ElispVariable . ,(all-the-icons-material "check_circle" :height 0.8 :face 'all-the-icons-blue))
|
||||
(ElispFeature . ,(all-the-icons-material "stars" :height 0.8 :face 'all-the-icons-orange))
|
||||
(ElispFace . ,(all-the-icons-material "format_paint" :height 0.8 :face 'all-the-icons-pink))))
|
||||
|
||||
(defun +company-box-icons--yasnippet (candidate)
|
||||
(when (get-text-property 0 'yas-annotation candidate)
|
||||
'Yasnippet))
|
||||
|
||||
(defun +company-box-icons--elisp (candidate)
|
||||
(when (derived-mode-p 'emacs-lisp-mode)
|
||||
(let ((sym (intern candidate)))
|
||||
(cond ((fboundp sym) 'ElispFunction)
|
||||
((boundp sym) 'ElispVariable)
|
||||
((featurep sym) 'ElispFeature)
|
||||
((facep sym) 'ElispFace))))))
|
||||
|
||||
|
||||
(def-package! company-dict
|
||||
:defer t
|
||||
:config
|
||||
(setq company-dict-dir (expand-file-name "dicts" doom-private-dir))
|
||||
(defun +company|enable-project-dicts (mode &rest _)
|
||||
"Enable per-project dictionaries."
|
||||
(if (symbol-value mode)
|
||||
|
|
|
@ -162,9 +162,10 @@ order.
|
|||
(string-join (delq nil (cdr command)) " ")
|
||||
(abbreviate-file-name directory))
|
||||
helm-source-do-ag)
|
||||
(cl-letf ((+helm-global-prompt prompt)
|
||||
((symbol-function 'helm-do-ag--helm)
|
||||
(helm-attrset '+helm-command command helm-source-do-ag)
|
||||
(cl-letf (((symbol-function 'helm-do-ag--helm)
|
||||
(lambda () (helm :sources '(helm-source-do-ag)
|
||||
:prompt prompt
|
||||
:buffer "*helm-ag*"
|
||||
:keymap helm-do-ag-map
|
||||
:input query
|
||||
|
@ -177,7 +178,7 @@ order.
|
|||
return (intern (format format tool))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +helm/project-search (&optional all-files-p)
|
||||
(defun +helm/project-search (&optional arg)
|
||||
"Performs a project search from the project root.
|
||||
|
||||
Uses the first available search backend from `+helm-project-search-engines'. If
|
||||
|
@ -186,10 +187,10 @@ ones, in the search."
|
|||
(interactive "P")
|
||||
(funcall (or (+helm--get-command "+helm/%s")
|
||||
#'+helm/grep)
|
||||
(or all-files-p current-prefix-arg)))
|
||||
arg))
|
||||
|
||||
;;;###autoload
|
||||
(defun +helm/project-search-from-cwd (&optional all-files-p)
|
||||
(defun +helm/project-search-from-cwd (&optional arg)
|
||||
"Performs a project search recursively from the current directory.
|
||||
|
||||
Uses the first available search backend from `+helm-project-search-engines'. If
|
||||
|
@ -198,7 +199,7 @@ ones."
|
|||
(interactive "P")
|
||||
(funcall (or (+helm--get-command "+helm/%s-from-cwd")
|
||||
#'+helm/grep-from-cwd)
|
||||
(or all-files-p current-prefix-arg)))
|
||||
arg))
|
||||
|
||||
|
||||
;; Relative to project root
|
||||
|
@ -213,21 +214,31 @@ ones."
|
|||
|
||||
(dolist (engine `(,@(cl-remove-duplicates +helm-project-search-engines :from-end t) grep))
|
||||
(defalias (intern (format "+helm/%s" engine))
|
||||
(lambda (all-files-p &optional query directory)
|
||||
(lambda (arg &optional query directory)
|
||||
(interactive "P")
|
||||
(+helm-file-search engine :query query :in directory :all-files all-files-p))
|
||||
(+helm-file-search engine
|
||||
:query query
|
||||
:in directory
|
||||
:all-files (and (not (null arg))
|
||||
(listp arg))))
|
||||
(format "Perform a project file search using %s.
|
||||
|
||||
QUERY is a regexp. If omitted, the current selection is used. If no selection is
|
||||
active, the last known search is used.
|
||||
|
||||
ARG is the universal argument. If a number is passed through it, e.g. C-u 3, then
|
||||
|
||||
If ALL-FILES-P, search compressed and hidden files as well."
|
||||
engine))
|
||||
|
||||
(defalias (intern (format "+helm/%s-from-cwd" engine))
|
||||
(lambda (all-files-p &optional query)
|
||||
(lambda (arg &optional query)
|
||||
(interactive "P")
|
||||
(+helm-file-search engine :query query :in default-directory :all-files all-files-p))
|
||||
(+helm-file-search engine
|
||||
:query query
|
||||
:in default-directory
|
||||
:all-files (and (not (null arg))
|
||||
(listp arg))))
|
||||
(format "Perform a project file search from the current directory using %s.
|
||||
|
||||
QUERY is a regexp. If omitted, the current selection is used. If no selection is
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
;;; completion/ivy/autoload/ivy.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defun +ivy--is-workspace-or-other-buffer-p (buffer)
|
||||
(defun +ivy--is-workspace-buffer-p (buffer)
|
||||
(let ((buffer (car buffer)))
|
||||
(when (stringp buffer)
|
||||
(setq buffer (get-buffer buffer)))
|
||||
(+workspace-contains-buffer-p buffer)))
|
||||
|
||||
(defun +ivy--is-workspace-other-buffer-p (buffer)
|
||||
(let ((buffer (car buffer)))
|
||||
(when (stringp buffer)
|
||||
(setq buffer (get-buffer buffer)))
|
||||
|
@ -28,21 +34,73 @@ temporary/special buffers in `font-lock-comment-face'."
|
|||
;;
|
||||
;; Library
|
||||
|
||||
(defun +ivy--switch-buffer-preview ()
|
||||
(let (ivy-use-virtual-buffers ivy--virtual-buffers)
|
||||
(counsel--switch-buffer-update-fn)))
|
||||
|
||||
(defalias '+ivy--switch-buffer-preview-all #'counsel--switch-buffer-update-fn)
|
||||
(defalias '+ivy--switch-buffer-unwind #'counsel--switch-buffer-unwind)
|
||||
|
||||
(defun +ivy--switch-buffer (workspace other)
|
||||
(let ((current (not other))
|
||||
prompt action filter update unwind)
|
||||
(cond ((and workspace current)
|
||||
(setq prompt "Switch to workspace buffer: "
|
||||
action #'ivy--switch-buffer-action
|
||||
filter #'+ivy--is-workspace-other-buffer-p))
|
||||
(workspace
|
||||
(setq prompt "Switch to workspace buffer in other window: "
|
||||
action #'ivy--switch-buffer-other-window-action
|
||||
filter #'+ivy--is-workspace-buffer-p))
|
||||
(current
|
||||
(setq prompt "Switch to buffer: "
|
||||
action #'ivy--switch-buffer-action))
|
||||
(t
|
||||
(setq prompt "Switch to buffer in other window: "
|
||||
action #'ivy--switch-buffer-other-window-action)))
|
||||
(when +ivy-buffer-preview
|
||||
(cond ((not (and ivy-use-virtual-buffers
|
||||
(eq +ivy-buffer-preview 'everything)))
|
||||
(setq update #'+ivy--switch-buffer-preview
|
||||
unwind #'+ivy--switch-buffer-unwind))
|
||||
(t
|
||||
(setq update #'+ivy--switch-buffer-preview-all
|
||||
unwind #'+ivy--switch-buffer-unwind))))
|
||||
(ivy-read prompt 'internal-complete-buffer
|
||||
:action action
|
||||
:predicate filter
|
||||
:update-fn update
|
||||
:unwind unwind
|
||||
:preselect (buffer-name (other-buffer (current-buffer)))
|
||||
:matcher #'ivy--switch-buffer-matcher
|
||||
:keymap ivy-switch-buffer-map
|
||||
:caller #'+ivy--switch-buffer)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy/switch-workspace-buffer (&optional arg)
|
||||
"Switch to another buffer within the current workspace.
|
||||
|
||||
If ARG (universal argument), open selection in other-window."
|
||||
(interactive "P")
|
||||
(ivy-read "Switch to workspace buffer: "
|
||||
'internal-complete-buffer
|
||||
:predicate #'+ivy--is-workspace-or-other-buffer-p
|
||||
:action (if arg
|
||||
#'ivy--switch-buffer-other-window-action
|
||||
#'ivy--switch-buffer-action)
|
||||
:matcher #'ivy--switch-buffer-matcher
|
||||
:keymap ivy-switch-buffer-map
|
||||
:caller #'+ivy/switch-workspace-buffer))
|
||||
(+ivy--switch-buffer t arg))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy/switch-workspace-buffer-other-window ()
|
||||
"Switch another window to a buffer within the current workspace."
|
||||
(interactive)
|
||||
(+ivy--switch-buffer t t))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy/switch-buffer ()
|
||||
"Switch to another buffer."
|
||||
(interactive)
|
||||
(+ivy--switch-buffer nil nil))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy/switch-buffer-other-window ()
|
||||
"Switch to another buffer in another window."
|
||||
(interactive)
|
||||
(+ivy--switch-buffer nil t))
|
||||
|
||||
(defun +ivy--tasks-candidates (tasks)
|
||||
"Generate a list of task tags (specified by `+ivy-task-tags') for
|
||||
|
@ -230,7 +288,7 @@ order.
|
|||
'grep)
|
||||
(error "No search engine specified (is ag, rg, pt or git installed?)")))
|
||||
(query
|
||||
(or query
|
||||
(or (if query (rxt-quote-pcre query))
|
||||
(when (use-region-p)
|
||||
(let ((beg (or (bound-and-true-p evil-visual-beginning) (region-beginning)))
|
||||
(end (or (bound-and-true-p evil-visual-end) (region-end))))
|
||||
|
|
|
@ -3,6 +3,13 @@
|
|||
(defvar +ivy-buffer-icons nil
|
||||
"If non-nil, show buffer mode icons in `ivy-switch-buffer' and the like.")
|
||||
|
||||
(defvar +ivy-buffer-preview nil
|
||||
"If non-nil, preview buffers while switching, à la `counsel-switch-buffer'.
|
||||
|
||||
When nil, don't preview anything.
|
||||
When non-nil, preview non-virtual buffers.
|
||||
When 'everything, also preview virtual buffers")
|
||||
|
||||
(defvar +ivy-task-tags
|
||||
'(("TODO" . warning)
|
||||
("FIXME" . error))
|
||||
|
@ -58,9 +65,11 @@ immediately runs it on the current candidate (ending the ivy session)."
|
|||
(after! yasnippet
|
||||
(add-to-list 'yas-prompt-functions #'+ivy-yas-prompt nil #'eq))
|
||||
|
||||
(map! [remap switch-to-buffer] #'ivy-switch-buffer
|
||||
[remap persp-switch-to-buffer] #'+ivy/switch-workspace-buffer
|
||||
[remap imenu-anywhere] #'ivy-imenu-anywhere)
|
||||
(map! :map ivy-mode-map
|
||||
[remap switch-to-buffer] #'+ivy/switch-buffer
|
||||
[remap switch-to-buffer-other-window] #'+ivy/switch-buffer-other-window
|
||||
[remap persp-switch-to-buffer] #'+ivy/switch-workspace-buffer
|
||||
[remap imenu-anywhere] #'ivy-imenu-anywhere)
|
||||
|
||||
(ivy-mode +1)
|
||||
|
||||
|
@ -68,15 +77,15 @@ immediately runs it on the current candidate (ending the ivy session)."
|
|||
:commands (ivy-dispatching-done-hydra ivy--matcher-desc)
|
||||
:init
|
||||
(define-key! ivy-minibuffer-map
|
||||
"\C-o" #'+ivy-coo-hydra/body
|
||||
(kbd "M-o") #'ivy-dispatching-done-hydra)))
|
||||
"C-o" #'+ivy-coo-hydra/body
|
||||
"M-o" #'ivy-dispatching-done-hydra)))
|
||||
|
||||
|
||||
(def-package! ivy-rich
|
||||
:hook (ivy-mode . ivy-rich-mode)
|
||||
:config
|
||||
;; Show more buffer information in other switch-buffer commands too
|
||||
(dolist (cmd '(+ivy/switch-workspace-buffer
|
||||
(dolist (cmd '(+ivy--switch-buffer
|
||||
counsel-projectile-switch-to-buffer))
|
||||
(ivy-set-display-transformer cmd 'ivy-rich--ivy-switch-buffer-transformer))
|
||||
;; Use `+ivy-rich-buffer-name' to display buffer names
|
||||
|
@ -95,6 +104,8 @@ immediately runs it on the current candidate (ending the ivy session)."
|
|||
[remap describe-face] #'counsel-faces
|
||||
[remap describe-function] #'counsel-describe-function
|
||||
[remap describe-variable] #'counsel-describe-variable
|
||||
[remap describe-bindings] #'counsel-descbinds
|
||||
[remap set-variable] #'counsel-set-variable
|
||||
[remap execute-extended-command] #'counsel-M-x
|
||||
[remap find-file] #'counsel-find-file
|
||||
[remap find-library] #'counsel-find-library
|
||||
|
@ -203,6 +214,10 @@ immediately runs it on the current candidate (ending the ivy session)."
|
|||
;; default to posframe display function
|
||||
(setf (alist-get t ivy-display-functions-alist) #'+ivy-display-at-frame-center-near-bottom)
|
||||
|
||||
;; Fix #1017: stop session persistence from restoring a broken posframe
|
||||
(defun +workspace|delete-all-posframes (&rest _) (posframe-delete-all))
|
||||
(add-hook 'persp-after-load-state-functions #'+workspace|delete-all-posframes)
|
||||
|
||||
;; posframe doesn't work well with async sources
|
||||
(dolist (fn '(swiper counsel-ag counsel-grep counsel-git-grep))
|
||||
(setf (alist-get fn ivy-display-functions-alist) #'ivy-display-function-fallback)))
|
||||
|
|
|
@ -1,304 +1,352 @@
|
|||
;;; config/default/+emacs-bindings.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; Sensible deafult key bindings for non-evil users
|
||||
(setq doom-leader-alt-key "C-c"
|
||||
doom-localleader-alt-key "C-c l")
|
||||
|
||||
;; persp-mode and projectile in different prefixes
|
||||
(setq persp-keymap-prefix (kbd "C-c e"))
|
||||
(setq persp-keymap-prefix (kbd "C-c w"))
|
||||
(after! projectile
|
||||
(define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map))
|
||||
|
||||
(which-key-add-key-based-replacements "C-c !" "checking")
|
||||
(which-key-add-key-based-replacements "C-c e" "perspective")
|
||||
(which-key-add-key-based-replacements "C-c p" "projectile")
|
||||
(after! which-key
|
||||
(which-key-add-key-based-replacements "C-c !" "checking")
|
||||
(which-key-add-key-based-replacements "C-c l" "<localleader>"))
|
||||
|
||||
;; Prefix key to invoke doom related commands
|
||||
(setq doom-leader-alt-key "C-c")
|
||||
(setq doom-localleader-alt-key "C-c l")
|
||||
|
||||
(map!
|
||||
;; Text scaling
|
||||
"<C-mouse-4>" #'text-scale-increase
|
||||
"<C-mouse-5>" #'text-scale-decrease
|
||||
"<C-down-mouse-2>" (λ! (text-scale-set 0))
|
||||
"M-+" (λ! (text-scale-set 0))
|
||||
"M-=" #'text-scale-increase
|
||||
"M--" #'text-scale-decrease
|
||||
;; Editor related bindings
|
||||
[remap newline] #'newline-and-indent
|
||||
"C-j" #'+default/newline
|
||||
(:when (featurep! :completion ivy)
|
||||
"C-S-s" #'swiper
|
||||
"C-S-r" #'ivy-resume)
|
||||
(:when (featurep! :completion helm)
|
||||
"C-S-s" #'swiper-helm
|
||||
"C-S-r" #'helm-resume)
|
||||
;; Buffer related bindings
|
||||
"C-x b" #'persp-switch-to-buffer
|
||||
"C-x C-b" #'ibuffer-list-buffers
|
||||
"C-x B" #'switch-to-buffer
|
||||
"C-x k" #'doom/kill-this-buffer-in-all-windows
|
||||
;; Popup bindigns
|
||||
"C-x p" #'+popup/other
|
||||
"C-`" #'+popup/toggle
|
||||
"C-~" #'+popup/raise
|
||||
;; Doom emacs bindings
|
||||
(:leader
|
||||
(:prefix ("d" . "doom")
|
||||
:desc "Dashboard" "d" #'+doom-dashboard/open
|
||||
:desc "Recent files" "f" #'recentf-open-files
|
||||
(:when (featurep! :ui neotree)
|
||||
:desc "Open neotree" "n" #'+neotree/open
|
||||
:desc "File in neotree" "N" #'neotree/find-this-file)
|
||||
(:when (featurep! :ui treemacs)
|
||||
:desc "Toggle treemacs" "n" #'+treemacs/toggle
|
||||
:desc "File in treemacs" "N" #'+treemacs/find-file)
|
||||
:desc "Popup other" "o" #'+popup/other
|
||||
:desc "Popup toggle" "t" #'+popup/toggle
|
||||
:desc "Popup close" "c" #'+popup/close
|
||||
:desc "Popup close all" "C" #'+popup/close-all
|
||||
:desc "Popup raise" "r" #'+popup/raise
|
||||
:desc "Popup restore" "R" #'+popup/restore
|
||||
:desc "Scratch buffer" "s" #'doom/open-scratch-buffer
|
||||
:desc "Switch to scratch buffer" "S" #'doom/switch-to-scratch-buffer
|
||||
:desc "Sudo this file" "u" #'doom/sudo-this-file
|
||||
:desc "Sudo find file" "U" #'doom/sudo-find-file
|
||||
:desc "Eshell popup" "e" #'+eshell/open-popup
|
||||
:desc "Eshell open" "E" #'+eshell/open
|
||||
:desc "Reload Private Config" "R" #'doom/reload)
|
||||
;; Org related bindings
|
||||
"o" nil ; we need to unbind it first as Org claims this
|
||||
(:prefix ("o". "org")
|
||||
:desc "Do what I mean" "o" #'+org/dwim-at-point
|
||||
:desc "Sync org caldav" "s" #'org-caldav-sync
|
||||
(:prefix ("a" . "org agenda")
|
||||
:desc "Agenda" "a" #'org-agenda
|
||||
:desc "Todo list" "t" #'org-todo-list
|
||||
:desc "Tags view" "m" #'org-tags-view
|
||||
:desc "View search" "v" #'org-search-view)
|
||||
:desc "Capture" "c" #'org-capture
|
||||
:desc "Goto capture" "C" (λ! (require 'org-capture) (call-interactively #'org-capture-goto-target))
|
||||
:desc "Switch org buffers" "b" #'org-switchb
|
||||
(:prefix ("e" . "org export")
|
||||
:desc "Export beamer to latex" "l b" #'org-beamer-export-to-latex
|
||||
:desc "Export beamer as latex" "l B" #'org-beamer-export-as-latex
|
||||
:desc "Export beamer as pdf" "l P" #'org-beamer-export-to-pdf)
|
||||
:desc "Link store" "l" #'org-store-link)
|
||||
;; Quit/Restart
|
||||
(:prefix ("q" . "quit/restart")
|
||||
:desc "Quit Emacs" "q" #'kill-emacs
|
||||
:desc "Save and quit Emacs" "Q" #'save-buffers-kill-terminal
|
||||
(:when (featurep! :feature workspaces)
|
||||
:desc "Quit Emacs & forget session" "X" #'+workspace/kill-session-and-quit
|
||||
:desc "Restart & restore Emacs" "r" #'+workspace/restart-emacs-then-restore)
|
||||
:desc "Restart Emacs" "R" #'restart-emacs)
|
||||
;; Snippets
|
||||
"&" nil ; yasnippet creates this prefix, we use a different one
|
||||
(:prefix ("s" . "snippets")
|
||||
:desc "New snippet" "n" #'yas-new-snippet
|
||||
:desc "Insert snippet" "i" #'yas-insert-snippet
|
||||
:desc "Find global snippet" "/" #'yas-visit-snippet-file
|
||||
:desc "Reload snippets" "r" #'yas-reload-all
|
||||
:desc "Create Temp Template" "c" #'aya-create
|
||||
:desc "Use Temp Template" "e" #'aya-expand)
|
||||
;; Version control bindings
|
||||
(:prefix ("v" . "versioning")
|
||||
:desc "Browse issues tracker" "i" #'forge-browse-issues
|
||||
:desc "Browse remote" "o" #'forge-browse-remote
|
||||
:desc "Diff current file" "d" #'magit-diff-buffer-file
|
||||
:desc "Git revert hunk" "r" #'git-gutter:revert-hunk
|
||||
:desc "Git stage file" "S" #'magit-stage-file
|
||||
:desc "Git stage hunk" "s" #'git-gutter:stage-hunk
|
||||
:desc "Git time machine" "t" #'git-timemachine-toggle
|
||||
:desc "Git unstage file" "U" #'magit-unstage-file
|
||||
:desc "Initialize repo" "I" #'magit-init
|
||||
:desc "List repositories" "L" #'magit-list-repositories
|
||||
:desc "Magit blame" "b" #'magit-blame-addition
|
||||
:desc "Magit buffer log" "l" #'magit-log-buffer-file
|
||||
:desc "Magit commit" "c" #'magit-commit-create
|
||||
:desc "Magit status" "g" #'magit-status
|
||||
:desc "Next hunk" "]" #'git-gutter:next-hunk
|
||||
:desc "Previous hunk" "[" #'git-gutter:previous-hunk)
|
||||
;; Worspace and window management bindings
|
||||
(:prefix ("w". "workspaces")
|
||||
:desc "Autosave session" "a" #'+workspace/save-session
|
||||
:desc "Display workspaces" "d" #'+workspace/display
|
||||
:desc "Rename workspace" "r" #'+workspace/rename
|
||||
:desc "Create workspace" "c" #'+workspace/new
|
||||
:desc "Delete workspace" "k" #'+workspace/delete
|
||||
:desc "Save session" "s" (λ! (let ((current-prefix-arg '(4))) (call-interactively #'+workspace/save-session)))
|
||||
:desc "Save workspace" "S" #'+workspace/save
|
||||
:desc "Load session" "l" #'+workspace/load-session
|
||||
:desc "Load last autosaved session" "L" #'+workspace/load-last-session
|
||||
:desc "Kill other buffers" "o" #'doom/kill-other-buffers
|
||||
:desc "Undo window config" "u" #'winner-undo
|
||||
:desc "Redo window config" "U" #'winner-redo
|
||||
:desc "Switch to left workspace" "p" #'+workspace/switch-left
|
||||
:desc "Switch to right workspace" "n" #'+workspace/switch-right
|
||||
:desc "Switch to" "w" #'+workspace/switch-to
|
||||
:desc "Switch to workspace 1" "1" (λ! (+workspace/switch-to 0))
|
||||
:desc "Switch to workspace 2" "2" (λ! (+workspace/switch-to 1))
|
||||
:desc "Switch to workspace 3" "3" (λ! (+workspace/switch-to 2))
|
||||
:desc "Switch to workspace 4" "4" (λ! (+workspace/switch-to 3))
|
||||
:desc "Switch to workspace 5" "5" (λ! (+workspace/switch-to 4))
|
||||
:desc "Switch to workspace 6" "6" (λ! (+workspace/switch-to 5))
|
||||
:desc "Switch to workspace 7" "7" (λ! (+workspace/switch-to 6))
|
||||
:desc "Switch to workspace 8" "8" (λ! (+workspace/switch-to 7))
|
||||
:desc "Switch to workspace 9" "9" (λ! (+workspace/switch-to 8))
|
||||
:desc "Switch to last workspace" "0" #'+workspace/switch-to-last)
|
||||
;; Multiple Cursors
|
||||
(:when (featurep! :editor multiple-cursors)
|
||||
(:prefix ("m" . "multiple cursors")
|
||||
:desc "Edit lines" "l" #'mc/edit-lines
|
||||
:desc "Mark next" "n" #'mc/mark-next-like-this
|
||||
:desc "Unmark next" "N" #'mc/unmark-next-like-this
|
||||
:desc "Mark previous" "p" #'mc/mark-previous-like-this
|
||||
:desc "Unmark previous" "P" #'mc/unmark-previous-like-this
|
||||
:desc "Mark all" "t" #'mc/mark-all-like-this
|
||||
:desc "Mark all DWIM" "m" #'mc/mark-all-like-this-dwim
|
||||
:desc "Edit line endings" "e" #'mc/edit-ends-of-lines
|
||||
:desc "Edit line starts" "a" #'mc/edit-beginnings-of-lines
|
||||
:desc "Mark tag" "s" #'mc/mark-sgml-tag-pair
|
||||
:desc "Mark in defun" "d" #'mc/mark-all-like-this-in-defun
|
||||
:desc "Add cursor w/mouse" "<mouse-1>" #'mc/add-cursor-on-click))
|
||||
;;
|
||||
;;; Global keybinds
|
||||
|
||||
;; APPs
|
||||
(map! "C-'" #'imenu
|
||||
;; Text scaling
|
||||
"<C-mouse-4>" #'text-scale-increase
|
||||
"<C-mouse-5>" #'text-scale-decrease
|
||||
"<C-down-mouse-2>" (λ! (text-scale-set 0))
|
||||
"M-+" (λ! (text-scale-set 0))
|
||||
"M-=" #'text-scale-increase
|
||||
"M--" #'text-scale-decrease
|
||||
;; Editor related bindings
|
||||
[remap newline] #'newline-and-indent
|
||||
"C-j" #'+default/newline
|
||||
(:when (featurep! :completion ivy)
|
||||
"C-S-s" #'swiper
|
||||
"C-S-r" #'ivy-resume)
|
||||
(:when (featurep! :completion helm)
|
||||
"C-S-s" #'swiper-helm
|
||||
"C-S-r" #'helm-resume)
|
||||
;; Buffer related bindings
|
||||
"C-x b" #'persp-switch-to-buffer
|
||||
(:when (featurep! :completion ivy)
|
||||
"C-x 4 b" #'+ivy/switch-workspace-buffer-other-window)
|
||||
"C-x C-b" #'ibuffer-list-buffers
|
||||
"C-x B" #'switch-to-buffer
|
||||
"C-x 4 B" #'switch-to-buffer-other-window
|
||||
"C-x k" #'doom/kill-this-buffer-in-all-windows
|
||||
;; Popup bindigns
|
||||
"C-x p" #'+popup/other
|
||||
"C-`" #'+popup/toggle
|
||||
"C-~" #'+popup/raise)
|
||||
|
||||
;; Email
|
||||
(:when (featurep! :app email)
|
||||
(:prefix ("M" . "email")
|
||||
:desc "Open email app" "m" #'=email
|
||||
:desc "Compose email" "c" #'+email/compose))
|
||||
;; IRC
|
||||
(:when (featurep! :app irc)
|
||||
(:prefix ("I" . "irc")
|
||||
:desc "Open irc app" "i" #'=irc
|
||||
:desc "Next unread buffer" "a" #'tracking-next-buffer
|
||||
:desc "Quit irc" "q" #'+irc/quit
|
||||
:desc "Reconnect all" "r" #'circe-reconnect-all
|
||||
:desc "Send message" "s" #'+irc/send-message
|
||||
(:when (featurep! :completion ivy)
|
||||
:desc "Jump to channel" "j" #'irc/ivy-jump-to-channel)))
|
||||
;; Twitter
|
||||
(:when (featurep! :app twitter)
|
||||
(:prefix ("T" . "twitter")
|
||||
:desc "Open twitter app" "t" #'=twitter
|
||||
:desc "Quit twitter" "q" #'+twitter/quit
|
||||
:desc "Rerender twits" "r" #'+twitter/rerender-all
|
||||
:desc "Ace link" "l" #'+twitter/ace-link)))
|
||||
|
||||
;; Plugins
|
||||
;;
|
||||
;;; Leader keys
|
||||
|
||||
;; misc plugins
|
||||
(:when (featurep! :ui neotree)
|
||||
"<f9>" #'+neotree/open)
|
||||
(:when (featurep! :ui treemacs)
|
||||
"<f9>" #'+treemacs/toggle)
|
||||
"C-=" #'er/expand-region
|
||||
"C--" #'er/contract-region
|
||||
;; smartparens
|
||||
(:after smartparens
|
||||
(:map smartparens-mode-map
|
||||
"C-M-a" #'sp-beginning-of-sexp
|
||||
"C-M-e" #'sp-end-of-sexp
|
||||
"C-M-f" #'sp-forward-sexp
|
||||
"C-M-b" #'sp-backward-sexp
|
||||
"C-M-d" #'sp-splice-sexp
|
||||
"C-M-k" #'sp-kill-sexp
|
||||
"C-M-t" #'sp-transpose-sexp
|
||||
"C-<right>" #'sp-forward-slurp-sexp
|
||||
"M-<right>" #'sp-forward-barf-sexp
|
||||
"C-<left>" #'sp-backward-slurp-sexp
|
||||
"M-<left>" #'sp-backward-barf-sexp))
|
||||
;; company mode
|
||||
"C-;" #'+company/complete
|
||||
;; 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))
|
||||
"C-h b" #'counsel-descbinds
|
||||
"C-M-y" #'counsel-yank-pop
|
||||
"C-h F" #'counsel-faces
|
||||
"C-h p" #'counsel-package
|
||||
"C-h a" #'counsel-apropos
|
||||
"C-h V" #'counsel-set-variable
|
||||
"C-'" #'counsel-imenu))
|
||||
;; repl toggle
|
||||
"C-c C-z" #'+eval/open-repl
|
||||
;; company mode
|
||||
(:after company
|
||||
(:map company-active-map
|
||||
"C-o" #'company-search-kill-others
|
||||
"C-n" #'company-select-next
|
||||
"C-p" #'company-select-previous
|
||||
"C-h" #'company-quickhelp-manual-begin
|
||||
"C-S-h" #'company-show-doc-buffer
|
||||
"C-s" #'company-search-candidates
|
||||
"M-s" #'company-filter-candidates
|
||||
"<C-tab>" #'company-complete-common-or-cycle
|
||||
[tab] #'company-complete-common-or-cycle
|
||||
[backtab] #'company-select-previous
|
||||
"C-RET" #'counsel-company)
|
||||
(:map company-search-map
|
||||
"C-n" #'company-search-repeat-forward
|
||||
"C-p" #'company-search-repeat-backward
|
||||
"C-s" (λ! (company-search-abort) (company-filter-candidates))))
|
||||
;; neotree bindings
|
||||
(:after neotree
|
||||
:map neotree-mode-map
|
||||
"q" #'neotree-hide
|
||||
[return] #'neotree-enter
|
||||
"RET" #'neotree-enter
|
||||
"SPC" #'neotree-quick-look
|
||||
"v" #'neotree-enter-vertical-split
|
||||
"s" #'neotree-enter-horizontal-split
|
||||
"c" #'neotree-create-node
|
||||
"D" #'neotree-delete-node
|
||||
"g" #'neotree-refresh
|
||||
"r" #'neotree-rename-node
|
||||
"R" #'neotree-refresh
|
||||
"h" #'+neotree/collapse-or-up
|
||||
"l" #'+neotree/expand-or-open
|
||||
"n" #'neotree-next-line
|
||||
"p" #'neotree-previous-line
|
||||
"N" #'neotree-select-next-sibling-node
|
||||
"P" #'neotree-select-previous-sibling-node)
|
||||
;; help and info
|
||||
(:after help-mode
|
||||
(:map help-mode-map
|
||||
"o" #'ace-link-help
|
||||
">" #'help-go-forward
|
||||
"<" #'help-go-back))
|
||||
(:after helpful-mode
|
||||
(:map helpful-mode-map
|
||||
"o" #'ace-link-help))
|
||||
(:after info
|
||||
(:map Info-mode-map
|
||||
"o" #'ace-link-info))
|
||||
;; yasnippet
|
||||
(:after yasnippet
|
||||
;; keymap while editing an inserted snippet
|
||||
(:map yas-keymap
|
||||
"C-e" #'+snippets/goto-end-of-field
|
||||
"C-a" #'+snippets/goto-start-of-field
|
||||
"<S-tab>" #'yas-prev-field
|
||||
"<M-backspace>" #'+snippets/delete-to-start-of-field
|
||||
[backspace] #'+snippets/delete-backward-char
|
||||
[delete] #'+snippets/delete-forward-char-or-field))
|
||||
;; flycheck
|
||||
(:after flycheck
|
||||
(:map flycheck-error-list-mode-map
|
||||
"C-n" #'flycheck-error-list-next-error
|
||||
"C-p" #'flycheck-error-list-previous-error
|
||||
"RET" #'flycheck-error-list-goto-error))
|
||||
;; ivy
|
||||
(:after ivy
|
||||
(:map ivy-minibuffer-map
|
||||
"TAB" #'ivy-alt-done
|
||||
"C-g" #'keyboard-escape-quit))
|
||||
;; ein notebokks
|
||||
(:after ein:notebook-multilang
|
||||
(:map ein:notebook-multilang-mode-map
|
||||
"C-c h" #'+ein/hydra/body)))
|
||||
(map! :leader
|
||||
:desc "Find file in project" "C-f" #'projectile-find-file
|
||||
:desc "Evaluate line/region" "e" #'+eval/line-or-region
|
||||
:desc "Pop up scratch buffer" "x" #'doom/open-to-scratch-buffer
|
||||
:desc "Switch to scratch buffer" "X" #'doom/switch-to-scratch-buffer
|
||||
|
||||
(:when (featurep! :emacs term)
|
||||
:desc "Terminal" "`" #'+term/open
|
||||
:desc "Terminal in popup" "~" #'+term/open-popup-in-project)
|
||||
(:when (featurep! :tools vterm)
|
||||
:desc "Terminal" "`" #'+vterm/open
|
||||
:desc "Terminal in popup" "~" #'+vterm/open-popup-in-project)
|
||||
(:when (featurep! :emacs eshell)
|
||||
:desc "Eshell" "`" #'+eshell/open
|
||||
:desc "Eshell in popup" "~" #'+eshell/open-popup)
|
||||
|
||||
;; Add labels to prefixes defined elsewhere
|
||||
:desc "project" "p" nil
|
||||
|
||||
(:prefix ("f" . "file")
|
||||
:desc "Find other file" "a" #'projectile-find-other-file
|
||||
:desc "Browse private config" "c" #'doom/open-private-config
|
||||
:desc "Find file in private config" "C" #'doom/find-file-in-private-config
|
||||
:desc "Open project editorconfig" "." #'editorconfig-find-current-editorconfig
|
||||
:desc "Find directory" "d" #'dired
|
||||
:desc "Find file in emacs.d" "e" #'+default/find-in-emacsd
|
||||
:desc "Browse emacs.d" "E" #'+default/browse-emacsd
|
||||
:desc "Find file from here" "f" (if (fboundp 'counsel-file-jump) #'counsel-file-jump #'find-file)
|
||||
:desc "Find file in other project" "F" #'doom/browse-in-other-project
|
||||
:desc "Find file in project" "p" #'projectile-find-file
|
||||
:desc "Find file in other project" "P" #'doom/find-file-in-other-project
|
||||
:desc "Recent files" "r" #'recentf-open-files
|
||||
:desc "Recent project files" "R" #'projectile-recentf
|
||||
:desc "Sudo this file" "s" #'doom/sudo-this-file
|
||||
:desc "Sudo find file" "S" #'doom/sudo-find-file
|
||||
:desc "Delete this file" "X" #'doom/delete-this-file
|
||||
:desc "Yank filename" "y" #'+default/yank-buffer-filename)
|
||||
|
||||
"o" nil ; we need to unbind it first as Org claims this
|
||||
(:prefix ("o". "org")
|
||||
(:prefix ("a" . "org agenda")
|
||||
:desc "Agenda" "a" #'org-agenda
|
||||
:desc "Todo list" "t" #'org-todo-list
|
||||
:desc "Tags view" "m" #'org-tags-view
|
||||
:desc "View search" "v" #'org-search-view)
|
||||
:desc "Switch org buffers" "b" #'org-switchb
|
||||
:desc "Capture" "c" #'org-capture
|
||||
:desc "Goto capture" "C" (λ! (require 'org-capture) (call-interactively #'org-capture-goto-target))
|
||||
:desc "Link store" "l" #'org-store-link
|
||||
:desc "Sync org caldav" "s" #'org-caldav-sync)
|
||||
|
||||
(:prefix ("q" . "quit/restart")
|
||||
:desc "Quit Emacs" "q" #'kill-emacs
|
||||
:desc "Save and quit Emacs" "Q" #'save-buffers-kill-terminal
|
||||
(:when (featurep! :feature workspaces)
|
||||
:desc "Quit Emacs & forget session" "X" #'+workspace/kill-session-and-quit)
|
||||
:desc "Restart & restore Emacs" "r" #'doom/restart-and-restore
|
||||
:desc "Restart Emacs" "R" #'doom/restart)
|
||||
|
||||
(:prefix ("&" . "snippets")
|
||||
:desc "New snippet" "n" #'yas-new-snippet
|
||||
:desc "Insert snippet" "i" #'yas-insert-snippet
|
||||
:desc "Find global snippet" "/" #'yas-visit-snippet-file
|
||||
:desc "Reload snippets" "r" #'yas-reload-all
|
||||
:desc "Create Temp Template" "c" #'aya-create
|
||||
:desc "Use Temp Template" "e" #'aya-expand)
|
||||
|
||||
(:prefix ("v" . "versioning")
|
||||
:desc "Git revert file" "R" #'vc-revert
|
||||
(:when (featurep! :ui vc-gutter)
|
||||
:desc "Git revert hunk" "r" #'git-gutter:revert-hunk
|
||||
:desc "Git stage hunk" "s" #'git-gutter:stage-hunk
|
||||
:desc "Git time machine" "t" #'git-timemachine-toggle
|
||||
:desc "Jump to next hunk" "n" #'git-gutter:next-hunk
|
||||
:desc "Jump to previous hunk" "p" #'git-gutter:previous-hunk)
|
||||
(:when (featurep! :tools magit)
|
||||
:desc "Magit dispatch" "/" #'magit-dispatch
|
||||
:desc "Forge dispatch" "'" #'forge-dispatch
|
||||
:desc "Magit status" "g" #'magit-status
|
||||
:desc "Magit file delete" "x" #'magit-file-delete
|
||||
:desc "Magit blame" "B" #'magit-blame-addition
|
||||
:desc "Magit clone" "C" #'+magit/clone
|
||||
:desc "Magit fetch" "F" #'magit-fetch
|
||||
:desc "Magit buffer log" "L" #'magit-log
|
||||
:desc "Git stage file" "S" #'magit-stage-file
|
||||
:desc "Git unstage file" "U" #'magit-unstage-file
|
||||
(:prefix ("f" . "find")
|
||||
:desc "Find file" "f" #'magit-find-file
|
||||
:desc "Find gitconfig file" "g" #'magit-find-git-config-file
|
||||
:desc "Find commit" "c" #'magit-show-commit
|
||||
:desc "Find issue" "i" #'forge-visit-issue
|
||||
:desc "Find pull request" "p" #'forge-visit-pullreq)
|
||||
(:prefix ("o" . "open in browser")
|
||||
:desc "Browse region or line" "." #'+vc/git-browse-region-or-line
|
||||
:desc "Browse remote" "r" #'forge-browse-remote
|
||||
:desc "Browse commit" "c" #'forge-browse-commit
|
||||
:desc "Browse an issue" "i" #'forge-browse-issue
|
||||
:desc "Browse a pull request" "p" #'forge-browse-pullreq
|
||||
:desc "Browse issues" "I" #'forge-browse-issues
|
||||
:desc "Browse pull requests" "P" #'forge-browse-pullreqs)
|
||||
(:prefix ("l" . "list")
|
||||
(:when (featurep! :tools gist)
|
||||
:desc "List gists" "g" #'+gist:list)
|
||||
:desc "List repositories" "r" #'magit-list-repositories
|
||||
:desc "List submodules" "s" #'magit-list-submodules
|
||||
:desc "List issues" "i" #'forge-list-issues
|
||||
:desc "List pull requests" "p" #'forge-list-pullreqs
|
||||
:desc "List notifications" "n" #'forge-list-notifications)
|
||||
(:prefix ("c" . "create")
|
||||
:desc "Initialize repo" "r" #'magit-init
|
||||
:desc "Clone repo" "R" #'+magit/clone
|
||||
:desc "Commit" "c" #'magit-commit-create
|
||||
:desc "Issue" "i" #'forge-create-issue
|
||||
:desc "Pull request" "p" #'forge-create-pullreq)))
|
||||
|
||||
(:prefix ("w" . "workspaces/windows")
|
||||
:desc "Autosave session" "a" #'doom/quicksave-session
|
||||
:desc "Display workspaces" "d" #'+workspace/display
|
||||
:desc "Rename workspace" "r" #'+workspace/rename
|
||||
:desc "Create workspace" "c" #'+workspace/new
|
||||
:desc "Delete workspace" "k" #'+workspace/delete
|
||||
:desc "Save session" "s" #'doom/save-session
|
||||
:desc "Save workspace" "S" #'+workspace/save
|
||||
:desc "Load session" "l" #'doom/load-session
|
||||
:desc "Load last autosaved session" "L" #'doom/quickload-session
|
||||
:desc "Kill other buffers" "o" #'doom/kill-other-buffers
|
||||
:desc "Undo window config" "u" #'winner-undo
|
||||
:desc "Redo window config" "U" #'winner-redo
|
||||
:desc "Switch to left workspace" "p" #'+workspace/switch-left
|
||||
:desc "Switch to right workspace" "n" #'+workspace/switch-right
|
||||
:desc "Switch to" "w" #'+workspace/switch-to
|
||||
:desc "Switch to workspace 1" "1" (λ! (+workspace/switch-to 0))
|
||||
:desc "Switch to workspace 2" "2" (λ! (+workspace/switch-to 1))
|
||||
:desc "Switch to workspace 3" "3" (λ! (+workspace/switch-to 2))
|
||||
:desc "Switch to workspace 4" "4" (λ! (+workspace/switch-to 3))
|
||||
:desc "Switch to workspace 5" "5" (λ! (+workspace/switch-to 4))
|
||||
:desc "Switch to workspace 6" "6" (λ! (+workspace/switch-to 5))
|
||||
:desc "Switch to workspace 7" "7" (λ! (+workspace/switch-to 6))
|
||||
:desc "Switch to workspace 8" "8" (λ! (+workspace/switch-to 7))
|
||||
:desc "Switch to workspace 9" "9" (λ! (+workspace/switch-to 8))
|
||||
:desc "Switch to last workspace" "0" #'+workspace/switch-to-last)
|
||||
|
||||
(:when (featurep! :editor multiple-cursors)
|
||||
(:prefix ("m" . "multiple cursors")
|
||||
:desc "Edit lines" "l" #'mc/edit-lines
|
||||
:desc "Mark next" "n" #'mc/mark-next-like-this
|
||||
:desc "Unmark next" "N" #'mc/unmark-next-like-this
|
||||
:desc "Mark previous" "p" #'mc/mark-previous-like-this
|
||||
:desc "Unmark previous" "P" #'mc/unmark-previous-like-this
|
||||
:desc "Mark all" "t" #'mc/mark-all-like-this
|
||||
:desc "Mark all DWIM" "m" #'mc/mark-all-like-this-dwim
|
||||
:desc "Edit line endings" "e" #'mc/edit-ends-of-lines
|
||||
:desc "Edit line starts" "a" #'mc/edit-beginnings-of-lines
|
||||
:desc "Mark tag" "s" #'mc/mark-sgml-tag-pair
|
||||
:desc "Mark in defun" "d" #'mc/mark-all-like-this-in-defun
|
||||
:desc "Add cursor w/mouse" "<mouse-1>" #'mc/add-cursor-on-click))
|
||||
|
||||
;; APPs
|
||||
(:when (featurep! :app email)
|
||||
(:prefix ("M" . "email")
|
||||
:desc "Open email app" "M" #'=email
|
||||
:desc "Compose email" "c" #'+email/compose))
|
||||
|
||||
(:when (featurep! :app irc)
|
||||
(:prefix ("I" . "irc")
|
||||
:desc "Open irc app" "I" #'=irc
|
||||
:desc "Next unread buffer" "a" #'tracking-next-buffer
|
||||
:desc "Quit irc" "q" #'+irc/quit
|
||||
:desc "Reconnect all" "r" #'circe-reconnect-all
|
||||
:desc "Send message" "s" #'+irc/send-message
|
||||
(:when (featurep! :completion ivy)
|
||||
:desc "Jump to channel" "j" #'irc/ivy-jump-to-channel)))
|
||||
|
||||
(:when (featurep! :app twitter)
|
||||
(:prefix ("T" . "twitter")
|
||||
:desc "Open twitter app" "T" #'=twitter
|
||||
:desc "Quit twitter" "q" #'+twitter/quit
|
||||
:desc "Rerender twits" "r" #'+twitter/rerender-all
|
||||
:desc "Ace link" "l" #'+twitter/ace-link)))
|
||||
|
||||
|
||||
;;
|
||||
;;; Plugins
|
||||
|
||||
(map! "C-=" #'er/expand-region
|
||||
"C--" #'er/contract-region
|
||||
(:when (featurep! :ui neotree)
|
||||
"<f9>" #'+neotree/open
|
||||
"<F-f9>" #'+neotree/find-this-file)
|
||||
(:when (featurep! :ui treemacs)
|
||||
"<f9>" #'+treemacs/open
|
||||
"<F-f9>" #'+treemacs/find-file)
|
||||
;; smartparens
|
||||
(:after smartparens
|
||||
:map smartparens-mode-map
|
||||
"C-M-a" #'sp-beginning-of-sexp
|
||||
"C-M-e" #'sp-end-of-sexp
|
||||
"C-M-f" #'sp-forward-sexp
|
||||
"C-M-b" #'sp-backward-sexp
|
||||
"C-M-d" #'sp-splice-sexp
|
||||
"C-M-k" #'sp-kill-sexp
|
||||
"C-M-t" #'sp-transpose-sexp
|
||||
"C-<right>" #'sp-forward-slurp-sexp
|
||||
"M-<right>" #'sp-forward-barf-sexp
|
||||
"C-<left>" #'sp-backward-slurp-sexp
|
||||
"M-<left>" #'sp-backward-barf-sexp)
|
||||
;; company mode
|
||||
"C-;" #'+company/complete
|
||||
;; 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))
|
||||
"C-M-y" #'counsel-yank-pop)
|
||||
;; repl toggle
|
||||
"C-c C-z" #'+eval/open-repl-other-window
|
||||
;; company mode
|
||||
(:after company
|
||||
:map company-active-map
|
||||
"C-o" #'company-search-kill-others
|
||||
"C-n" #'company-select-next
|
||||
"C-p" #'company-select-previous
|
||||
"C-h" #'company-quickhelp-manual-begin
|
||||
"C-S-h" #'company-show-doc-buffer
|
||||
"C-s" #'company-search-candidates
|
||||
"M-s" #'company-filter-candidates
|
||||
"<C-tab>" #'company-complete-common-or-cycle
|
||||
[tab] #'company-complete-common-or-cycle
|
||||
[backtab] #'company-select-previous
|
||||
"C-RET" #'counsel-company
|
||||
:map company-search-map
|
||||
"C-n" #'company-search-repeat-forward
|
||||
"C-p" #'company-search-repeat-backward
|
||||
"C-s" (λ! (company-search-abort) (company-filter-candidates)))
|
||||
;; neotree bindings
|
||||
(:after neotree
|
||||
:map neotree-mode-map
|
||||
"q" #'neotree-hide
|
||||
"RET" #'neotree-enter
|
||||
"SPC" #'neotree-quick-look
|
||||
"v" #'neotree-enter-vertical-split
|
||||
"s" #'neotree-enter-horizontal-split
|
||||
"c" #'neotree-create-node
|
||||
"D" #'neotree-delete-node
|
||||
"g" #'neotree-refresh
|
||||
"r" #'neotree-rename-node
|
||||
"R" #'neotree-refresh
|
||||
"h" #'+neotree/collapse-or-up
|
||||
"l" #'+neotree/expand-or-open
|
||||
"n" #'neotree-next-line
|
||||
"p" #'neotree-previous-line
|
||||
"N" #'neotree-select-next-sibling-node
|
||||
"P" #'neotree-select-previous-sibling-node)
|
||||
;; help and info
|
||||
(:after help-mode
|
||||
:map help-mode-map
|
||||
"o" #'ace-link-help
|
||||
">" #'help-go-forward
|
||||
"<" #'help-go-back
|
||||
"n" #'forward-button
|
||||
"p" #'backward-button)
|
||||
(:after helpful
|
||||
:map helpful-mode-map
|
||||
"o" #'ace-link-help)
|
||||
(:after apropos
|
||||
:map apropos-mode-map
|
||||
"o" #'ace-link-help
|
||||
"n" #'forward-button
|
||||
"p" #'backward-button)
|
||||
(:after info
|
||||
:map Info-mode-map
|
||||
"o" #'ace-link-info)
|
||||
;; yasnippet
|
||||
(:after yasnippet
|
||||
;; keymap while editing an inserted snippet
|
||||
:map yas-keymap
|
||||
"C-e" #'+snippets/goto-end-of-field
|
||||
"C-a" #'+snippets/goto-start-of-field
|
||||
"<S-tab>" #'yas-prev-field
|
||||
"<M-backspace>" #'+snippets/delete-to-start-of-field
|
||||
[backspace] #'+snippets/delete-backward-char
|
||||
[delete] #'+snippets/delete-forward-char-or-field)
|
||||
;; flycheck
|
||||
(:after flycheck
|
||||
:map flycheck-error-list-mode-map
|
||||
"C-n" #'flycheck-error-list-next-error
|
||||
"C-p" #'flycheck-error-list-previous-error
|
||||
"RET" #'flycheck-error-list-goto-error)
|
||||
;; ivy
|
||||
(:after ivy
|
||||
:map ivy-minibuffer-map
|
||||
"TAB" #'ivy-alt-done
|
||||
"C-g" #'keyboard-escape-quit)
|
||||
;; ein notebokks
|
||||
(:after ein:notebook-multilang
|
||||
:map ein:notebook-multilang-mode-map
|
||||
"C-c h" #'+ein/hydra/body))
|
||||
|
|
32
modules/config/default/+emacs.el
Normal file
32
modules/config/default/+emacs.el
Normal file
|
@ -0,0 +1,32 @@
|
|||
;;; config/default/+emacs.el -*- lexical-binding: t; -*-
|
||||
|
||||
(require 'projectile) ; we need its keybinds immediately
|
||||
|
||||
|
||||
;;
|
||||
;;; Reasonable defaults
|
||||
|
||||
(setq shift-select-mode t)
|
||||
(delete-selection-mode +1)
|
||||
|
||||
(def-package! expand-region
|
||||
:commands (er/contract-region er/mark-symbol er/mark-word)
|
||||
:config
|
||||
(defun doom*quit-expand-region ()
|
||||
"Properly abort an expand-region region."
|
||||
(when (memq last-command '(er/expand-region er/contract-region))
|
||||
(er/contract-region 0)))
|
||||
(advice-add #'evil-escape :before #'doom*quit-expand-region)
|
||||
(advice-add #'doom/escape :before #'doom*quit-expand-region))
|
||||
|
||||
|
||||
(def-package! winum
|
||||
:after-call (doom-switch-window-hook)
|
||||
:config (winum-mode +1))
|
||||
|
||||
|
||||
;;
|
||||
;;; Keybinds
|
||||
|
||||
(when (featurep! +bindings)
|
||||
(load! "+emacs-bindings"))
|
|
@ -2,10 +2,6 @@
|
|||
|
||||
;; This file defines a Spacemacs-esque keybinding scheme
|
||||
|
||||
;; expand-region's prompt can't tell what key contract-region is bound to, so we
|
||||
;; tell it explicitly.
|
||||
(setq expand-region-contract-fast-key "C-v")
|
||||
|
||||
;; Don't let evil-collection interfere with certain keys
|
||||
(setq evil-collection-key-blacklist
|
||||
(list "C-j" "C-k" "gd" "gf" "K" "[" "]" "gz"
|
||||
|
@ -21,9 +17,6 @@
|
|||
"M-;" #'eval-expression
|
||||
"A-;" #'eval-expression)
|
||||
|
||||
[remap evil-jump-to-tag] #'projectile-find-tag
|
||||
[remap find-tag] #'projectile-find-tag
|
||||
|
||||
;; Smart tab
|
||||
:i [tab] (general-predicate-dispatch nil ; fall back to nearest keymap
|
||||
(and (featurep! :feature snippets)
|
||||
|
@ -34,10 +27,6 @@
|
|||
(+company-has-completion-p))
|
||||
'+company/complete)
|
||||
:n [tab] (general-predicate-dispatch nil
|
||||
(derived-mode-p 'magit-mode)
|
||||
'magit-section-toggle
|
||||
(derived-mode-p 'deadgrep-mode)
|
||||
'deadgrep-toggle-file-results
|
||||
(and (featurep! :editor fold)
|
||||
(save-excursion (end-of-line) (invisible-p (point))))
|
||||
'+fold/toggle
|
||||
|
@ -59,18 +48,111 @@
|
|||
:i [remap newline] #'newline-and-indent ; auto-indent on newline
|
||||
:i "C-j" #'+default/newline ; default behavior
|
||||
|
||||
;; expand-region
|
||||
:v "v" (general-predicate-dispatch 'er/expand-region
|
||||
(eq (evil-visual-type) 'line)
|
||||
'evil-visual-char)
|
||||
:v "C-v" #'er/contract-region
|
||||
|
||||
(:after vc-annotate
|
||||
:map vc-annotate-mode-map
|
||||
[remap quit-window] #'kill-this-buffer)
|
||||
|
||||
;; misc
|
||||
:n "C-S-f" #'toggle-frame-fullscreen)
|
||||
:n "C-S-f" #'toggle-frame-fullscreen
|
||||
|
||||
;; Global evil keybinds
|
||||
:m "]a" #'evil-forward-arg
|
||||
:m "[a" #'evil-backward-arg
|
||||
:m "]o" #'outline-next-visible-heading
|
||||
:m "[o" #'outline-previous-visible-heading
|
||||
:n "]b" #'next-buffer
|
||||
:n "[b" #'previous-buffer
|
||||
:n "zx" #'kill-this-buffer
|
||||
:n "ZX" #'bury-buffer
|
||||
:n "gp" #'+evil/reselect-paste
|
||||
:n "g=" #'widen
|
||||
:v "g=" #'+evil:narrow-buffer
|
||||
:nv "g@" #'+evil:apply-macro
|
||||
:nv "gc" #'evil-commentary
|
||||
:nv "gx" #'evil-exchange
|
||||
:nv "C-a" #'evil-numbers/inc-at-pt
|
||||
:nv "C-S-a" #'evil-numbers/dec-at-pt
|
||||
:v "gp" #'+evil/paste-preserve-register
|
||||
:v "@" #'+evil:apply-macro
|
||||
;; repeat in visual mode (FIXME buggy)
|
||||
:v "." #'+evil:apply-macro
|
||||
;; don't leave visual mode after shifting
|
||||
:v "<" #'+evil/visual-dedent ; vnoremap < <gv
|
||||
:v ">" #'+evil/visual-indent ; vnoremap > >gv
|
||||
|
||||
;; window management (prefix "C-w")
|
||||
(:map evil-window-map
|
||||
;; Navigation
|
||||
"C-h" #'evil-window-left
|
||||
"C-j" #'evil-window-down
|
||||
"C-k" #'evil-window-up
|
||||
"C-l" #'evil-window-right
|
||||
"C-w" #'other-window
|
||||
;; Swapping windows
|
||||
"H" #'+evil/window-move-left
|
||||
"J" #'+evil/window-move-down
|
||||
"K" #'+evil/window-move-up
|
||||
"L" #'+evil/window-move-right
|
||||
"C-S-w" #'ace-swap-window
|
||||
;; Window undo/redo
|
||||
"u" #'winner-undo
|
||||
"C-u" #'winner-undo
|
||||
"C-r" #'winner-redo
|
||||
"o" #'doom/window-enlargen
|
||||
"O" #'doom/window-zoom
|
||||
;; Delete window
|
||||
"c" #'+workspace/close-window-or-workspace
|
||||
"C-C" #'ace-delete-window)
|
||||
|
||||
;; Plugins
|
||||
;; evil-easymotion
|
||||
:m "gs" #'+evil/easymotion ; lazy-load `evil-easymotion'
|
||||
(:after evil-easymotion
|
||||
:map evilem-map
|
||||
"a" (evilem-create #'evil-forward-arg)
|
||||
"A" (evilem-create #'evil-backward-arg)
|
||||
"s" (evilem-create #'evil-snipe-repeat
|
||||
:name 'evil-easymotion-snipe-forward
|
||||
:pre-hook (save-excursion (call-interactively #'evil-snipe-s))
|
||||
:bind ((evil-snipe-scope 'buffer)
|
||||
(evil-snipe-enable-highlight)
|
||||
(evil-snipe-enable-incremental-highlight)))
|
||||
"S" (evilem-create #'evil-snipe-repeat
|
||||
:name 'evil-easymotion-snipe-backward
|
||||
:pre-hook (save-excursion (call-interactively #'evil-snipe-S))
|
||||
:bind ((evil-snipe-scope 'buffer)
|
||||
(evil-snipe-enable-highlight)
|
||||
(evil-snipe-enable-incremental-highlight)))
|
||||
"SPC" #'avy-goto-char-timer
|
||||
"/" (evilem-create #'evil-ex-search-next
|
||||
:pre-hook (save-excursion (call-interactively #'evil-ex-search-forward))
|
||||
:bind ((evil-search-wrap)))
|
||||
"?" (evilem-create #'evil-ex-search-previous
|
||||
:pre-hook (save-excursion (call-interactively #'evil-ex-search-backward))
|
||||
:bind ((evil-search-wrap))))
|
||||
|
||||
;; text object plugins
|
||||
:textobj "x" #'evil-inner-xml-attr #'evil-outer-xml-attr
|
||||
:textobj "a" #'evil-inner-arg #'evil-outer-arg
|
||||
:textobj "B" #'evil-textobj-anyblock-inner-block #'evil-textobj-anyblock-a-block
|
||||
:textobj "i" #'evil-indent-plus-i-indent #'evil-indent-plus-a-indent
|
||||
:textobj "k" #'evil-indent-plus-i-indent-up #'evil-indent-plus-a-indent-up
|
||||
:textobj "j" #'evil-indent-plus-i-indent-up-down #'evil-indent-plus-a-indent-up-down
|
||||
|
||||
;; evil-snipe
|
||||
(:after evil-snipe
|
||||
:map evil-snipe-parent-transient-map
|
||||
"C-;" (λ! (require 'evil-easymotion)
|
||||
(call-interactively
|
||||
(evilem-create #'evil-snipe-repeat
|
||||
:bind ((evil-snipe-scope 'whole-buffer)
|
||||
(evil-snipe-enable-highlight)
|
||||
(evil-snipe-enable-incremental-highlight))))))
|
||||
|
||||
;; evil-surround
|
||||
:v "S" #'evil-surround-region
|
||||
:o "s" #'evil-surround-edit
|
||||
:o "S" #'evil-Surround-edit)
|
||||
|
||||
|
||||
;;
|
||||
|
@ -95,105 +177,6 @@
|
|||
:n "gR" #'+eval/buffer
|
||||
:v "gR" #'+eval:replace-region)
|
||||
|
||||
(:when (featurep! :feature evil)
|
||||
:m "]a" #'evil-forward-arg
|
||||
:m "[a" #'evil-backward-arg
|
||||
:m "]o" #'outline-next-visible-heading
|
||||
:m "[o" #'outline-previous-visible-heading
|
||||
:n "]b" #'next-buffer
|
||||
:n "[b" #'previous-buffer
|
||||
:n "zx" #'kill-this-buffer
|
||||
:n "ZX" #'bury-buffer
|
||||
:n "gp" #'+evil/reselect-paste
|
||||
:n "g=" #'widen
|
||||
:v "g=" #'+evil:narrow-buffer
|
||||
:nv "g@" #'+evil:apply-macro
|
||||
:nv "gc" #'evil-commentary
|
||||
:nv "gx" #'evil-exchange
|
||||
:nv "C-a" #'evil-numbers/inc-at-pt
|
||||
:nv "C-S-a" #'evil-numbers/dec-at-pt
|
||||
:v "gp" #'+evil/paste-preserve-register
|
||||
:v "@" #'+evil:apply-macro
|
||||
;; repeat in visual mode (FIXME buggy)
|
||||
:v "." #'+evil:apply-macro
|
||||
;; don't leave visual mode after shifting
|
||||
:v "<" #'+evil/visual-dedent ; vnoremap < <gv
|
||||
:v ">" #'+evil/visual-indent ; vnoremap > >gv
|
||||
|
||||
;; window management (prefix "C-w")
|
||||
(:map evil-window-map
|
||||
;; Navigation
|
||||
"C-h" #'evil-window-left
|
||||
"C-j" #'evil-window-down
|
||||
"C-k" #'evil-window-up
|
||||
"C-l" #'evil-window-right
|
||||
"C-w" #'other-window
|
||||
;; Swapping windows
|
||||
"H" #'+evil/window-move-left
|
||||
"J" #'+evil/window-move-down
|
||||
"K" #'+evil/window-move-up
|
||||
"L" #'+evil/window-move-right
|
||||
"C-S-w" #'ace-swap-window
|
||||
;; Window undo/redo
|
||||
"u" #'winner-undo
|
||||
"C-u" #'winner-undo
|
||||
"C-r" #'winner-redo
|
||||
"o" #'doom/window-enlargen
|
||||
"O" #'doom/window-zoom
|
||||
;; Delete window
|
||||
"c" #'+workspace/close-window-or-workspace
|
||||
"C-C" #'ace-delete-window)
|
||||
|
||||
;; Plugins
|
||||
;; evil-easymotion
|
||||
:m "gs" #'+evil/easymotion ; lazy-load `evil-easymotion'
|
||||
(:after evil-easymotion
|
||||
:map evilem-map
|
||||
"a" (evilem-create #'evil-forward-arg)
|
||||
"A" (evilem-create #'evil-backward-arg)
|
||||
"s" (evilem-create #'evil-snipe-repeat
|
||||
:name 'evil-easymotion-snipe-forward
|
||||
:pre-hook (save-excursion (call-interactively #'evil-snipe-s))
|
||||
:bind ((evil-snipe-scope 'buffer)
|
||||
(evil-snipe-enable-highlight)
|
||||
(evil-snipe-enable-incremental-highlight)))
|
||||
"S" (evilem-create #'evil-snipe-repeat
|
||||
:name 'evil-easymotion-snipe-backward
|
||||
:pre-hook (save-excursion (call-interactively #'evil-snipe-S))
|
||||
:bind ((evil-snipe-scope 'buffer)
|
||||
(evil-snipe-enable-highlight)
|
||||
(evil-snipe-enable-incremental-highlight)))
|
||||
"SPC" #'avy-goto-char-timer
|
||||
"/" (evilem-create #'evil-ex-search-next
|
||||
:pre-hook (save-excursion (call-interactively #'evil-ex-search-forward))
|
||||
:bind ((evil-search-wrap)))
|
||||
"?" (evilem-create #'evil-ex-search-previous
|
||||
:pre-hook (save-excursion (call-interactively #'evil-ex-search-backward))
|
||||
:bind ((evil-search-wrap))))
|
||||
|
||||
;; text object plugins
|
||||
:textobj "x" #'evil-inner-xml-attr #'evil-outer-xml-attr
|
||||
:textobj "a" #'evil-inner-arg #'evil-outer-arg
|
||||
:textobj "B" #'evil-textobj-anyblock-inner-block #'evil-textobj-anyblock-a-block
|
||||
:textobj "i" #'evil-indent-plus-i-indent #'evil-indent-plus-a-indent
|
||||
:textobj "k" #'evil-indent-plus-i-indent-up #'evil-indent-plus-a-indent-up
|
||||
:textobj "j" #'evil-indent-plus-i-indent-up-down #'evil-indent-plus-a-indent-up-down
|
||||
|
||||
;; evil-snipe
|
||||
(:after evil-snipe
|
||||
:map evil-snipe-parent-transient-map
|
||||
"C-;" (λ! (require 'evil-easymotion)
|
||||
(call-interactively
|
||||
(evilem-create #'evil-snipe-repeat
|
||||
:bind ((evil-snipe-scope 'whole-buffer)
|
||||
(evil-snipe-enable-highlight)
|
||||
(evil-snipe-enable-incremental-highlight))))))
|
||||
|
||||
;; evil-surround
|
||||
:v "S" #'evil-surround-region
|
||||
:o "s" #'evil-surround-edit
|
||||
:o "S" #'evil-Surround-edit)
|
||||
|
||||
(:when (featurep! :feature lookup)
|
||||
:nv "K" #'+lookup/documentation
|
||||
:nv "gd" #'+lookup/definition
|
||||
|
@ -216,10 +199,13 @@
|
|||
[delete] #'+snippets/delete-forward-char-or-field)))
|
||||
|
||||
(:when (featurep! :tools flyspell)
|
||||
:m "]s" #'evil-next-flyspell-error
|
||||
:m "[s" #'evil-prev-flyspell-error
|
||||
:m "]S" #'flyspell-correct-word-generic
|
||||
:m "[S" #'flyspell-correct-previous-word-generic
|
||||
(:map flyspell-mouse-map
|
||||
"RET" #'flyspell-correct-word-generic
|
||||
[return] #'flyspell-correct-word-generic
|
||||
[mouse-1] #'flyspell-correct-word-generic))
|
||||
|
||||
(:when (featurep! :tools flycheck)
|
||||
|
@ -227,11 +213,12 @@
|
|||
:m "[e" #'previous-error
|
||||
(:after flycheck
|
||||
:map flycheck-error-list-mode-map
|
||||
:n "C-n" #'flycheck-error-list-next-error
|
||||
:n "C-p" #'flycheck-error-list-previous-error
|
||||
:n "j" #'flycheck-error-list-next-error
|
||||
:n "k" #'flycheck-error-list-previous-error
|
||||
:n "RET" #'flycheck-error-list-goto-error))
|
||||
:n "C-n" #'flycheck-error-list-next-error
|
||||
:n "C-p" #'flycheck-error-list-previous-error
|
||||
:n "j" #'flycheck-error-list-next-error
|
||||
:n "k" #'flycheck-error-list-previous-error
|
||||
:n "RET" #'flycheck-error-list-goto-error
|
||||
:n [return] #'flycheck-error-list-goto-error))
|
||||
|
||||
(:when (featurep! :feature workspaces)
|
||||
:n "gt" #'+workspace/switch-right
|
||||
|
@ -279,6 +266,7 @@
|
|||
"C-S-s" (cond ((featurep! :completion helm) #'helm-company)
|
||||
((featurep! :completion ivy) #'counsel-company))
|
||||
"C-SPC" #'company-complete-common
|
||||
"TAB" #'company-complete-common-or-cycle
|
||||
[tab] #'company-complete-common-or-cycle
|
||||
[backtab] #'company-select-previous)
|
||||
(:map company-search-map ; applies to `company-filter-map' too
|
||||
|
@ -287,9 +275,11 @@
|
|||
"C-j" #'company-select-next-or-abort
|
||||
"C-k" #'company-select-previous-or-abort
|
||||
"C-s" (λ! (company-search-abort) (company-filter-candidates))
|
||||
[escape] #'company-search-abort)
|
||||
"ESC" #'company-search-abort)
|
||||
;; TAB auto-completion in term buffers
|
||||
:map comint-mode-map [tab] #'company-complete))
|
||||
(:map comint-mode-map
|
||||
"TAB" #'company-complete
|
||||
[tab] #'company-complete)))
|
||||
|
||||
(:when (featurep! :completion ivy)
|
||||
(:map (help-mode-map helpful-mode-map)
|
||||
|
@ -302,6 +292,7 @@
|
|||
(:after counsel
|
||||
:map counsel-ag-map
|
||||
"C-SPC" #'ivy-call-and-recenter ; preview
|
||||
"C-l" #'ivy-done
|
||||
[backtab] #'+ivy/wgrep-occur ; search/replace on results
|
||||
[C-return] (+ivy-do-action! #'+ivy-git-grep-other-window-action))
|
||||
(:after swiper
|
||||
|
@ -327,6 +318,7 @@
|
|||
"C-s" #'helm-minibuffer-history
|
||||
"C-b" #'backward-word
|
||||
;; Swap TAB and C-z
|
||||
"TAB" #'helm-execute-persistent-action
|
||||
[tab] #'helm-execute-persistent-action
|
||||
"C-z" #'helm-select-action)
|
||||
(:after swiper-helm
|
||||
|
@ -363,29 +355,31 @@
|
|||
(:when (featurep! :ui neotree)
|
||||
:after neotree
|
||||
:map neotree-mode-map
|
||||
:n "g" nil
|
||||
:n [tab] #'neotree-quick-look
|
||||
:n [return] #'neotree-enter
|
||||
:n [backspace] #'evil-window-prev
|
||||
:n "c" #'neotree-create-node
|
||||
:n "r" #'neotree-rename-node
|
||||
:n "d" #'neotree-delete-node
|
||||
:n "j" #'neotree-next-line
|
||||
:n "k" #'neotree-previous-line
|
||||
:n "n" #'neotree-next-line
|
||||
:n "p" #'neotree-previous-line
|
||||
:n "h" #'+neotree/collapse-or-up
|
||||
:n "l" #'+neotree/expand-or-open
|
||||
:n "J" #'neotree-select-next-sibling-node
|
||||
:n "K" #'neotree-select-previous-sibling-node
|
||||
:n "H" #'neotree-select-up-node
|
||||
:n "L" #'neotree-select-down-node
|
||||
:n "G" #'evil-goto-line
|
||||
:n "gg" #'evil-goto-first-line
|
||||
:n "v" #'neotree-enter-vertical-split
|
||||
:n "s" #'neotree-enter-horizontal-split
|
||||
:n "q" #'neotree-hide
|
||||
:n "R" #'neotree-refresh)
|
||||
:n "g" nil
|
||||
:n "TAB" #'neotree-quick-look
|
||||
:n "RET" #'neotree-enter
|
||||
:n [tab] #'neotree-quick-look
|
||||
:n [return] #'neotree-enter
|
||||
:n "DEL" #'evil-window-prev
|
||||
:n "c" #'neotree-create-node
|
||||
:n "r" #'neotree-rename-node
|
||||
:n "d" #'neotree-delete-node
|
||||
:n "j" #'neotree-next-line
|
||||
:n "k" #'neotree-previous-line
|
||||
:n "n" #'neotree-next-line
|
||||
:n "p" #'neotree-previous-line
|
||||
:n "h" #'+neotree/collapse-or-up
|
||||
:n "l" #'+neotree/expand-or-open
|
||||
:n "J" #'neotree-select-next-sibling-node
|
||||
:n "K" #'neotree-select-previous-sibling-node
|
||||
:n "H" #'neotree-select-up-node
|
||||
:n "L" #'neotree-select-down-node
|
||||
:n "G" #'evil-goto-line
|
||||
:n "gg" #'evil-goto-first-line
|
||||
:n "v" #'neotree-enter-vertical-split
|
||||
:n "s" #'neotree-enter-horizontal-split
|
||||
:n "q" #'neotree-hide
|
||||
:n "R" #'neotree-refresh)
|
||||
|
||||
(:when (featurep! :ui popup)
|
||||
:n "C-`" #'+popup/toggle
|
||||
|
@ -415,8 +409,9 @@
|
|||
:nv "N" #'evil-mc-make-and-goto-last-cursor
|
||||
:nv "p" #'evil-mc-make-and-goto-prev-cursor
|
||||
:nv "P" #'evil-mc-make-and-goto-first-cursor
|
||||
:nv "q" #'evil-mc-undo-all-cursors
|
||||
:nv "t" #'+multiple-cursors/evil-mc-toggle-cursors
|
||||
:nv "u" #'evil-mc-undo-all-cursors
|
||||
:nv "u" #'evil-mc-undo-last-added-cursor
|
||||
:nv "z" #'+multiple-cursors/evil-mc-make-cursor-here)
|
||||
(:after evil-mc
|
||||
:map evil-mc-key-map
|
||||
|
@ -433,9 +428,10 @@
|
|||
:nv "C-M-d" #'evil-multiedit-restore
|
||||
(:after evil-multiedit
|
||||
(:map evil-multiedit-state-map
|
||||
"M-d" #'evil-multiedit-match-and-next
|
||||
"M-D" #'evil-multiedit-match-and-prev
|
||||
"RET" #'evil-multiedit-toggle-or-restrict-region)
|
||||
"M-d" #'evil-multiedit-match-and-next
|
||||
"M-D" #'evil-multiedit-match-and-prev
|
||||
"RET" #'evil-multiedit-toggle-or-restrict-region
|
||||
[return] #'evil-multiedit-toggle-or-restrict-region)
|
||||
(:map (evil-multiedit-state-map evil-multiedit-insert-state-map)
|
||||
"C-n" #'evil-multiedit-next
|
||||
"C-p" #'evil-multiedit-prev)))
|
||||
|
@ -467,7 +463,8 @@
|
|||
(:when (featurep! :tools gist)
|
||||
:after gist
|
||||
:map gist-list-menu-mode-map
|
||||
:n "RET" #'+gist/open-current
|
||||
:n "RET" #'+gist/open-current
|
||||
:n [return] #'+gist/open-current
|
||||
:n "b" #'gist-browse-current-url
|
||||
:n "c" #'gist-add-buffer
|
||||
:n "d" #'gist-kill-current
|
||||
|
@ -497,16 +494,16 @@
|
|||
|
||||
;; C-u is used by evil
|
||||
:desc "Universal argument" "u" #'universal-argument
|
||||
:desc "Window management" "w" #'evil-window-map
|
||||
:desc "window" "w" evil-window-map
|
||||
:desc "help" "h" help-map
|
||||
|
||||
:desc "Toggle last popup" "~" #'+popup/toggle
|
||||
:desc "Find file" "." #'find-file
|
||||
|
||||
:desc "Switch buffer" "," #'switch-to-buffer
|
||||
(:when (featurep! :feature workspaces)
|
||||
:desc "Switch workspace buffer" "," #'persp-switch-to-buffer
|
||||
:desc "Switch buffer" "<" #'switch-to-buffer)
|
||||
(:unless (featurep! :feature workspaces)
|
||||
:desc "Switch buffer" "," #'switch-to-buffer)
|
||||
|
||||
:desc "Resume last search" "'"
|
||||
(cond ((featurep! :completion ivy) #'ivy-resume)
|
||||
|
@ -520,49 +517,23 @@
|
|||
(:prefix ("/" . "search")
|
||||
:desc "Jump to symbol across buffers" "I" #'imenu-anywhere
|
||||
:desc "Search buffer" "b" #'swiper
|
||||
:desc "Search current directory" "d"
|
||||
(cond ((featurep! :completion helm) #'+helm/project-search-from-cwd)
|
||||
((featurep! :completion ivy) #'+ivy/project-search-from-cwd))
|
||||
:desc "Search current directory" "d" #'+default/search-from-cwd
|
||||
:desc "Jump to symbol" "i" #'imenu
|
||||
:desc "Jump to link" "l" #'ace-link
|
||||
:desc "Look up online" "o" #'+lookup/online-select
|
||||
:desc "Search project" "p"
|
||||
(cond ((featurep! :completion ivy) #'+ivy/project-search)
|
||||
((featurep! :completion helm) #'+helm/project-search)))
|
||||
|
||||
(:prefix ("]" . "next")
|
||||
:desc "Increase text size" "]" #'text-scale-increase
|
||||
:desc "Next buffer" "b" #'next-buffer
|
||||
:desc "Next diff Hunk" "d" #'git-gutter:next-hunk
|
||||
:desc "Next todo" "t" #'hl-todo-next
|
||||
:desc "Next error" "e" #'next-error
|
||||
:desc "Next workspace" "w" #'+workspace/switch-right
|
||||
:desc "Next spelling error" "s" #'evil-next-flyspell-error
|
||||
:desc "Next spelling correction" "S" #'flyspell-correct-next-word-generic)
|
||||
|
||||
(:prefix ("[" . "previous")
|
||||
:desc "Decrease text size" "[" #'text-scale-decrease
|
||||
:desc "Previous buffer" "b" #'previous-buffer
|
||||
:desc "Previous diff Hunk" "d" #'git-gutter:previous-hunk
|
||||
:desc "Previous todo" "t" #'hl-todo-previous
|
||||
:desc "Previous error" "e" #'previous-error
|
||||
:desc "Previous workspace" "w" #'+workspace/switch-left
|
||||
:desc "Previous spelling error" "s" #'evil-prev-flyspell-error
|
||||
:desc "Previous spelling correction" "S" #'flyspell-correct-word-generic)
|
||||
:desc "Search project" "p" #'+default/search-project)
|
||||
|
||||
(:when (featurep! :feature workspaces)
|
||||
(:prefix ([tab] . "workspace")
|
||||
(:prefix ("TAB" . "workspace")
|
||||
:desc "Display tab bar" "TAB" #'+workspace/display
|
||||
:desc "Switch workspace" "." #'+workspace/switch-to
|
||||
:desc "New workspace" "n" #'+workspace/new
|
||||
:desc "Load workspace from file" "l" #'+workspace/load
|
||||
:desc "Load a past session" "L" #'+workspace/load-session
|
||||
:desc "Save workspace to file" "s" #'+workspace/save
|
||||
:desc "Autosave current session" "S" #'+workspace/save-session
|
||||
:desc "Switch workspace" "." #'+workspace/switch-to
|
||||
:desc "Delete session" "x" #'+workspace/kill-session
|
||||
:desc "Delete this workspace" "d" #'+workspace/delete
|
||||
:desc "Rename workspace" "r" #'+workspace/rename
|
||||
:desc "Restore last session" "R" #'+workspace/load-last-session
|
||||
:desc "Restore last session" "R" #'+workspace/restore-last-session
|
||||
:desc "Next workspace" "]" #'+workspace/switch-right
|
||||
:desc "Previous workspace" "[" #'+workspace/switch-left
|
||||
:desc "Switch to 1st workspace" "1" (λ! (+workspace/switch-to 0))
|
||||
|
@ -578,8 +549,6 @@
|
|||
|
||||
(:prefix ("b" . "buffer")
|
||||
:desc "Toggle narrowing" "-" #'doom/clone-and-narrow-buffer
|
||||
:desc "New empty buffer" "N" #'evil-buffer-new
|
||||
:desc "Sudo edit this file" "S" #'doom/sudo-this-file
|
||||
:desc "Previous buffer" "[" #'previous-buffer
|
||||
:desc "Next buffer" "]" #'next-buffer
|
||||
(:when (featurep! :feature workspaces)
|
||||
|
@ -589,40 +558,44 @@
|
|||
:desc "Switch buffer" "b" #'switch-to-buffer)
|
||||
:desc "Kill buffer" "k" #'kill-this-buffer
|
||||
:desc "Next buffer" "n" #'next-buffer
|
||||
:desc "New empty buffer" "N" #'evil-buffer-new
|
||||
:desc "Kill other buffers" "o" #'doom/kill-other-buffers
|
||||
:desc "Previous buffer" "p" #'previous-buffer
|
||||
:desc "Save buffer" "s" #'save-buffer
|
||||
:desc "Sudo edit this file" "S" #'doom/sudo-this-file
|
||||
:desc "Pop scratch buffer" "x" #'doom/open-scratch-buffer
|
||||
:desc "Bury buffer" "z" #'bury-buffer)
|
||||
|
||||
(:prefix ("c" . "code")
|
||||
:desc "Jump to references" "D" #'+lookup/references
|
||||
:desc "Evaluate & replace region" "E" #'+eval:replace-region
|
||||
:desc "Delete trailing newlines" "W" #'doom/delete-trailing-newlines
|
||||
:desc "Build tasks" "b" #'+eval/build
|
||||
:desc "Compile project" "c" #'projectile-compile-project
|
||||
:desc "Jump to definition" "d" #'+lookup/definition
|
||||
:desc "Jump to references" "D" #'+lookup/references
|
||||
:desc "Evaluate buffer/region" "e" #'+eval/buffer-or-region
|
||||
:desc "Evaluate & replace region" "E" #'+eval:replace-region
|
||||
:desc "Format buffer/region" "f" #'+format/region-or-buffer
|
||||
:desc "Open REPL" "r" #'+eval/open-repl-other-window
|
||||
:desc "Delete trailing whitespace" "w" #'delete-trailing-whitespace
|
||||
:desc "Delete trailing newlines" "W" #'doom/delete-trailing-newlines
|
||||
:desc "List errors" "x" #'flycheck-list-errors)
|
||||
|
||||
(:prefix ("f" . "file")
|
||||
:desc "Find file" "." #'find-file
|
||||
:desc "Find file" "." (if (fboundp 'counsel-file-jump) #'counsel-file-jump #'find-file)
|
||||
:desc "Find file in other project" ">" #'doom/browse-in-other-project
|
||||
:desc "Find file in project" "/" #'projectile-find-file
|
||||
:desc "Sudo find file" ">" #'doom/sudo-find-file
|
||||
:desc "Find file from here" "?" #'counsel-file-jump
|
||||
:desc "Browse emacs.d" "E" #'+default/browse-emacsd
|
||||
:desc "Browse private config" "P" #'+default/browse-config
|
||||
:desc "Recent project files" "R" #'projectile-recentf
|
||||
:desc "Delete this file" "X" #'doom/delete-this-file
|
||||
:desc "Find file in other project" "?" #'doom/find-file-in-other-project
|
||||
:desc "Find other file" "a" #'projectile-find-other-file
|
||||
:desc "Open project editorconfig" "c" #'editorconfig-find-current-editorconfig
|
||||
:desc "Find directory" "d" #'dired
|
||||
:desc "Find file in emacs.d" "e" #'+default/find-in-emacsd
|
||||
:desc "Find file in private config" "p" #'+default/find-in-config
|
||||
:desc "Browse emacs.d" "E" #'+default/browse-emacsd
|
||||
:desc "Find file from here" "f" #'find-file
|
||||
:desc "Find file in private config" "p" #'doom/find-file-in-private-config
|
||||
:desc "Browse private config" "P" #'doom/open-private-config
|
||||
:desc "Recent files" "r" #'recentf-open-files
|
||||
:desc "Recent project files" "R" #'projectile-recentf
|
||||
:desc "Save file" "s" #'save-buffer
|
||||
:desc "Sudo find file" "S" #'doom/sudo-find-file
|
||||
:desc "Delete this file" "X" #'doom/delete-this-file
|
||||
:desc "Yank filename" "y" #'+default/yank-buffer-filename)
|
||||
|
||||
(:prefix ("g" . "git")
|
||||
|
@ -673,34 +646,6 @@
|
|||
:desc "Issue" "i" #'forge-create-issue
|
||||
:desc "Pull request" "p" #'forge-create-pullreq)))
|
||||
|
||||
(:prefix ("h" . "help")
|
||||
:desc "What face" "'" #'doom/what-face
|
||||
:desc "Describe at point" "." #'helpful-at-point
|
||||
:desc "Describe active minor modes" ";" #'doom/describe-active-minor-mode
|
||||
:desc "Open Doom manual" "D" #'doom/open-manual
|
||||
:desc "Open vanilla sandbox" "E" #'doom/open-vanilla-sandbox
|
||||
:desc "Describe face" "F" #'describe-face
|
||||
:desc "Find documentation" "K" #'+lookup/documentation
|
||||
:desc "Command log" "L" #'global-command-log-mode
|
||||
:desc "Describe mode" "M" #'describe-mode
|
||||
:desc "Reload private config" "R" #'doom/reload
|
||||
:desc "Print Doom version" "V" #'doom/version
|
||||
:desc "Apropos" "a" #'apropos
|
||||
:desc "Open Bug Report" "b" #'doom/open-bug-report
|
||||
:desc "Describe char" "c" #'describe-char
|
||||
:desc "Describe DOOM module" "d" #'doom/describe-module
|
||||
:desc "Describe function" "f" #'describe-function
|
||||
:desc "Emacs help map" "h" help-map
|
||||
:desc "Info" "i" #'info-lookup-symbol
|
||||
:desc "Describe key" "k" #'describe-key
|
||||
:desc "Find library" "l" #'find-library
|
||||
:desc "View *Messages*" "m" #'view-echo-area-messages
|
||||
:desc "Toggle profiler" "p" #'doom/toggle-profiler
|
||||
:desc "Reload theme" "r" #'doom/reload-theme
|
||||
:desc "Describe DOOM setting" "s" #'doom/describe-setters
|
||||
:desc "Describe variable" "v" #'describe-variable
|
||||
:desc "Man pages" "w" #'+default/man-or-woman)
|
||||
|
||||
(:prefix ("i" . "insert")
|
||||
:desc "Insert from clipboard" "y" #'+default/yank-pop
|
||||
:desc "Insert from evil register" "r" #'evil-ex-registers
|
||||
|
@ -710,10 +655,17 @@
|
|||
:desc "Open deft" "d" #'deft
|
||||
:desc "Find file in notes" "n" #'+default/find-in-notes
|
||||
:desc "Browse notes" "N" #'+default/browse-notes
|
||||
:desc "Org capture" "x" #'org-capture)
|
||||
:desc "Pop scratch buffer" "s" #'doom/open-scratch-buffer
|
||||
:desc "Org capture" "x" #'org-capture
|
||||
:desc "Org store link" "l" #'org-store-link)
|
||||
|
||||
(:prefix ("o" . "open")
|
||||
:desc "Org agenda" "a" #'org-agenda
|
||||
:desc "Org agenda" "A" #'org-agenda
|
||||
(:prefix ("a" . "org agenda")
|
||||
:desc "Agenda" "a" #'org-agenda
|
||||
:desc "Todo list" "t" #'org-todo-list
|
||||
:desc "Tags search" "m" #'org-tags-view
|
||||
:desc "View search" "v" #'org-search-view)
|
||||
:desc "Default browser" "b" #'browse-url-of-file
|
||||
:desc "Debugger" "d" #'+debug/open
|
||||
:desc "REPL" "r" #'+eval/open-repl-other-window
|
||||
|
@ -767,12 +719,15 @@
|
|||
:desc "List project tasks" "t" #'+default/project-tasks
|
||||
:desc "Invalidate cache" "x" #'projectile-invalidate-cache)
|
||||
|
||||
(:prefix ("q" . "quit/restart")
|
||||
(:prefix ("q" . "session")
|
||||
:desc "Quit Emacs" "q" #'evil-quit-all
|
||||
:desc "Save and quit Emacs" "Q" #'evil-save-and-quit
|
||||
:desc "Quit Emacs & forget session" "X" #'+workspace/kill-session-and-quit
|
||||
:desc "Restart & restore Emacs" "r" #'+workspace/restart-emacs-then-restore
|
||||
:desc "Restart Emacs" "R" #'restart-emacs)
|
||||
:desc "Quick save current session" "s" #'doom/quicksave-session
|
||||
:desc "Restore last session" "l" #'doom/quickload-session
|
||||
:desc "Save session to file" "S" #'doom/save-session
|
||||
:desc "Restore session from file" "L" #'doom/load-session
|
||||
:desc "Restart & restore Emacs" "r" #'doom/restart-and-restore
|
||||
:desc "Restart Emacs" "R" #'doom/restart)
|
||||
|
||||
(:when (featurep! :tools upload)
|
||||
(:prefix ("r" . "remote")
|
||||
|
@ -790,15 +745,16 @@
|
|||
:desc "Jump to mode snippet" "/" #'yas-visit-snippet-file
|
||||
:desc "Jump to snippet" "s" #'+snippets/find-file
|
||||
:desc "Browse snippets" "S" #'+snippets/browse
|
||||
:desc "Reload snippets" "r" #'yas-reload-all))
|
||||
:desc "Reload snippets" "r" #'yas-reload-all
|
||||
:desc "Create temporary snippet" "c" #'aya-create
|
||||
:desc "Use temporary snippet" "e" #'aya-expand))
|
||||
|
||||
(:prefix ("t" . "toggle")
|
||||
:desc "Flyspell" "s" #'flyspell-mode
|
||||
:desc "Flycheck" "f" #'flycheck-mode
|
||||
:desc "Line numbers" "l" #'doom/toggle-line-numbers
|
||||
:desc "Frame fullscreen" "F" #'toggle-frame-fullscreen
|
||||
:desc "Indent guides" "i" #'highlight-indentation-mode
|
||||
:desc "Indent guides (column)" "I" #'highlight-indentation-current-column-mode
|
||||
:desc "Indent guides" "i" #'highlight-indent-guides-mode
|
||||
:desc "Impatient mode" "h" #'+impatient-mode/toggle
|
||||
:desc "Big mode" "b" #'doom-big-font-mode
|
||||
:desc "Evil goggles" "g" #'evil-goggles-mode
|
||||
|
|
109
modules/config/default/+evil.el
Normal file
109
modules/config/default/+evil.el
Normal file
|
@ -0,0 +1,109 @@
|
|||
;;; config/default/+evil.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defun +default|disable-delete-selection-mode ()
|
||||
(delete-selection-mode -1))
|
||||
(add-hook 'evil-insert-state-entry-hook #'delete-selection-mode)
|
||||
(add-hook 'evil-insert-state-exit-hook #'+default|disable-delete-selection-mode)
|
||||
|
||||
|
||||
;;
|
||||
;;; Smartparens config
|
||||
|
||||
(when (featurep! +smartparens)
|
||||
;; You can disable :unless predicates with (sp-pair "'" nil :unless nil)
|
||||
;; And disable :post-handlers with (sp-pair "{" nil :post-handlers nil)
|
||||
;; or specific :post-handlers with:
|
||||
;; (sp-pair "{" nil :post-handlers '(:rem ("| " "SPC")))
|
||||
(after! smartparens
|
||||
;; Autopair quotes more conservatively; if I'm next to a word/before another
|
||||
;; quote, I likely don't want to open a new pair.
|
||||
(let ((unless-list '(sp-point-before-word-p
|
||||
sp-point-after-word-p
|
||||
sp-point-before-same-p)))
|
||||
(sp-pair "'" nil :unless unless-list)
|
||||
(sp-pair "\"" nil :unless unless-list))
|
||||
|
||||
;; Expand {|} => { | }
|
||||
;; Expand {|} => {
|
||||
;; |
|
||||
;; }
|
||||
(dolist (brace '("(" "{" "["))
|
||||
(sp-pair brace nil
|
||||
:post-handlers '(("||\n[i]" "RET") ("| " "SPC"))
|
||||
;; I likely don't want a new pair if adjacent to a word or opening brace
|
||||
:unless '(sp-point-before-word-p sp-point-before-same-p)))
|
||||
|
||||
;; Major-mode specific fixes
|
||||
(sp-local-pair '(ruby-mode enh-ruby-mode) "{" "}"
|
||||
:pre-handlers '(:rem sp-ruby-pre-handler)
|
||||
:post-handlers '(:rem sp-ruby-post-handler))
|
||||
|
||||
;; Don't do square-bracket space-expansion where it doesn't make sense to
|
||||
(sp-local-pair '(emacs-lisp-mode org-mode markdown-mode gfm-mode)
|
||||
"[" nil :post-handlers '(:rem ("| " "SPC")))
|
||||
|
||||
;; Reasonable default pairs for HTML-style comments
|
||||
(sp-local-pair (append sp--html-modes '(markdown-mode gfm-mode))
|
||||
"<!--" "-->"
|
||||
:unless '(sp-point-before-word-p sp-point-before-same-p)
|
||||
:actions '(insert) :post-handlers '(("| " "SPC")))
|
||||
|
||||
;; Disable electric keys in C modes because it interferes with smartparens
|
||||
;; and custom bindings. We'll do it ourselves (mostly).
|
||||
(after! cc-mode
|
||||
(c-toggle-electric-state -1)
|
||||
(c-toggle-auto-newline -1)
|
||||
(setq c-electric-flag nil)
|
||||
(dolist (key '("#" "{" "}" "/" "*" ";" "," ":" "(" ")" "\177"))
|
||||
(define-key c-mode-base-map key nil)))
|
||||
|
||||
;; Expand C-style doc comment blocks. Must be done manually because some of
|
||||
;; these languages use specialized (and deferred) parsers, whose state we
|
||||
;; can't access while smartparens is doing its thing.
|
||||
(defun +default-expand-doc-comment-block (&rest _ignored)
|
||||
(let ((indent (current-indentation)))
|
||||
(newline-and-indent)
|
||||
(save-excursion
|
||||
(newline)
|
||||
(insert (make-string indent 32) " */")
|
||||
(delete-char 2))))
|
||||
(sp-local-pair
|
||||
'(js2-mode typescript-mode rjsx-mode rust-mode c-mode c++-mode objc-mode
|
||||
csharp-mode java-mode php-mode css-mode scss-mode less-css-mode
|
||||
stylus-mode)
|
||||
"/*" "*/"
|
||||
:actions '(insert)
|
||||
:post-handlers '(("| " "SPC") ("|\n*/[i][d-2]" "RET") (+default-expand-doc-comment-block "*")))
|
||||
|
||||
;; Highjacks backspace to:
|
||||
;; a) balance spaces inside brackets/parentheses ( | ) -> (|)
|
||||
;; b) delete space-indented `tab-width' steps at a time
|
||||
;; c) close empty multiline brace blocks in one step:
|
||||
;; {
|
||||
;; |
|
||||
;; }
|
||||
;; becomes {|}
|
||||
;; d) refresh smartparens' :post-handlers, so SPC and RET expansions work
|
||||
;; even after a backspace.
|
||||
;; e) properly delete smartparen pairs when they are encountered, without
|
||||
;; the need for strict mode.
|
||||
;; f) do none of this when inside a string
|
||||
(advice-add #'delete-backward-char :override #'+default*delete-backward-char)
|
||||
|
||||
;; Makes `newline-and-indent' continue comments (and more reliably)
|
||||
(advice-add #'newline-and-indent :around #'+default*newline-indent-and-continue-comments)))
|
||||
|
||||
|
||||
;;
|
||||
;;; Keybindings
|
||||
|
||||
;; This section is dedicated to "fixing" certain keys so that they behave
|
||||
;; sensibly (and consistently with similar contexts).
|
||||
|
||||
;; Make SPC u SPC u [...] possible (#747)
|
||||
(map! :map universal-argument-map
|
||||
:prefix doom-leader-key "u" #'universal-argument-more
|
||||
:prefix doom-leader-alt-key "u" #'universal-argument-more)
|
||||
|
||||
(when (featurep! +bindings)
|
||||
(load! "+evil-bindings"))
|
|
@ -34,18 +34,6 @@
|
|||
(defun +default/find-in-notes ()
|
||||
(interactive) (doom-project-find-file org-directory))
|
||||
|
||||
;;;###autoload
|
||||
(defun +default/find-in-config ()
|
||||
"Open a file somewhere in `doom-private-dir' via a fuzzy filename search."
|
||||
(interactive)
|
||||
(doom-project-find-file doom-private-dir))
|
||||
|
||||
;;;###autoload
|
||||
(defun +default/browse-config ()
|
||||
"Browse the files in `doom-private-dir'."
|
||||
(interactive)
|
||||
(doom-project-browse doom-private-dir))
|
||||
|
||||
;;;###autoload
|
||||
(defun +default/compile (arg)
|
||||
"Runs `compile' from the root of the current project.
|
||||
|
@ -230,3 +218,34 @@ possible, or just one char if that's not possible."
|
|||
((doom--backward-delete-whitespace-to-column)))))))
|
||||
;; Otherwise, do simple deletion.
|
||||
((delete-char (- n) killflag))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +default/search-from-cwd (&optional arg)
|
||||
"Conduct a text search in files under the current folder.
|
||||
If prefix ARG is set, prompt for a directory to search from."
|
||||
(interactive "P")
|
||||
(let ((default-directory
|
||||
(if arg
|
||||
(read-directory-name "Switch to project: " default-directory)
|
||||
default-directory)))
|
||||
(call-interactively
|
||||
(cond ((featurep! :completion ivy) #'+ivy/project-search-from-cwd)
|
||||
((featurep! :completion helm) #'+helm/project-search-from-cwd)
|
||||
(#'projectile-grep)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +default/search-project (&optional arg)
|
||||
"Conduct a text search in files under the project root.
|
||||
If prefix ARG is set, prompt for a project to search from."
|
||||
(interactive "P")
|
||||
(let ((default-directory
|
||||
(if arg
|
||||
(if-let* ((projects (projectile-relevant-known-projects)))
|
||||
(completing-read "Switch to project: " projects
|
||||
nil t nil nil (doom-project-root))
|
||||
(user-error "There are no known projects"))
|
||||
default-directory)))
|
||||
(call-interactively
|
||||
(cond ((featurep! :completion ivy) #'+ivy/project-search)
|
||||
((featurep! :completion helm) #'+helm/project-search)
|
||||
(#'rgrep)))))
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
;; config/default/autoload/evil.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! :feature evil)
|
||||
|
||||
;;;###autoload (autoload '+default:multi-next-line "config/default/autoload/evil" nil t)
|
||||
(evil-define-motion +default:multi-next-line (count)
|
||||
"Move down 6 lines."
|
||||
:type line
|
||||
(let ((line-move-visual (or visual-line-mode (derived-mode-p 'text-mode 'magit-mode))))
|
||||
(evil-line-move (* 6 (or count 1)))))
|
||||
|
||||
;;;###autoload (autoload '+default:multi-previous-line "config/default/autoload/evil" nil t)
|
||||
(evil-define-motion +default:multi-previous-line (count)
|
||||
"Move up 6 lines."
|
||||
:type line
|
||||
(let ((line-move-visual (or visual-line-mode (derived-mode-p 'text-mode 'magit-mode))))
|
||||
(evil-line-move (- (* 6 (or count 1))))))
|
||||
|
||||
;;;###autoload (autoload '+default:cd "config/default/autoload/evil" nil t)
|
||||
(evil-define-command +default:cd ()
|
||||
"Change `default-directory' with `cd'."
|
||||
(interactive "<f>")
|
||||
(cd input))
|
||||
|
||||
;;;###autoload (autoload '+default:kill-all-buffers "config/default/autoload/evil" nil t)
|
||||
(evil-define-command +default:kill-all-buffers (&optional bang)
|
||||
"Kill all buffers. If BANG, kill current session too."
|
||||
(interactive "<!>")
|
||||
(if bang
|
||||
(+workspace/kill-session)
|
||||
(doom/kill-all-buffers)))
|
||||
|
||||
;;;###autoload (autoload '+default:kill-matching-buffers "config/default/autoload/evil" nil t)
|
||||
(evil-define-command +default:kill-matching-buffers (&optional bang pattern)
|
||||
"Kill all buffers matching PATTERN regexp. If BANG, only match project
|
||||
buffers."
|
||||
(interactive "<a>")
|
||||
(doom/kill-matching-buffers pattern bang))
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
|
||||
;;
|
||||
;; Reasonable defaults
|
||||
;;; Reasonable defaults
|
||||
|
||||
(after! epa
|
||||
(setq epa-file-encrypt-to
|
||||
|
@ -27,113 +27,12 @@
|
|||
epa-pinentry-mode 'loopback))
|
||||
|
||||
|
||||
(when (featurep! +smartparens)
|
||||
;; You can disable :unless predicates with (sp-pair "'" nil :unless nil)
|
||||
;; And disable :post-handlers with (sp-pair "{" nil :post-handlers nil)
|
||||
;; or specific :post-handlers with:
|
||||
;; (sp-pair "{" nil :post-handlers '(:rem ("| " "SPC")))
|
||||
(after! smartparens
|
||||
;; Autopair quotes more conservatively; if I'm next to a word/before another
|
||||
;; quote, I likely don't want to open a new pair.
|
||||
(let ((unless-list '(sp-point-before-word-p
|
||||
sp-point-after-word-p
|
||||
sp-point-before-same-p)))
|
||||
(sp-pair "'" nil :unless unless-list)
|
||||
(sp-pair "\"" nil :unless unless-list))
|
||||
|
||||
;; Expand {|} => { | }
|
||||
;; Expand {|} => {
|
||||
;; |
|
||||
;; }
|
||||
(dolist (brace '("(" "{" "["))
|
||||
(sp-pair brace nil
|
||||
:post-handlers '(("||\n[i]" "RET") ("| " "SPC"))
|
||||
;; I likely don't want a new pair if adjacent to a word or opening brace
|
||||
:unless '(sp-point-before-word-p sp-point-before-same-p)))
|
||||
|
||||
;; Major-mode specific fixes
|
||||
(sp-local-pair '(ruby-mode enh-ruby-mode) "{" "}"
|
||||
:pre-handlers '(:rem sp-ruby-pre-handler)
|
||||
:post-handlers '(:rem sp-ruby-post-handler))
|
||||
|
||||
;; Don't do square-bracket space-expansion where it doesn't make sense to
|
||||
(sp-local-pair '(emacs-lisp-mode org-mode markdown-mode gfm-mode)
|
||||
"[" nil :post-handlers '(:rem ("| " "SPC")))
|
||||
|
||||
;; Reasonable default pairs for HTML-style comments
|
||||
(sp-local-pair (append sp--html-modes '(markdown-mode gfm-mode))
|
||||
"<!--" "-->" :actions '(insert) :post-handlers '(("| " "SPC")))
|
||||
|
||||
;; Disable electric keys in C modes because it interferes with smartparens
|
||||
;; and custom bindings. We'll do it ourselves (mostly).
|
||||
(after! cc-mode
|
||||
(c-toggle-electric-state -1)
|
||||
(c-toggle-auto-newline -1)
|
||||
(setq c-tab-always-indent nil
|
||||
c-electric-flag nil)
|
||||
(dolist (key '("#" "{" "}" "/" "*" ";" "," ":" "(" ")" "\177"))
|
||||
(define-key c-mode-base-map key nil)))
|
||||
|
||||
;; Expand C-style doc comment blocks. Must be done manually because some of
|
||||
;; these languages use specialized (and deferred) parsers, whose state we
|
||||
;; can't access while smartparens is doing its thing.
|
||||
(defun +default-expand-doc-comment-block (&rest _ignored)
|
||||
(let ((indent (current-indentation)))
|
||||
(newline-and-indent)
|
||||
(save-excursion
|
||||
(newline)
|
||||
(insert (make-string indent 32) " */")
|
||||
(delete-char 2))))
|
||||
(sp-local-pair
|
||||
'(js2-mode typescript-mode rjsx-mode rust-mode c-mode c++-mode objc-mode
|
||||
csharp-mode java-mode php-mode css-mode scss-mode less-css-mode
|
||||
stylus-mode)
|
||||
"/*" "*/"
|
||||
:actions '(insert)
|
||||
:post-handlers '(("| " "SPC") ("|\n*/[i][d-2]" "RET") (+default-expand-doc-comment-block "*")))
|
||||
|
||||
;; Highjacks backspace to:
|
||||
;; a) balance spaces inside brackets/parentheses ( | ) -> (|)
|
||||
;; b) delete space-indented `tab-width' steps at a time
|
||||
;; c) close empty multiline brace blocks in one step:
|
||||
;; {
|
||||
;; |
|
||||
;; }
|
||||
;; becomes {|}
|
||||
;; d) refresh smartparens' :post-handlers, so SPC and RET expansions work
|
||||
;; even after a backspace.
|
||||
;; e) properly delete smartparen pairs when they are encountered, without
|
||||
;; the need for strict mode.
|
||||
;; f) do none of this when inside a string
|
||||
(advice-add #'delete-backward-char :override #'+default*delete-backward-char)
|
||||
|
||||
;; Makes `newline-and-indent' continue comments (and more reliably)
|
||||
(advice-add #'newline-and-indent :around #'+default*newline-indent-and-continue-comments)))
|
||||
|
||||
|
||||
;;
|
||||
;; Keybinding fixes
|
||||
;;; Keybinding fixes
|
||||
|
||||
;; This section is dedicated to "fixing" certain keys so that they behave
|
||||
;; sensibly (and consistently with similar contexts).
|
||||
|
||||
;; Make SPC u SPC u [...] possible (#747)
|
||||
(map! :map universal-argument-map
|
||||
:prefix doom-leader-key "u" #'universal-argument-more
|
||||
:prefix doom-leader-alt-key "u" #'universal-argument-more)
|
||||
|
||||
(defun +default|setup-input-decode-map ()
|
||||
"Ensure TAB and [tab] are treated the same in TTY Emacs."
|
||||
(define-key input-decode-map (kbd "TAB") [tab]))
|
||||
(add-hook 'tty-setup-hook #'+default|setup-input-decode-map)
|
||||
|
||||
;; A Doom convention where C-s on popups and interactive searches will invoke
|
||||
;; ivy/helm for their superior filtering.
|
||||
(define-key! :keymaps +default-minibuffer-maps
|
||||
"C-s" (if (featurep! :completion ivy)
|
||||
#'counsel-minibuffer-history
|
||||
#'helm-minibuffer-history))
|
||||
|
||||
;; Consistently use q to quit windows
|
||||
(after! tabulated-list
|
||||
(define-key tabulated-list-mode-map "q" #'quit-window))
|
||||
|
@ -171,7 +70,7 @@
|
|||
:n "s-/" #'evil-commentary-line
|
||||
:v "s-/" #'evil-commentary
|
||||
:gni [s-return] #'+default/newline-below
|
||||
:gni [s-S-return] #'+default/newline-above
|
||||
:gni [S-s-return] #'+default/newline-above
|
||||
:gi [s-backspace] #'doom/backward-kill-to-bol-and-indent
|
||||
:gi [s-left] #'doom/backward-to-bol-or-indent
|
||||
:gi [s-right] #'doom/forward-to-last-non-comment-or-eol
|
||||
|
@ -181,7 +80,48 @@
|
|||
|
||||
|
||||
;;
|
||||
;; Doom's keybinding scheme
|
||||
;;; Keybind schemes
|
||||
|
||||
;; Custom help keys -- these aren't under `+bindings' because they ought to be
|
||||
;; universal.
|
||||
(map! :map help-map
|
||||
"'" #'describe-char
|
||||
"a" #'apropos ; replaces `apropos-command'
|
||||
"A" #'doom/describe-autodefs
|
||||
"B" #'doom/open-bug-report
|
||||
"C-c" #'describe-coding-system ; replaces `describe-copying' b/c not useful
|
||||
"d" #'doom/describe-module ; replaces `apropos-documentation' b/c `apropos' covers this
|
||||
"D" #'doom/open-manual
|
||||
"E" #'doom/open-vanilla-sandbox
|
||||
"F" #'describe-face ; replaces `Info-got-emacs-command-node' b/c redundant w/ `Info-goto-node'
|
||||
"h" #'doom/describe-symbol ; replaces `view-hello-file' b/c annoying
|
||||
"C-k" #'describe-key-briefly
|
||||
"L" #'global-command-log-mode ; replaces `describe-language-environment' b/c remapped to C-l
|
||||
"C-l" #'describe-language-environment
|
||||
"M" #'doom/describe-active-minor-mode
|
||||
"C-m" #'info-emacs-manual
|
||||
"n" #'doom/open-news ; replaces `view-emacs-news' b/c it's on C-n too
|
||||
"O" #'+lookup/online
|
||||
"p" #'doom/describe-package ; replaces `finder-by-keyword'
|
||||
"P" #'find-library ; replaces `describe-package' b/c redundant w/ `doom/describe-package'
|
||||
"r" nil ; replaces `info-emacs-manual' b/c it's on C-m now
|
||||
(:prefix "r"
|
||||
"r" #'doom/reload
|
||||
"t" #'doom/reload-theme
|
||||
"p" #'doom/reload-packages
|
||||
"f" #'doom/reload-font
|
||||
"P" #'doom/reload-project)
|
||||
"T" #'doom/toggle-profiler
|
||||
"V" #'set-variable
|
||||
"C-v" #'doom/version
|
||||
"W" #'+default/man-or-woman)
|
||||
|
||||
(after! which-key
|
||||
(which-key-add-key-based-replacements "C-h r" "reload")
|
||||
(when (featurep 'evil)
|
||||
(which-key-add-key-based-replacements (concat doom-leader-key " r") "reload")
|
||||
(which-key-add-key-based-replacements (concat doom-leader-alt-key " r") "reload")))
|
||||
|
||||
|
||||
(when (featurep! +bindings)
|
||||
;; Make M-x harder to miss
|
||||
|
@ -189,6 +129,13 @@
|
|||
"M-x" #'execute-extended-command
|
||||
"A-x" #'execute-extended-command)
|
||||
|
||||
;; A Doom convention where C-s on popups and interactive searches will invoke
|
||||
;; ivy/helm for their superior filtering.
|
||||
(define-key! :keymaps +default-minibuffer-maps
|
||||
"C-s" (if (featurep! :completion ivy)
|
||||
#'counsel-minibuffer-history
|
||||
#'helm-minibuffer-history))
|
||||
|
||||
;; Smarter C-a/C-e for both Emacs and Evil. C-a will jump to indentation.
|
||||
;; Pressing it again will send you to the true bol. Same goes for C-e, except
|
||||
;; it will ignore comments+trailing whitespace before jumping to eol.
|
||||
|
@ -199,8 +146,12 @@
|
|||
:gni [M-return] #'+default/newline-below
|
||||
:gni [M-S-return] #'+default/newline-above
|
||||
:gni [C-return] #'+default/newline-below
|
||||
:gni [C-S-return] #'+default/newline-above)
|
||||
:gni [C-S-return] #'+default/newline-above))
|
||||
|
||||
(if (featurep 'evil)
|
||||
(load! "+evil-bindings")
|
||||
(load! "+emacs-bindings")))
|
||||
|
||||
;;
|
||||
;;; Bootstrap configs
|
||||
|
||||
(if (featurep 'evil)
|
||||
(load! "+evil")
|
||||
(load! "+emacs"))
|
||||
|
|
6
modules/config/default/packages.el
Normal file
6
modules/config/default/packages.el
Normal file
|
@ -0,0 +1,6 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; config/default/packages.el
|
||||
|
||||
(unless (featurep! :feature evil)
|
||||
(package! winum)
|
||||
(package! expand-region))
|
|
@ -45,11 +45,11 @@ Targets `vimmish-fold', `hideshow' and `outline' folds."
|
|||
(interactive)
|
||||
(save-excursion
|
||||
(cond ((+fold--vimish-fold-p) (vimish-fold-toggle))
|
||||
((+fold--hideshow-fold-p) (+fold-from-eol (hs-toggle-hiding)))
|
||||
((+fold--outline-fold-p)
|
||||
(cl-letf (((symbol-function #'outline-hide-subtree)
|
||||
(symbol-function #'outline-hide-entry)))
|
||||
(outline-toggle-children))))))
|
||||
(outline-toggle-children)))
|
||||
((+fold--hideshow-fold-p) (+fold-from-eol (hs-toggle-hiding))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +fold/open ()
|
||||
|
@ -59,10 +59,10 @@ Targets `vimmish-fold', `hideshow' and `outline' folds."
|
|||
(interactive)
|
||||
(save-excursion
|
||||
(cond ((+fold--vimish-fold-p) (vimish-fold-unfold))
|
||||
((+fold--hideshow-fold-p) (+fold-from-eol (hs-show-block)))
|
||||
((+fold--outline-fold-p)
|
||||
(outline-show-children)
|
||||
(outline-show-entry)))))
|
||||
(outline-show-entry))
|
||||
((+fold--hideshow-fold-p) (+fold-from-eol (hs-show-block))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +fold/close ()
|
||||
|
|
|
@ -34,16 +34,14 @@
|
|||
(insert input)
|
||||
(condition-case e
|
||||
(progn
|
||||
(when doom-debug-mode
|
||||
(message "formatter (commandp) %s" #',formatter))
|
||||
(doom-log "formatter (commandp) %s" #',formatter)
|
||||
(call-interactively #',formatter)
|
||||
(list nil ""))
|
||||
(error (list t (error-message-string e))))))))
|
||||
|
||||
(defun +format--make-function (formatter &rest _)
|
||||
`(progn
|
||||
(when doom-debug-mode
|
||||
(message "formatter (functionp) %s" #',formatter))
|
||||
(doom-log "formatter (functionp) %s" #',formatter)
|
||||
(format-all-buffer-thunk #',formatter)))
|
||||
|
||||
(defun +format--make-shell-command (command ok-statuses error-regexp)
|
||||
|
@ -66,8 +64,7 @@
|
|||
((stringp this)
|
||||
(push this subargs))))
|
||||
(setq args (append subargs args)))))))
|
||||
(when doom-debug-mode
|
||||
(message "formatter (arglist) %s" args))
|
||||
(doom-log "formatter (arglist) %s" args)
|
||||
(if ,(and (or ok-statuses error-regexp) t)
|
||||
(apply #'format-all-buffer-hard
|
||||
',ok-statuses ,error-regexp
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
(defvar evil-mc-key-map (make-sparse-keymap))
|
||||
:config
|
||||
(global-evil-mc-mode +1)
|
||||
(setq evil-mc-enable-bar-cursor (not (or IS-MAC IS-WINDOWS)))
|
||||
|
||||
(after! smartparens
|
||||
;; Make evil-mc cooperate with smartparens better
|
||||
|
@ -56,7 +57,7 @@
|
|||
:evil-mc t))
|
||||
|
||||
|
||||
(after! multiple-cursors
|
||||
(after! multiple-cursors-core
|
||||
(setq mc/list-file (concat doom-etc-dir "mc-lists.el"))
|
||||
|
||||
;; TODO multiple-cursors config for Emacs users?
|
||||
|
|
|
@ -17,17 +17,18 @@
|
|||
image-dired-temp-image-file (concat image-dired-dir "temp-image")
|
||||
image-dired-temp-rotate-image-file (concat image-dired-dir "temp-rotate-image"))
|
||||
:config
|
||||
(setq dired-listing-switches "-aBhl --group-directories-first")
|
||||
|
||||
(when IS-BSD
|
||||
;; Use GNU ls as `gls' from `coreutils' if available. Add `(setq
|
||||
;; dired-use-ls-dired nil)' to your config to suppress the Dired warning
|
||||
;; when not using GNU ls. We must look for `gls' after
|
||||
;; `exec-path-from-shell' was initialized to make sure that `gls' is in
|
||||
;; `exec-path'
|
||||
(if-let* ((gls (executable-find "gls")))
|
||||
(setq insert-directory-program gls)
|
||||
(message "Cannot find `gls` (GNU ls). Install coreutils via your system package manager")))
|
||||
(let ((args (list "-aBhl" "--group-directories-first")))
|
||||
(when IS-BSD
|
||||
;; Use GNU ls as `gls' from `coreutils' if available. Add `(setq
|
||||
;; dired-use-ls-dired nil)' to your config to suppress the Dired warning
|
||||
;; when not using GNU ls. We must look for `gls' after
|
||||
;; `exec-path-from-shell' was initialized to make sure that `gls' is in
|
||||
;; `exec-path'
|
||||
(if-let* ((gls (executable-find "gls")))
|
||||
(setq insert-directory-program gls)
|
||||
(setq args (delete "--group-directories-first" args))
|
||||
(message "Cannot find `gls` (GNU ls). Install coreutils via your system package manager")))
|
||||
(setq dired-listing-switches (string-join args " ")))
|
||||
|
||||
(defun +dired|sort-directories-first ()
|
||||
"List directories first in dired buffers."
|
||||
|
@ -91,6 +92,7 @@
|
|||
ranger-excluded-extensions '("mkv" "iso" "mp4")
|
||||
ranger-deer-show-details nil
|
||||
ranger-max-preview-size 10
|
||||
ranger-show-literal nil
|
||||
dired-omit-verbose nil))
|
||||
|
||||
|
||||
|
|
|
@ -17,8 +17,10 @@ Enables `electric-indent-local-mode' in MODES.
|
|||
(unintern fn nil))
|
||||
((fset fn
|
||||
(lambda ()
|
||||
(cl-destructuring-bind (&key chars words) plist
|
||||
(electric-indent-local-mode +1)
|
||||
(if chars (setq electric-indent-chars chars))
|
||||
(if words (setq +electric-indent-words words)))))
|
||||
(when (eq major-mode mode)
|
||||
(setq-local electric-indent-inhibit nil)
|
||||
(cl-destructuring-bind (&key chars words) plist
|
||||
(electric-indent-local-mode +1)
|
||||
(if chars (setq electric-indent-chars chars))
|
||||
(if words (setq +electric-indent-words words))))))
|
||||
(add-hook hook fn))))))
|
||||
|
|
|
@ -107,7 +107,7 @@ You should use `det-eshell-alias!' to change this.")
|
|||
;; Visual commands require a proper terminal. Eshell can't handle that, so
|
||||
;; it delegates these commands to a term buffer.
|
||||
(after! em-term
|
||||
(dolist (cmd '("tmux" "htop" "bash" "zsh" "fish" "vim" "nvim" "ncmpcpp"))
|
||||
(dolist (cmd '("tmux" "htop" "vim" "nvim" "ncmpcpp"))
|
||||
(add-to-list 'eshell-visual-commands cmd)))
|
||||
|
||||
(defun +eshell|init-aliases ()
|
||||
|
|
|
@ -17,6 +17,14 @@
|
|||
(funcall runner beg end)
|
||||
(quickrun-region beg end))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +eval/line-or-region ()
|
||||
"Evaluate the current line or selected region."
|
||||
(interactive)
|
||||
(if (use-region-p)
|
||||
(call-interactively #'+eval/region)
|
||||
(+eval/region (line-beginning-position) (line-end-position))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +eval/buffer-or-region ()
|
||||
"Evaluate the whole buffer."
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
;;; feature/evil/+commands.el -*- lexical-binding: t; -*-
|
||||
|
||||
(evil-define-command +evil:cleanup-session (bang)
|
||||
(interactive "<!>")
|
||||
(doom/cleanup-session bang))
|
||||
|
||||
(evil-define-operator +evil:open-scratch-buffer (bang)
|
||||
(interactive "<!>")
|
||||
(doom/open-scratch-buffer bang))
|
||||
|
@ -46,14 +42,30 @@ This command understands vim file modifiers (like %:p:h). See
|
|||
(interactive "<r>")
|
||||
(reverse-region beg end))
|
||||
|
||||
(evil-define-command +evil:cd (&optional path)
|
||||
"Change `default-directory' with `cd'."
|
||||
(interactive "<f>")
|
||||
(let ((path (or path "~")))
|
||||
(cd path)
|
||||
(message "Changed directory to '%s'" (abbreviate-file-name (expand-file-name path)))))
|
||||
|
||||
(evil-define-command +evil:kill-all-buffers (&optional bang)
|
||||
"Kill all buffers. If BANG, kill current session too."
|
||||
(interactive "<!>")
|
||||
(if (and bang (fboundp '+workspace/kill-session))
|
||||
(+workspace/kill-session)
|
||||
(doom/kill-all-buffers)))
|
||||
|
||||
(evil-define-command +evil:kill-matching-buffers (&optional bang pattern)
|
||||
"Kill all buffers matching PATTERN regexp. If BANG, only match project
|
||||
buffers."
|
||||
(interactive "<a>")
|
||||
(doom/kill-matching-buffers pattern bang))
|
||||
|
||||
|
||||
;;
|
||||
;; Commands
|
||||
|
||||
;;; these are defined in feature/evil
|
||||
;;(evil-ex-define-cmd "al[ign]" #'+evil:align)
|
||||
;;(evil-ex-define-cmd "g[lobal]" #'+evil:global)
|
||||
|
||||
;;; Custom commands
|
||||
;; Editing
|
||||
(evil-ex-define-cmd "@" #'+evil:macro-on-all-lines) ; TODO Test me
|
||||
|
@ -94,18 +106,18 @@ This command understands vim file modifiers (like %:p:h). See
|
|||
(evil-ex-define-cmd "grevert" #'git-gutter:revert-hunk)
|
||||
|
||||
;;; Dealing with buffers
|
||||
(evil-ex-define-cmd "clean[up]" #'+evil:cleanup-session)
|
||||
(evil-ex-define-cmd "k[ill]" #'doom/kill-this-buffer)
|
||||
(evil-ex-define-cmd "k[ill]all" #'+default:kill-all-buffers)
|
||||
(evil-ex-define-cmd "k[ill]m" #'+default:kill-matching-buffers)
|
||||
(evil-ex-define-cmd "k[ill]all" #'+evil:kill-all-buffers)
|
||||
(evil-ex-define-cmd "k[ill]m" #'+evil:kill-matching-buffers)
|
||||
(evil-ex-define-cmd "k[ill]o" #'doom/kill-other-buffers)
|
||||
(evil-ex-define-cmd "k[ill]b" #'doom/kill-buried-buffers)
|
||||
(evil-ex-define-cmd "l[ast]" #'doom/popup-restore)
|
||||
(evil-ex-define-cmd "m[sg]" #'view-echo-area-messages)
|
||||
(evil-ex-define-cmd "pop[up]" #'doom/popup-this-buffer)
|
||||
|
||||
;;; Project navigation
|
||||
(evil-ex-define-cmd "a" #'projectile-find-other-file)
|
||||
(evil-ex-define-cmd "cd" #'+default:cd)
|
||||
(evil-ex-define-cmd "cd" #'+evil:cd)
|
||||
(evil-ex-define-cmd "pwd" #'+evil:pwd)
|
||||
|
||||
(cond ((featurep! :completion ivy)
|
||||
|
@ -135,7 +147,7 @@ This command understands vim file modifiers (like %:p:h). See
|
|||
;;; Project tools
|
||||
(evil-ex-define-cmd "compile" #'+evil:compile)
|
||||
(evil-ex-define-cmd "mak[e]" #'+evil:make)
|
||||
(evil-ex-define-cmd "debug" #'+debug/run)
|
||||
;; (evil-ex-define-cmd "debug" #'+debug/run)
|
||||
(evil-ex-define-cmd "er[rors]" #'flycheck-list-errors)
|
||||
|
||||
;;; File operations
|
||||
|
@ -145,8 +157,8 @@ This command understands vim file modifiers (like %:p:h). See
|
|||
|
||||
;;; Sessions/tabs
|
||||
(evil-ex-define-cmd "sclear" #'+workspace/kill-session)
|
||||
(evil-ex-define-cmd "sl[oad]" #'+workspace:load-session)
|
||||
(evil-ex-define-cmd "ss[ave]" #'+workspace:save-session)
|
||||
(evil-ex-define-cmd "sl[oad]" #'doom/quickload-session)
|
||||
(evil-ex-define-cmd "ss[ave]" #'doom/quicksave-session)
|
||||
(evil-ex-define-cmd "tabc[lose]" #'+workspace:delete)
|
||||
(evil-ex-define-cmd "tabclear" #'doom/kill-all-buffers)
|
||||
(evil-ex-define-cmd "tabl[ast]" #'+workspace/switch-to-last)
|
||||
|
|
|
@ -163,8 +163,7 @@ variable for an explanation of the defaults (in comments). See
|
|||
|
||||
(defun +evil-collection-init (module)
|
||||
(unless (memq (or (car-safe module) module) +evil-collection-disabled-list)
|
||||
(when doom-debug-mode
|
||||
(message "Loaded evil-collection-%s" (or (car-safe module) module)))
|
||||
(doom-log "Initialized evil-collection-%s" (or (car-safe module) module))
|
||||
(with-demoted-errors "evil-collection error: %s"
|
||||
(evil-collection-init (list module)))))
|
||||
|
||||
|
@ -195,6 +194,10 @@ variable for an explanation of the defaults (in comments). See
|
|||
"]l" #'forward-button
|
||||
"[l" #'backward-button))
|
||||
|
||||
(evil-define-key* 'normal process-menu-mode-map
|
||||
"q" #'kill-this-buffer
|
||||
"d" #'process-menu-delete-process)
|
||||
|
||||
;; Load the rest
|
||||
(dolist (mode evil-collection-mode-list)
|
||||
(dolist (req (or (cdr-safe mode) (list mode)))
|
||||
|
|
|
@ -4,26 +4,25 @@
|
|||
#+STARTUP: inlineimages
|
||||
|
||||
* Table of Contents :TOC_3:noexport:
|
||||
- [[Description][Description]]
|
||||
- [[Module Flags][Module Flags]]
|
||||
- [[Plugins][Plugins]]
|
||||
- [[Hacks][Hacks]]
|
||||
- [[Prerequisites][Prerequisites]]
|
||||
- [[Features][Features]]
|
||||
- [[Ported vim plugins][Ported vim plugins]]
|
||||
- [[Custom Text Objects][Custom Text Objects]]
|
||||
- [[Custom Ex Commands][Custom Ex Commands]]
|
||||
- [[A hybrid code-folding system][A hybrid code-folding system]]
|
||||
- [[Differences from vim][Differences from vim]]
|
||||
- [[Configuration][Configuration]]
|
||||
- [[Removing evil-mode][Removing evil-mode]]
|
||||
- [[#description][Description]]
|
||||
- [[#module-flags][Module Flags]]
|
||||
- [[#plugins][Plugins]]
|
||||
- [[#hacks][Hacks]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#features][Features]]
|
||||
- [[#ported-vim-plugins][Ported vim plugins]]
|
||||
- [[#custom-text-objects][Custom Text Objects]]
|
||||
- [[#custom-ex-commands][Custom Ex Commands]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#removing-evil-mode][Removing evil-mode]]
|
||||
- [[#restoring-old-substitution-behavior-on-ss][Restoring old substitution behavior on s/S]]
|
||||
|
||||
* Description
|
||||
This holy module brings the vim experience to Emacs.
|
||||
|
||||
** Module Flags
|
||||
+ =+everywhere= Enables evilified keybinds everywhere possible, utilizing the
|
||||
~evil-collection~ plugin.
|
||||
+ =+everywhere= Enables evilified keybinds everywhere possible. Uses the
|
||||
[[https://github.com/emacs-evil/evil-collection][evil-collection]] plugin as a foundation.
|
||||
|
||||
** Plugins
|
||||
+ [[https://github.com/emacs-evil/evil][evil]]
|
||||
|
@ -48,10 +47,9 @@ This holy module brings the vim experience to Emacs.
|
|||
+ When a window is split, the new window will be focused.
|
||||
+ The o/O keys will respect and continue commented lines (can be disabled by
|
||||
setting ~+evil-want-o/O-to-continue-comments~ to ~nil~).
|
||||
+ From visual mode, =*= and =#= will search for the current selection instead of
|
||||
+ In visual mode, =*= and =#= will search for the current selection instead of
|
||||
the word-at-point.
|
||||
+ The ~:g[lobal]~ ex command has been modified to highlight matches
|
||||
incrementally.
|
||||
+ The ~:g[lobal]~ ex command has been modified to highlight matches.
|
||||
+ More of vim's filename modifiers are supported in ex commands (like ~:p~,
|
||||
~:p:h~ or ~:t~) than vanilla evil-mode offers.
|
||||
+ A custom filename modifier is available in Doom: ~:P~, which expands to the
|
||||
|
@ -64,64 +62,115 @@ This module has no external prerequisites.
|
|||
** Ported vim plugins
|
||||
The following vim plugins have been ported to evil:
|
||||
|
||||
| Vim Plugin | Emacs Plugin | Keybind(s) |
|
||||
|-----------------------+--------------------------------+---------------------|
|
||||
| vim-commentary | evil-commentary | omap =gc= |
|
||||
| vim-easymotion | evil-easymotion | omap =gs= |
|
||||
| vim-seek or vim-sneak | evil-snipe | mmap =s=/=S= |
|
||||
| vim-surround | evil-embrace and evil-surround | vmap =S=, omap =ys= |
|
||||
| Vim Plugin | Emacs Plugin | Keybind(s) |
|
||||
|-----------------------+--------------------------------+--------------------------------------|
|
||||
| vim-commentary | evil-commentary | omap =gc= |
|
||||
| vim-easymotion | evil-easymotion | omap =gs= |
|
||||
| vim-seek or vim-sneak | evil-snipe | mmap =s=/=S=, omap =z=/=Z= & =x=/=x= |
|
||||
| vim-surround | evil-embrace and evil-surround | vmap =S=, omap =ys= |
|
||||
|
||||
In other modules:
|
||||
+ The tools/neotree & tools/treemacs modules contain a =NERDTree= equivalent.
|
||||
+ The editor/multiple-cursors module contains:
|
||||
+ ~vim-multiedit~ => evil-multiedit
|
||||
+ ~vim-multiple-cursors~ => evil-mc
|
||||
+ The tools/neotree & tools/treemacs modules provide a =NERDTree= equivalent.
|
||||
+ The editor/multiple-cursors module contains functionality equal to the
|
||||
following vim plugins:
|
||||
+ evil-multiedit => vim-multiedit
|
||||
+ evil-mc => vim-multiple-cursors
|
||||
|
||||
** Custom Text Objects
|
||||
+ A list of new text objects:
|
||||
+ Blocks: ~B~ (from ~evil-textobj-anyblock~)
|
||||
+ Args: ~a~ (from ~evil-args~)
|
||||
+ Indentation: ~i~ / ~I~ / ~J~ (from ~evil-indent-plus~)
|
||||
This module provides a couple extra text objects, along with the built-in ones.
|
||||
For posterity, here are the built-in ones:
|
||||
|
||||
+ =w W= words
|
||||
+ =s= sentences
|
||||
+ =p= paragraphs
|
||||
+ =b= parenthesized blocks
|
||||
+ =b ( ) { } [ ] < >= braces, parentheses and brackets
|
||||
+ =' " `= quotes
|
||||
+ =t= tags
|
||||
+ =o= symbols
|
||||
|
||||
And these are text objects added by this module:
|
||||
|
||||
+ =B= any block delimited by braces, parentheses or backets (provided by
|
||||
~evil-textobj-anyblock~)
|
||||
+ =a= C-style fucntion arguments (provided by ~evil-args~)
|
||||
+ =i I J= By indentation (I includes on line above and J includes one line
|
||||
below) (provided by ~evil-indent-plus~)
|
||||
+ =x= XML attributes (provided by ~exato~)
|
||||
|
||||
** Custom Ex Commands
|
||||
| Ex Command | Description |
|
||||
|----------------------+----------------------------------------------------------------------------------|
|
||||
| ~:al[ign][!] REGEXP~ | Align text to the first match of REGEXP. If BANG, align all matches on each line |
|
||||
| ~:mv[!] NEWPATH~ | Move the current file to NEWPATH |
|
||||
| ~:cp[!] NEWPATH~ | Copy the current file to NEWPATH |
|
||||
| ~:rm[!] [PATH]~ | Delete the current buffer's file and buffer |
|
||||
|
||||
** A hybrid code-folding system
|
||||
This module combines ~vimish-fold~ and ~hideshow~. The former allows arbitrary
|
||||
folds and the latter allows folds on markers and indentation. Together, they
|
||||
create a more consistent (and feature-complete) code-folding system.
|
||||
|
||||
Most vim folding keys should work, e.g. =zr=, =zm=, =za=, =zo=, etc.
|
||||
|
||||
** Differences from vim
|
||||
+ Column-wise ranges in ex commands are enabled by default. i.e. the range in
|
||||
=:'<,'>s/a/b= will only affects the visual selection, not full lines (see
|
||||
~evil-ex-visual-char-range~).
|
||||
+ =:g= will incrementally highlight buffer matches.
|
||||
| Ex Command | Description |
|
||||
|----------------------+--------------------------------------------------------------------------------------|
|
||||
| ~:@~ | Apply macro on selected lines |
|
||||
| ~:ag[!] REGEXP~ | Perform a project search with ag |
|
||||
| ~:agcwd[!] REGEXP~ | Perform a project search with ag |
|
||||
| ~:al[ign] REGEXP~ | Align text that matches REGEXP |
|
||||
| ~:al[ign][!] REGEXP~ | Align text to the first match of REGEXP. If BANG, align all matches on each line |
|
||||
| ~:cp[!] NEWPATH~ | Copy the current file to NEWPATH |
|
||||
| ~:dash QUERY~ | Look up QUERY (or the symbol at point) in dash docsets |
|
||||
| ~:dehtml [INPUT]~ | HTML decode selected text / inserts result if INPUT is given |
|
||||
| ~:enhtml [INPUT]~ | HTML encode selected text / inserts result if INPUT is given |
|
||||
| ~:grep[!]~ | Perform a project search with git-grep |
|
||||
| ~:grepcwd[!]~ | Perform a project search with git-grep |
|
||||
| ~:iedit REGEXP~ | Invoke iedit on all matches for REGEXP |
|
||||
| ~:k[ill]all[!]~ | Kill all buffers (if BANG, affect buffer across workspaces) |
|
||||
| ~:k[ill]b~ | Kill all buried buffers |
|
||||
| ~:k[ill]m[!] REGEXP~ | Kill buffers whose name matches REGEXP (if BANG, affect buffers across workspaces) |
|
||||
| ~:k[ill]o~ | Kill all other buffers besides the selected one |
|
||||
| ~:k[ill]~ | Kill the current buffer |
|
||||
| ~:lo[okup] QUERY~ | Look up QUERY on an online search engine |
|
||||
| ~:mc REGEXP~ | Invoke multiple cursors on all matches for REGEXP |
|
||||
| ~:mv[!] NEWPATH~ | Move the current file to NEWPATH |
|
||||
| ~:na[rrow]~ | Narrow the buffer to the selection |
|
||||
| ~:pad~ | Open a scratch pad for running code quickly |
|
||||
| ~:pt[!]~ | Perform a project search with pt |
|
||||
| ~:ptcwd[!]~ | Perform a project search with pt |
|
||||
| ~:ral[ign] REGEXP~ | Right-align text that matches REGEXP |
|
||||
| ~:repl~ | Open a REPL and/or copy the current selection to it |
|
||||
| ~:retab~ | Convert indentation to the default within the selection |
|
||||
| ~:rev[erse]~ | Reverse the selected lines |
|
||||
| ~:rg[!]~ | Perform a project search with ripgrep |
|
||||
| ~:rgcwd[!]~ | Perform a project search with rigprep |
|
||||
| ~:rm[!] [PATH]~ | Delete the current buffer's file and buffer |
|
||||
| ~:tcd[!]~ | Send =cd X= to tmux. X = the project root if BANG, X = ~default-directory~ otherwise |
|
||||
|
||||
* Configuration
|
||||
** Removing evil-mode
|
||||
You must do two things to remove Evil:
|
||||
|
||||
1. Remove =:feature evil= from =~/.doom.d/init.el=,
|
||||
2. Run ~bin/doom refresh~ to clean up lingering dependencies and refresh yuor
|
||||
2. Run ~doom refresh~ to clean up lingering dependencies and refresh yuor
|
||||
autoloads files.
|
||||
3. [OPTIONAL] You may want a new ~doom-leader-alt-key~ and
|
||||
~doom-localleader-alt-key~. By default, these are bound to =M-SPC= and =M-SPC
|
||||
m=.
|
||||
3. [OPTIONAL] You may want to assign new values to ~doom-leader-alt-key~ and
|
||||
~doom-localleader-alt-key~. These are bound to =C-c= and =C-c l= by default.
|
||||
|
||||
#+begin_quote
|
||||
Ignore ~doom-leader-key~ and ~doom-localleader-key~, they don't apply to
|
||||
non-evil sessions.
|
||||
#+end_quote
|
||||
|
||||
Note that evil-specific configuration and keybinds (defined with ~map!~) will be
|
||||
ignored without evil present (and stripped out when byte-compiling).
|
||||
Evil-specific configuration and keybindings (defined with ~map!~) will be
|
||||
ignored without =:feature evil= present (and omitted when byte-compiling).
|
||||
|
||||
Unfortunately, since Doom was designed by a vimmer, for vimmers, little
|
||||
consideration into a keybinding scheme for vanilla Emacs users.
|
||||
Keep in mind that, at the time of this writing, Doom was designed by a vimmer,
|
||||
for vimmers. Little consideration has been put into designing a keybind scheme
|
||||
for vanilla Emacs users (though it's being worked on!).
|
||||
|
||||
That means that much of Doom's functionality will be orphaned in an evil-less
|
||||
setup. You'll have to set your own keybinds.
|
||||
|
||||
I suggest studying [[file:../../config/default/+emacs-bindings.el][config/default/+emacs-bindings.el]] to see what keybinds are
|
||||
available for non-evil users. Otherwise, you may find inspiration [[file:../../../docs/example_configs.org][on the example
|
||||
Doom configurations page]].
|
||||
|
||||
** Restoring old substitution behavior on s/S
|
||||
Doom replaces the =s= and =S= keys with the =evil-snipe= package (a port of
|
||||
vim-seek/vim-sneak for 2-character versions of f/F/t/T).
|
||||
|
||||
To disable evil-snipe on s/S, you can either:
|
||||
|
||||
1. Disable ~evil-snipe-mode~ by adding ~(after! evil-snipe (evil-snipe-mode
|
||||
-1))~ to =$DOOMDIR/config.el=,
|
||||
2. Or disable =evil-snipe= completely with ~(package! evil-snipe :disable t)~
|
||||
added to =$DOOMDIR/packages.el=, but this will also disable incremental
|
||||
highlighting for the f/F/t/T motions keys.
|
||||
|
|
|
@ -185,3 +185,23 @@ more information on modifiers."
|
|||
"Call `doom/escape' if `evil-force-normal-state' is called interactively."
|
||||
(when (called-interactively-p 'any)
|
||||
(call-interactively #'doom/escape)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil*make-numbered-markers-global (orig-fn char)
|
||||
(or (and (>= char ?2) (<= char ?9))
|
||||
(funcall orig-fn char)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil*set-jump (orig-fn &rest args)
|
||||
"Set a jump point and ensure ORIG-FN doesn't set any new jump points."
|
||||
(evil-set-jump (if (markerp (car args)) (car args)))
|
||||
(let ((evil--jumps-jumping t))
|
||||
(apply orig-fn args)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil*fix-dabbrev-in-minibuffer ()
|
||||
"Make `try-expand-dabbrev' from `hippie-expand' work in minibuffer. See
|
||||
`he-dabbrev-beg', so we need to redefine syntax for '/'."
|
||||
(set-syntax-table (let* ((table (make-syntax-table)))
|
||||
(modify-syntax-entry ?/ "." table)
|
||||
table)))
|
||||
|
|
33
modules/feature/evil/autoload/embrace.el
Normal file
33
modules/feature/evil/autoload/embrace.el
Normal file
|
@ -0,0 +1,33 @@
|
|||
;;; feature/evil/autoload/embrace.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil--embrace-get-pair (char)
|
||||
(if-let* ((pair (cdr-safe (assoc (string-to-char char) evil-surround-pairs-alist))))
|
||||
pair
|
||||
(if-let* ((pair (assoc-default char embrace--pairs-list)))
|
||||
(if-let* ((real-pair (and (functionp (embrace-pair-struct-read-function pair))
|
||||
(funcall (embrace-pair-struct-read-function pair)))))
|
||||
real-pair
|
||||
(cons (embrace-pair-struct-left pair) (embrace-pair-struct-right pair)))
|
||||
(cons char char))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil--embrace-escaped ()
|
||||
"Backslash-escaped surround character support for embrace."
|
||||
(let ((char (read-char "\\")))
|
||||
(if (eq char 27)
|
||||
(cons "" "")
|
||||
(let ((pair (+evil--embrace-get-pair (string char)))
|
||||
(text (if (sp-point-in-string) "\\\\%s" "\\%s")))
|
||||
(cons (format text (car pair))
|
||||
(format text (cdr pair)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil--embrace-latex ()
|
||||
"LaTeX command support for embrace."
|
||||
(cons (format "\\%s{" (read-string "\\")) "}"))
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil--embrace-elisp-fn ()
|
||||
"Elisp function support for embrace."
|
||||
(cons (format "(%s " (or (read-string "(") "")) ")"))
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
|
||||
;;
|
||||
;; Commands
|
||||
;;; Commands
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil/visual-indent ()
|
||||
|
@ -50,10 +50,10 @@
|
|||
(call-interactively #'evil-paste-after)))
|
||||
|
||||
(defun +evil--window-swap (direction)
|
||||
"Move current window to the next window in DIRECTION. If there are no windows
|
||||
there and there is only one window, split in that direction and place this
|
||||
window there. If there are no windows and this isn't the only window, use
|
||||
evil-window-move-* (e.g. `evil-window-move-far-left')"
|
||||
"Move current window to the next window in DIRECTION.
|
||||
If there are no windows there and there is only one window, split in that
|
||||
direction and place this window there. If there are no windows and this isn't
|
||||
the only window, use evil-window-move-* (e.g. `evil-window-move-far-left')."
|
||||
(when (window-dedicated-p)
|
||||
(user-error "Cannot swap a dedicated window"))
|
||||
(let* ((this-window (selected-window))
|
||||
|
@ -111,7 +111,7 @@ integration."
|
|||
|
||||
|
||||
;;
|
||||
;; Evil commands/operators
|
||||
;;; Evil commands/operators
|
||||
|
||||
;;;###autoload (autoload '+evil:apply-macro "feature/evil/autoload/evil" nil t)
|
||||
(evil-define-operator +evil:apply-macro (beg end)
|
||||
|
@ -154,7 +154,8 @@ integration."
|
|||
(doom/clone-and-narrow-buffer beg end bang))
|
||||
|
||||
|
||||
;; --- custom arg handlers ----------------
|
||||
;;
|
||||
;;; Custom arg handlers
|
||||
|
||||
(defvar +evil--flag nil)
|
||||
|
||||
|
@ -241,7 +242,8 @@ the first match on each line)."
|
|||
-1 1 bang))
|
||||
|
||||
|
||||
;; --- wgrep ------------------------------
|
||||
;;
|
||||
;;; wgrep
|
||||
|
||||
;;;###autoload (autoload '+evil-delete "feature/evil/autoload/evil" nil t)
|
||||
(evil-define-operator +evil-delete (beg end type register yank-handler)
|
||||
|
|
|
@ -14,7 +14,9 @@ line with a linewise comment.")
|
|||
(defvar evil-want-Y-yank-to-eol t)
|
||||
|
||||
(def-package! evil
|
||||
:init
|
||||
:hook (doom-init-modules . evil-mode)
|
||||
:demand t
|
||||
:preface
|
||||
(setq evil-want-visual-char-semi-exclusive t
|
||||
evil-magic t
|
||||
evil-echo-state t
|
||||
|
@ -27,8 +29,6 @@ line with a linewise comment.")
|
|||
evil-respect-visual-line-mode t
|
||||
;; more vim-like behavior
|
||||
evil-symbol-word-search t
|
||||
;; don't activate mark on shift-click
|
||||
shift-select-mode nil
|
||||
;; cursor appearance
|
||||
evil-default-cursor '+evil-default-cursor
|
||||
evil-normal-state-cursor 'box
|
||||
|
@ -39,18 +39,16 @@ line with a linewise comment.")
|
|||
evil-want-keybinding (not (featurep! +everywhere)))
|
||||
|
||||
:config
|
||||
(load! "+commands")
|
||||
|
||||
(add-hook 'doom-post-init-hook #'evil-mode)
|
||||
(evil-select-search-module 'evil-search-module 'evil-search)
|
||||
|
||||
(put 'evil-define-key* 'lisp-indent-function 'defun)
|
||||
|
||||
;; Done in a hook to ensure the popup rules load as late as possible
|
||||
(defun +evil|init-popup-rules ()
|
||||
(set-popup-rules!
|
||||
'(("^\\*evil-registers" :size 0.3)
|
||||
("^\\*Command Line" :size 8))))
|
||||
(add-hook 'doom-post-init-hook #'+evil|init-popup-rules)
|
||||
(add-hook 'doom-init-modules-hook #'+evil|init-popup-rules)
|
||||
|
||||
;; Change the cursor color in emacs mode
|
||||
(defvar +evil--default-cursor-color
|
||||
|
@ -104,12 +102,7 @@ line with a linewise comment.")
|
|||
;; and one custom one: %:P (expand to the project root).
|
||||
(advice-add #'evil-ex-replace-special-filenames :override #'+evil*resolve-vim-path)
|
||||
|
||||
;; make `try-expand-dabbrev' from `hippie-expand' work in minibuffer. See
|
||||
;; `he-dabbrev-beg', so we need to redefine syntax for '/'
|
||||
(defun +evil*fix-dabbrev-in-minibuffer ()
|
||||
(set-syntax-table (let* ((table (make-syntax-table)))
|
||||
(modify-syntax-entry ?/ "." table)
|
||||
table)))
|
||||
;; make `try-expand-dabbrev' (from `hippie-expand') work in minibuffer
|
||||
(add-hook 'minibuffer-inactive-mode-hook #'+evil*fix-dabbrev-in-minibuffer)
|
||||
|
||||
;; Focus and recenter new splits
|
||||
|
@ -117,25 +110,26 @@ line with a linewise comment.")
|
|||
(advice-add #'evil-window-vsplit :override #'+evil*window-vsplit)
|
||||
|
||||
;; Integrate evil's jump-list into some navigational commands
|
||||
(defun +evil*set-jump (orig-fn &rest args)
|
||||
"Set a jump point and ensure ORIG-FN doesn't set any new jump points."
|
||||
(evil-set-jump (if (markerp (car args)) (car args)))
|
||||
(let ((evil--jumps-jumping t))
|
||||
(apply orig-fn args)))
|
||||
(advice-add #'counsel-git-grep-action :around #'+evil*set-jump)
|
||||
(advice-add #'helm-ag--find-file-action :around #'+evil*set-jump)
|
||||
(advice-add #'xref-push-marker-stack :around #'+evil*set-jump)
|
||||
|
||||
;; In evil, registers 2-9 are buffer-local. In vim, they're global, so...
|
||||
(defun +evil*make-numbered-markers-global (orig-fn char)
|
||||
(or (and (>= char ?2) (<= char ?9))
|
||||
(funcall orig-fn char)))
|
||||
(advice-add #'evil-global-marker-p :around #'+evil*make-numbered-markers-global)
|
||||
|
||||
;; Make o/O continue comments (see `+evil-want-o/O-to-continue-comments')
|
||||
(advice-add #'evil-open-above :around #'+evil*insert-newline-above-and-respect-comments)
|
||||
(advice-add #'evil-open-below :around #'+evil*insert-newline-below-and-respect-comments)
|
||||
|
||||
;; Recenter screen after most searches
|
||||
(advice-add! '(evil-visualstar/begin-search-forward
|
||||
evil-visualstar/begin-search-backward
|
||||
evil-ex-search-word-backward
|
||||
evil-ex-search-word-backward
|
||||
evil-ex-search-forward
|
||||
evil-ex-search-backward)
|
||||
:after #'doom*recenter)
|
||||
|
||||
;; --- custom interactive codes -----------
|
||||
;; These arg types will highlight matches in the current buffer
|
||||
(evil-ex-define-argument-type buffer-match :runner +evil-ex-buffer-match)
|
||||
|
@ -159,7 +153,10 @@ line with a linewise comment.")
|
|||
|
||||
;; `evil-collection'
|
||||
(when (featurep! +everywhere)
|
||||
(load! "+everywhere")))
|
||||
(load! "+everywhere"))
|
||||
|
||||
;; Custom evil ex commands
|
||||
(load! "+commands"))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -186,49 +183,24 @@ line with a linewise comment.")
|
|||
|
||||
|
||||
(def-package! evil-embrace
|
||||
:after evil-surround
|
||||
:commands (embrace-add-pair embrace-add-pair-regexp)
|
||||
:hook (LaTeX-mode . embrace-LaTeX-mode-hook)
|
||||
:hook (org-mode . embrace-org-mode-hook)
|
||||
:hook ((ruby-mode enh-ruby-mode) . embrace-ruby-mode-hook)
|
||||
:hook (emacs-lisp-mode . embrace-emacs-lisp-mode-hook)
|
||||
:hook ((emacs-lisp-mode lisp-mode) . +evil|embrace-lisp-mode-hook)
|
||||
:hook ((org-mode LaTeX-mode) . +evil|embrace-latex-mode-hook)
|
||||
:init
|
||||
;; Add extra pairs
|
||||
(add-hook! emacs-lisp-mode
|
||||
(embrace-add-pair ?\` "`" "'"))
|
||||
(add-hook! (emacs-lisp-mode lisp-mode)
|
||||
(embrace-add-pair-regexp ?f "([^ ]+ " ")" #'+evil--embrace-elisp-fn))
|
||||
(add-hook! (org-mode LaTeX-mode)
|
||||
(embrace-add-pair-regexp ?l "\\[a-z]+{" "}" #'+evil--embrace-latex))
|
||||
(after! evil-surround
|
||||
(evil-embrace-enable-evil-surround-integration))
|
||||
:config
|
||||
(setq evil-embrace-show-help-p nil)
|
||||
(evil-embrace-enable-evil-surround-integration)
|
||||
|
||||
(defun +evil--embrace-get-pair (char)
|
||||
(if-let* ((pair (cdr-safe (assoc (string-to-char char) evil-surround-pairs-alist))))
|
||||
pair
|
||||
(if-let* ((pair (assoc-default char embrace--pairs-list)))
|
||||
(if-let* ((real-pair (and (functionp (embrace-pair-struct-read-function pair))
|
||||
(funcall (embrace-pair-struct-read-function pair)))))
|
||||
real-pair
|
||||
(cons (embrace-pair-struct-left pair) (embrace-pair-struct-right pair)))
|
||||
(cons char char))))
|
||||
(defun +evil|embrace-latex-mode-hook ()
|
||||
(embrace-add-pair-regexp ?l "\\[a-z]+{" "}" #'+evil--embrace-latex))
|
||||
|
||||
(defun +evil--embrace-escaped ()
|
||||
"Backslash-escaped surround character support for embrace."
|
||||
(let ((char (read-char "\\")))
|
||||
(if (eq char 27)
|
||||
(cons "" "")
|
||||
(let ((pair (+evil--embrace-get-pair (string char)))
|
||||
(text (if (sp-point-in-string) "\\\\%s" "\\%s")))
|
||||
(cons (format text (car pair))
|
||||
(format text (cdr pair)))))))
|
||||
|
||||
(defun +evil--embrace-latex ()
|
||||
"LaTeX command support for embrace."
|
||||
(cons (format "\\%s{" (read-string "\\")) "}"))
|
||||
|
||||
(defun +evil--embrace-elisp-fn ()
|
||||
"Elisp function support for embrace."
|
||||
(cons (format "(%s " (or (read-string "(") "")) ")"))
|
||||
(defun +evil|embrace-lisp-mode-hook ()
|
||||
(embrace-add-pair-regexp ?f "([^ ]+ " ")" #'+evil--embrace-elisp-fn))
|
||||
|
||||
;; Add escaped-sequence support to embrace
|
||||
(setf (alist-get ?\\ (default-value 'embrace--pairs-list))
|
||||
|
@ -240,13 +212,13 @@ line with a linewise comment.")
|
|||
|
||||
|
||||
(def-package! evil-escape
|
||||
:commands (evil-escape evil-escape-mode evil-escape-pre-command-hook)
|
||||
:commands (evil-escape)
|
||||
:after-call (evil-normal-state-exit-hook)
|
||||
:init
|
||||
(setq evil-escape-excluded-states '(normal visual multiedit emacs motion)
|
||||
evil-escape-excluded-major-modes '(neotree-mode treemacs-mode term-mode)
|
||||
evil-escape-key-sequence "jk"
|
||||
evil-escape-delay 0.25)
|
||||
(add-hook 'pre-command-hook #'evil-escape-pre-command-hook)
|
||||
(evil-define-key* '(insert replace visual operator) 'global "\C-g" #'evil-escape)
|
||||
:config
|
||||
;; no `evil-escape' in minibuffer
|
||||
|
@ -311,9 +283,7 @@ the new algorithm is confusing, like in python or ruby."
|
|||
:config (global-evil-surround-mode 1))
|
||||
|
||||
|
||||
;; Without `evil-visualstar', * and # grab the word at point and search, no
|
||||
;; matter what mode you're in. I want to be able to visually select a region and
|
||||
;; search for other occurrences of it.
|
||||
;; Allows you to use the selection for * and #
|
||||
(def-package! evil-visualstar
|
||||
:commands (evil-visualstar/begin-search
|
||||
evil-visualstar/begin-search-forward
|
||||
|
|
|
@ -84,7 +84,7 @@ Otherwise, these properties are available to be set:
|
|||
|
||||
|
||||
;;
|
||||
;; Library
|
||||
;; Helpers
|
||||
|
||||
;; Helpers
|
||||
(defun +lookup--online-provider (&optional force-p namespace)
|
||||
|
@ -100,59 +100,64 @@ Otherwise, these properties are available to be set:
|
|||
provider))))
|
||||
|
||||
(defun +lookup--symbol-or-region (&optional initial)
|
||||
(cond (initial)
|
||||
(cond ((stringp initial)
|
||||
initial)
|
||||
((use-region-p)
|
||||
(buffer-substring-no-properties (region-beginning)
|
||||
(region-end)))
|
||||
((require 'xref nil t)
|
||||
(xref-backend-identifier-at-point (xref-find-backend)))))
|
||||
|
||||
(defun +lookup--jump-to (prop identifier &optional other-window)
|
||||
;; TODO Refactor me
|
||||
(let ((origin (point-marker)))
|
||||
(cl-loop for fn
|
||||
in (plist-get (list :definition +lookup-definition-functions
|
||||
:references +lookup-references-functions
|
||||
:documentation +lookup-documentation-functions
|
||||
:file +lookup-file-functions)
|
||||
prop)
|
||||
for cmd = (or (command-remapping fn) fn)
|
||||
if (get fn '+lookup-async)
|
||||
return
|
||||
(progn
|
||||
(when other-window
|
||||
;; If async, we can't catch the window change or destination buffer
|
||||
;; reliably, so we set up the new window ahead of time.
|
||||
(switch-to-buffer-other-window (current-buffer))
|
||||
(goto-char (marker-position origin)))
|
||||
(call-interactively fn)
|
||||
t)
|
||||
if (condition-case e
|
||||
(save-window-excursion
|
||||
(when (or (if (commandp cmd)
|
||||
(call-interactively cmd)
|
||||
(funcall cmd identifier))
|
||||
(/= (point-marker) origin))
|
||||
(point-marker)))
|
||||
(error (ignore (message "%s" e))))
|
||||
return
|
||||
(progn
|
||||
(funcall (if other-window
|
||||
#'switch-to-buffer-other-window
|
||||
#'switch-to-buffer)
|
||||
(marker-buffer it))
|
||||
(goto-char it)))))
|
||||
(defun +lookup--run-hooks (hook identifier origin &optional other-window)
|
||||
(doom-log "Looking up '%s' with '%s'" identifier hook)
|
||||
(condition-case-unless-debug e
|
||||
(if (get hook '+lookup-async)
|
||||
(progn
|
||||
(when other-window
|
||||
;; If async, we can't catch the window change or destination buffer
|
||||
;; reliably, so we set up the new window ahead of time.
|
||||
(switch-to-buffer-other-window (current-buffer))
|
||||
(goto-char (marker-position origin)))
|
||||
(if (commandp hook)
|
||||
(call-interactively hook)
|
||||
(funcall hook identifier))
|
||||
t)
|
||||
(save-window-excursion
|
||||
(when (or (if (commandp hook)
|
||||
(call-interactively hook)
|
||||
(funcall hook identifier))
|
||||
(null origin)
|
||||
(/= (point-marker) origin))
|
||||
(point-marker))))
|
||||
((error user-error)
|
||||
(message "%s" e)
|
||||
nil)))
|
||||
|
||||
(defun +lookup--file-search (identifier)
|
||||
(unless identifier
|
||||
(let ((query (rxt-quote-pcre identifier)))
|
||||
(ignore-errors
|
||||
(cond ((featurep! :completion ivy)
|
||||
(+ivy-file-search nil :query query)
|
||||
t)
|
||||
((featurep! :completion helm)
|
||||
(+helm-file-search nil :query query)
|
||||
t))))))
|
||||
(defun +lookup--jump-to (prop identifier &optional other-window)
|
||||
(let ((ret
|
||||
(condition-case e
|
||||
(run-hook-wrapped
|
||||
(plist-get (list :definition '+lookup-definition-functions
|
||||
:references '+lookup-references-functions
|
||||
:documentation '+lookup-documentation-functions
|
||||
:file '+lookup-file-functions)
|
||||
prop)
|
||||
'+lookup--run-hooks
|
||||
identifier
|
||||
(point-marker)
|
||||
other-window)
|
||||
(quit (user-error "Aborted %s lookup" prop)))))
|
||||
(cond ((null ret)
|
||||
(message "Could not find '%s'" identifier)
|
||||
nil)
|
||||
((markerp ret)
|
||||
(funcall (if other-window
|
||||
#'switch-to-buffer-other-window
|
||||
#'switch-to-buffer)
|
||||
(marker-buffer ret))
|
||||
(goto-char ret)
|
||||
(recenter)
|
||||
t))))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -196,8 +201,7 @@ falling back to git-grep)."
|
|||
(defun +lookup-evil-goto-definition-backend (identifier)
|
||||
"Uses `evil-goto-definition' to conduct a text search for IDENTIFIER in the
|
||||
current buffer."
|
||||
(and (featurep 'evil)
|
||||
evil-mode
|
||||
(and (fboundp 'evil-goto-definition)
|
||||
(ignore-errors
|
||||
(cl-destructuring-bind (beg . end)
|
||||
(bounds-of-thing-at-point 'symbol)
|
||||
|
@ -268,7 +272,7 @@ search otherwise."
|
|||
((error "Couldn't find references of '%s'" identifier))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +lookup/documentation (identifier &optional other-window)
|
||||
(defun +lookup/documentation (identifier &optional arg)
|
||||
"Show documentation for IDENTIFIER (defaults to symbol at point or selection.
|
||||
|
||||
First attempts the :documentation handler specified with `set-lookup-handlers!'
|
||||
|
@ -277,9 +281,7 @@ for the current mode/buffer (if any), then falls back to the backends in
|
|||
(interactive
|
||||
(list (+lookup--symbol-or-region)
|
||||
current-prefix-arg))
|
||||
(cond ((null identifier) (user-error "Nothing under point"))
|
||||
|
||||
((+lookup--jump-to :documentation identifier other-window))
|
||||
(cond ((+lookup--jump-to :documentation identifier t))
|
||||
|
||||
((user-error "Couldn't find documentation for '%s'" identifier))))
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
;; be loaded before it is byte-compiled during installation. To ensure this, we
|
||||
;; declare helm before dumb-jump.
|
||||
(when (featurep! :completion helm)
|
||||
(depends-on! :completion helm))
|
||||
(package! helm))
|
||||
|
||||
;;
|
||||
(package! dumb-jump)
|
||||
|
|
|
@ -21,13 +21,15 @@
|
|||
:config
|
||||
(setq yas-verbosity (if doom-debug-mode 3 0)
|
||||
yas-also-auto-indent-first-line t
|
||||
yas-triggers-in-field t) ; Allow nested snippets
|
||||
yas-triggers-in-field t ; Allow nested snippets
|
||||
;; Remove default ~/.emacs.d/snippets
|
||||
yas-snippet-dirs (delete yas--default-user-snippets-dir yas-snippet-dirs))
|
||||
|
||||
;; Allow private snippets in DOOMDIR/snippets
|
||||
(add-to-list 'yas-snippet-dirs '+snippets-dir nil #'eq)
|
||||
|
||||
;; Remove GUI dropdown prompt (prefer ivy/helm)
|
||||
(delq #'yas-dropdown-prompt yas-prompt-functions)
|
||||
(setq yas-prompt-functions (delq 'yas-dropdown-prompt yas-prompt-functions))
|
||||
;; Prioritize private snippets in `+snippets-dir' over built-in ones if there
|
||||
;; are multiple choices.
|
||||
(add-to-list 'yas-prompt-functions #'+snippets-prompt-private nil #'eq)
|
||||
|
|
|
@ -61,9 +61,9 @@ in [[../../private/default/+evil-commands.el][private/default/+evil-commands.el]
|
|||
| ~+workspace/new~ | =SPC TAB n= | Create a new, blank workspace |
|
||||
| ~+workspace/display~ | =SPC TAB TAB= | Display open workspaces in the mode-line |
|
||||
| ~+workspace/load~ | =SPC TAB l= | Load a saved workspace into the current session |
|
||||
| ~+workspace/load-session~ | =SPC TAB L= / =:sl[oad]= | Replace current session with a saved one |
|
||||
| ~doom/quicksave-load~ | =SPC TAB L= / =:sl[oad]= | Replace current session with a saved one |
|
||||
| ~+workspace/save~ | =SPC TAB s= | Save the current workspace to a file |
|
||||
| ~+workspace/save-session~ | =SPC TAB S= / =:ss[ave]= | Save current session |
|
||||
| ~doom/quicksave-save~ | =SPC TAB S= / =:ss[ave]= | Save current session |
|
||||
| ~+workspace/switch-to~ | =SPC TAB .= | Switch to an open workspace |
|
||||
| ~+workspace/switch-left~ | =SPC TAB [= / =[ w= / =gT= | Switch to previous workspace |
|
||||
| ~+workspace/switch-right~ | =SPC TAB [= / =] w= / =gt= | Switch to next workspace |
|
||||
|
|
|
@ -1,20 +1,6 @@
|
|||
;;; feature/workspaces/autoload/evil.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! :feature evil)
|
||||
|
||||
;;;###autoload (autoload '+workspace:save-session "feature/workspaces/autoload/evil" nil t)
|
||||
(evil-define-command +workspace:save-session (&optional bang name)
|
||||
"Ex wrapper around `+workspace/save-session'. If BANG, then autosave
|
||||
(pointless if autosaving/loading is off). If NAME is nil, default to 'last'."
|
||||
(interactive "<!><a>")
|
||||
(+workspace/save-session (if bang persp-auto-save-fname name)))
|
||||
|
||||
;;;###autoload (autoload '+workspace:load-session "feature/workspaces/autoload/evil" nil t)
|
||||
(evil-define-command +workspace:load-session (&optional bang name)
|
||||
"Ex wrapper around `+workspace/load-session'. If BANG, then load last autosave
|
||||
(pointless if autosaving/loading is off). If NAME is nil, defaults to 'last'."
|
||||
(interactive "<!><a>")
|
||||
(+workspace/load-session (if bang persp-auto-save-fname name)))
|
||||
|
||||
;;;###autoload (autoload '+workspace:save "feature/workspaces/autoload/evil" nil t)
|
||||
(evil-define-command +workspace:save (&optional name)
|
||||
"Ex wrapper around `+workspace/save-session'."
|
||||
|
|
|
@ -112,14 +112,6 @@ Returns t if successful, nil otherwise."
|
|||
*persp-hash* (list name))
|
||||
(+workspace-exists-p name))
|
||||
|
||||
;;;###autoload
|
||||
(defun +workspace-load-session (&optional name)
|
||||
"Replace current session with the entire session named NAME. If NAME is nil,
|
||||
use `persp-auto-save-fname'."
|
||||
(mapc #'+workspace-delete (+workspace-list-names))
|
||||
(persp-load-state-from-file
|
||||
(expand-file-name (or name persp-auto-save-fname) persp-save-dir)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +workspace-save (name)
|
||||
"Saves a single workspace (NAME) from the current session. Can be loaded again
|
||||
|
@ -134,18 +126,6 @@ Returns t on success, nil otherwise."
|
|||
(and (member name (persp-list-persp-names-in-file fname))
|
||||
t)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +workspace-save-session (&optional name)
|
||||
"Save a whole session as NAME. If NAME is nil, use `persp-auto-save-fname'.
|
||||
Return t on success, nil otherwise."
|
||||
(let ((fname (expand-file-name (or name persp-auto-save-fname)
|
||||
persp-save-dir)))
|
||||
;; disable auto-saving on kill-emacs if autosaving (i.e. name is nil)
|
||||
(when (or (not name)
|
||||
(string= name persp-auto-save-fname))
|
||||
(setq persp-auto-save-opt 0))
|
||||
(and (persp-save-state-to-file fname) t)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +workspace-new (name)
|
||||
"Create a new workspace named NAME. If one already exists, return nil.
|
||||
|
@ -206,6 +186,9 @@ throws an error."
|
|||
;;
|
||||
;; Commands
|
||||
|
||||
;;;###autoload
|
||||
(defalias '+workspace/restore-last-session #'doom/quickload-session)
|
||||
|
||||
;;;###autoload
|
||||
(defun +workspace/load (name)
|
||||
"Load a workspace and switch to it. If called with C-u, try to reload the
|
||||
|
@ -236,46 +219,6 @@ workspace."
|
|||
(+workspace-message (format "'%s' workspace saved" name) 'success)
|
||||
(+workspace-error (format "Couldn't save workspace %s" name))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +workspace/load-session (&optional name)
|
||||
"Load a session and switch to it. If called with C-u, try to load the last
|
||||
session."
|
||||
(interactive
|
||||
(list
|
||||
(unless current-prefix-arg
|
||||
(completing-read
|
||||
"Session to load: "
|
||||
(directory-files persp-save-dir nil "^[^_.]")
|
||||
nil t))))
|
||||
(condition-case ex
|
||||
(let ((name (or name persp-auto-save-fname)))
|
||||
(+workspace-load-session name)
|
||||
(+workspace-message (format "'%s' workspace loaded" name) 'success))
|
||||
'(error (+workspace-error (cadr ex) t))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +workspace/load-last-session ()
|
||||
"Restore last session and switch to it."
|
||||
(interactive)
|
||||
(+workspace/load-session))
|
||||
|
||||
;;;###autoload
|
||||
(defun +workspace/save-session (&optional name)
|
||||
"Save the current session. If called with C-u, prompt you for the name to save
|
||||
the session as."
|
||||
(interactive
|
||||
(list
|
||||
(when current-prefix-arg
|
||||
(completing-read
|
||||
"Save session as: "
|
||||
(directory-files persp-save-dir nil "^[^_.]")))))
|
||||
(condition-case-unless-debug ex
|
||||
(let ((name (or name persp-auto-save-fname)))
|
||||
(if (+workspace-save-session name)
|
||||
(+workspace-message (format "Saved session as '%s'" name) 'success)
|
||||
(error "Couldn't save session as '%s'" name)))
|
||||
('error (+workspace-error ex t))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +workspace/rename (new-name)
|
||||
"Rename the current workspace."
|
||||
|
@ -437,12 +380,6 @@ the next."
|
|||
|
||||
(t (+workspace-error "Can't delete last workspace" t)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +workspace/restart-emacs-then-restore ()
|
||||
"Restarts Emacs, then restores the session."
|
||||
(interactive)
|
||||
(restart-emacs (list "--restore")))
|
||||
|
||||
|
||||
;;
|
||||
;; Tabs display in minibuffer
|
||||
|
@ -570,7 +507,7 @@ This be hooked to `projectile-after-switch-project-hook'."
|
|||
(+workspace-message
|
||||
(format "Switched to '%s' in new workspace" new-name)
|
||||
'success))
|
||||
(with-current-buffer (switch-to-buffer (doom-fallback-buffer))
|
||||
(with-current-buffer (doom-fallback-buffer)
|
||||
(setq default-directory +workspaces--project-dir)
|
||||
(message "Switched to '%s'" (doom-project-name +workspaces--project-dir)))
|
||||
(unless current-prefix-arg
|
||||
|
|
|
@ -5,11 +5,6 @@
|
|||
;; it because it was unstable and slow; `persp-mode' is neither (and still
|
||||
;; maintained).
|
||||
;;
|
||||
;; By default, sessions are autosaved, but not autoloaded. Use :ss or
|
||||
;; `+workspace/save-session' to save, and :sl or `+workspace/load-session' to
|
||||
;; load the last autosaved session. You can give sessions a custom name so they
|
||||
;; can be loaded later.
|
||||
;;
|
||||
;; NOTE persp-mode requires `workgroups' for file persistence in Emacs 24.4.
|
||||
|
||||
(defvar +workspaces-main "main"
|
||||
|
@ -20,26 +15,20 @@
|
|||
`counsel-projectile-switch-project'. This function must take one argument: the
|
||||
new project directory.")
|
||||
|
||||
;; FIXME actually use this for wconf bookmark system
|
||||
(defvar +workspaces-data-file "_workspaces"
|
||||
"The basename of the file to store single workspace perspectives. Will be
|
||||
stored in `persp-save-dir'.")
|
||||
|
||||
(defvar +workspaces-on-switch-project-behavior 'non-empty
|
||||
"Controls the behavior of workspaces when switching to a new project.
|
||||
|
||||
Can be one of the following:
|
||||
|
||||
t Always create a new workspace for the project
|
||||
'non-empty Only create a new workspace if the current one has no buffers
|
||||
'non-empty Only create a new workspace if the current one already has buffers
|
||||
associated with it.
|
||||
nil Never create a new workspace on project switch.")
|
||||
|
||||
;; If emacs is passed --restore, restore the last session on startup. This is
|
||||
;; used by the `+workspace/restart-emacs-then-restore' command.
|
||||
(defun +workspaces-restore-last-session (&rest _)
|
||||
(add-hook 'emacs-startup-hook #'+workspace/load-session :append))
|
||||
(add-to-list 'command-switch-alist (cons "--restore" #'+workspaces-restore-last-session))
|
||||
;; FIXME actually use this for wconf bookmark system
|
||||
(defvar +workspaces-data-file "_workspaces"
|
||||
"The basename of the file to store single workspace perspectives. Will be
|
||||
stored in `persp-save-dir'.")
|
||||
|
||||
|
||||
;;
|
||||
|
@ -64,31 +53,31 @@ workspace. Also ensures that the *Warnings* buffer will be visible in main.
|
|||
|
||||
Uses `+workspaces-main' to determine the name of the main workspace."
|
||||
(unless persp-mode
|
||||
(persp-mode +1))
|
||||
(unless noninteractive
|
||||
(let (persp-before-switch-functions persp-activated-functions)
|
||||
(with-selected-frame frame
|
||||
;; The default perspective persp-mode creates (`persp-nil-name') is
|
||||
;; special and doesn't represent a real persp object, so buffers can't
|
||||
;; really be assigned to it, among other quirks. We create a *real*
|
||||
;; main workspace to fill this role.
|
||||
(unless (persp-get-by-name +workspaces-main)
|
||||
(persp-add-new +workspaces-main))
|
||||
;; Switch to it if we aren't auto-loading the last session
|
||||
(when (and (string= (safe-persp-name (get-current-persp)) persp-nil-name)
|
||||
(= persp-auto-resume-time -1))
|
||||
(persp-frame-switch +workspaces-main frame)
|
||||
;; We want to know where we are in every new daemon frame
|
||||
(when (daemonp)
|
||||
(run-at-time 0.1 nil #'+workspace/display))
|
||||
;; Fix #319: the warnings buffer gets swallowed by creating
|
||||
;; `+workspaces-main', so we display it manually, if it exists.
|
||||
(when-let* ((warnings (get-buffer "*Warnings*")))
|
||||
(save-excursion
|
||||
(display-buffer-in-side-window
|
||||
warnings '((window-height . shrink-window-if-larger-than-buffer))))))))))
|
||||
(persp-mode +1)
|
||||
(unless noninteractive
|
||||
(let (persp-before-switch-functions persp-activated-functions)
|
||||
(with-selected-frame frame
|
||||
;; The default perspective persp-mode creates (`persp-nil-name') is
|
||||
;; special and doesn't represent a real persp object, so buffers can't
|
||||
;; really be assigned to it, among other quirks. We create a *real*
|
||||
;; main workspace to fill this role.
|
||||
(unless (persp-get-by-name +workspaces-main)
|
||||
(persp-add-new +workspaces-main))
|
||||
;; Switch to it if we aren't auto-loading the last session
|
||||
(when (and (string= (safe-persp-name (get-current-persp)) persp-nil-name)
|
||||
(= persp-auto-resume-time -1))
|
||||
(persp-frame-switch +workspaces-main frame)
|
||||
;; We want to know where we are in every new daemon frame
|
||||
(when (daemonp)
|
||||
(run-at-time 0.1 nil #'+workspace/display))
|
||||
;; Fix #319: the warnings buffer gets swallowed by creating
|
||||
;; `+workspaces-main', so we display it manually, if it exists.
|
||||
(when-let* ((warnings (get-buffer "*Warnings*")))
|
||||
(save-excursion
|
||||
(display-buffer-in-side-window
|
||||
warnings '((window-height . shrink-window-if-larger-than-buffer)))))))))))
|
||||
|
||||
(add-hook 'doom-post-init-hook #'+workspaces|init t)
|
||||
(add-hook 'doom-init-modules-hook #'+workspaces|init t)
|
||||
:config
|
||||
(setq persp-autokill-buffer-on-remove 'kill-weak
|
||||
persp-nil-hidden t
|
||||
|
@ -102,8 +91,6 @@ Uses `+workspaces-main' to determine the name of the main workspace."
|
|||
|
||||
(advice-add #'persp-asave-on-exit :around #'+workspaces*autosave-real-buffers)
|
||||
|
||||
(add-hook 'doom-cleanup-hook #'+workspaces|cleanup-unassociated-buffers)
|
||||
|
||||
;; Ensure buffers we've opened/switched to are auto-added to the current
|
||||
;; perspective
|
||||
(setq persp-add-buffer-on-find-file t
|
||||
|
|
|
@ -56,7 +56,16 @@ preceded by the opening brace or a comma (disregarding whitespace in between)."
|
|||
|
||||
;;;###autoload
|
||||
(defun +cc-c-c++-objc-mode ()
|
||||
"Sets either `c-mode', `objc-mode' or `c++-mode', whichever is appropriate."
|
||||
"Uses heuristics to detect `c-mode', `objc-mode' or `c++-mode'.
|
||||
|
||||
1. Checks if there are nearby cpp/cc/m/mm files with the same name.
|
||||
2. Checks for ObjC and C++-specific keywords and libraries.
|
||||
3. Falls back to `+cc-default-header-file-mode', if set.
|
||||
4. Otherwise, activates `c-mode'.
|
||||
|
||||
This is meant to replace `c-or-c++-mode' (introduced in Emacs 26.1), which
|
||||
doesn't support specification of the fallback mode and whose heuristics are
|
||||
simpler."
|
||||
(let ((base (file-name-sans-extension (buffer-file-name (buffer-base-buffer)))))
|
||||
(cond ((file-exists-p! (or (concat base ".cpp")
|
||||
(concat base ".cc")))
|
||||
|
@ -70,13 +79,11 @@ preceded by the opening brace or a comma (disregarding whitespace in between)."
|
|||
"\\|[-+] ([a-zA-Z0-9_]+)"
|
||||
"\\)")))
|
||||
(objc-mode))
|
||||
((fboundp 'c-or-c++-mode) ; introduced in Emacs 26.1
|
||||
(c-or-c++-mode))
|
||||
((+cc--re-search-for ; TODO Remove this along with Emacs 25 support
|
||||
((+cc--re-search-for
|
||||
(let ((id "[a-zA-Z0-9_]+") (ws "[ \t\r]+") (ws-maybe "[ \t\r]*"))
|
||||
(concat "^" ws-maybe "\\(?:"
|
||||
"using" ws "\\(?:namespace" ws "std;\\|std::\\)"
|
||||
"\\|" "namespace" "\\(:?" ws id "\\)?" ws-maybe "{"
|
||||
"using" ws "\\(?:namespace" ws "std;\\|std::\\)"
|
||||
"\\|" "namespace" "\\(?:" ws id "\\)?" ws-maybe "{"
|
||||
"\\|" "class" ws id ws-maybe "[:{\n]"
|
||||
"\\|" "template" ws-maybe "<.*>"
|
||||
"\\|" "#include" ws-maybe "<\\(?:string\\|iostream\\|map\\)>"
|
||||
|
@ -86,6 +93,14 @@ preceded by the opening brace or a comma (disregarding whitespace in between)."
|
|||
(funcall +cc-default-header-file-mode))
|
||||
((c-mode)))))
|
||||
|
||||
(defun +cc-resolve-include-paths ()
|
||||
(cl-loop with path = (or buffer-file-name default-directory)
|
||||
for dir in +cc-default-include-paths
|
||||
if (file-name-absolute-p dir)
|
||||
collect dir
|
||||
else if (projectile-locate-dominating-file path dir)
|
||||
collect (expand-file-name dir it)))
|
||||
|
||||
|
||||
;;
|
||||
;; Commands
|
||||
|
@ -99,7 +114,7 @@ preceded by the opening brace or a comma (disregarding whitespace in between)."
|
|||
;; first rtag
|
||||
(when (and (featurep 'rtags)
|
||||
rtags-enabled
|
||||
(executable-find "rc"))
|
||||
(executable-find rtags-rc-binary-name))
|
||||
(with-temp-buffer
|
||||
(message "Reloaded compile commands for rtags daemon")
|
||||
(rtags-call-rc :silent t "-J" (or (doom-project-root) default-directory))))
|
||||
|
@ -128,12 +143,13 @@ preceded by the opening brace or a comma (disregarding whitespace in between)."
|
|||
"Better fontification for preprocessor constants"
|
||||
(when (memq major-mode '(c-mode c++-mode))
|
||||
(font-lock-add-keywords
|
||||
nil '(("\\<[A-Z]*_[A-Z_]+\\>" . font-lock-constant-face)
|
||||
nil '(("\\<[A-Z]*_[0-9A-Z_]+\\>" . font-lock-constant-face)
|
||||
("\\<[A-Z]\\{3,\\}\\>" . font-lock-constant-face))
|
||||
t)))
|
||||
|
||||
(defvar +cc--project-includes-alist nil)
|
||||
;;;###autoload
|
||||
(defun +cc|irony-init-compile-options ()
|
||||
(defun +cc|init-irony-compile-options ()
|
||||
"Initialize compiler options for irony-mode. It searches for the nearest
|
||||
compilation database and initailizes it, otherwise falling back on
|
||||
`+cc-default-compiler-options' and `+cc-default-include-paths'.
|
||||
|
@ -143,33 +159,47 @@ compilation dbs."
|
|||
(when (memq major-mode '(c-mode c++-mode objc-mode))
|
||||
(require 'irony-cdb)
|
||||
(unless (irony-cdb-autosetup-compile-options)
|
||||
(irony-cdb--update-compile-options
|
||||
(delq nil
|
||||
(append (cdr-safe (assq major-mode +cc-default-compiler-options))
|
||||
(cl-loop with path = (or buffer-file-name default-directory)
|
||||
for dir in '("include" "includes")
|
||||
if (projectile-locate-dominating-file path dir)
|
||||
collect it)
|
||||
(cl-loop for path in +cc-default-include-paths
|
||||
if (stringp path)
|
||||
nconc (list "-I" path))))
|
||||
(doom-project-root)))
|
||||
;; Make ffap aware of include paths
|
||||
(when irony--working-directory
|
||||
(require 'ffap)
|
||||
(make-local-variable 'ffap-c-path)
|
||||
(make-local-variable 'ffap-c++-path)
|
||||
(cl-loop for opt in irony--compile-options
|
||||
if (and (stringp opt)
|
||||
(string-match "^-I\\(.+\\)" opt))
|
||||
do (add-to-list (pcase major-mode
|
||||
(`c-mode 'ffap-c-path)
|
||||
(`c++-mode 'ffap-c++-path))
|
||||
(expand-file-name (match-string 1 opt)
|
||||
irony--working-directory))))))
|
||||
(let ((project-root (doom-project-root))
|
||||
(include-paths (+cc-resolve-include-paths)))
|
||||
(setf (alist-get project-root +cc--project-includes-alist)
|
||||
include-paths)
|
||||
(irony-cdb--update-compile-options
|
||||
(append (delq nil (cdr-safe (assq major-mode +cc-default-compiler-options)))
|
||||
(cl-loop for path in include-paths
|
||||
collect (format "-I%s" path)))
|
||||
project-root)))))
|
||||
|
||||
;; ;;;###autoload
|
||||
;; (defun +cc|init-ccls-compile-options ()
|
||||
;; "TODO"
|
||||
;; (when (memq major-mode '(c-mode c++-mode objc-mode))
|
||||
;; (when-let* ((include-paths (+cc-resolve-include-paths)))
|
||||
;; (let ((args (delq nil (cdr-safe (assq major-mode +cc-default-compiler-options)))))
|
||||
;; (setf (alist-get (or (lsp-workspace-root)
|
||||
;; (lsp--suggest-project-root)
|
||||
;; (doom-project-root))
|
||||
;; +cc--project-includes-alist)
|
||||
;; include-paths)
|
||||
;; (setq ccls-initialization-options
|
||||
;; `(:clang (:extraArgs
|
||||
;; [,@(cl-loop for path in include-paths
|
||||
;; collect (format "-I%s" path))])))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +cc|cleanup-rtags ()
|
||||
"Kill rtags server(s) if there are no C/C++ buffers open."
|
||||
(unless (doom-buffers-in-mode '(c-mode c++-mode) (buffer-list))
|
||||
(rtags-cancel-process)))
|
||||
(defun +cc|init-ffap-integration ()
|
||||
"Takes the local project include paths and registers them with ffap.
|
||||
This way, `find-file-at-point' (and `+lookup/file') will know where to find most
|
||||
header files."
|
||||
(when-let* ((project-root (or (bound-and-true-p irony--working-directory)
|
||||
(and (featurep 'lsp)
|
||||
(or (lsp-workspace-root)
|
||||
(doom-project-root))))))
|
||||
(require 'ffap)
|
||||
(make-local-variable 'ffap-c-path)
|
||||
(make-local-variable 'ffap-c++-path)
|
||||
(cl-loop for dir in (or (cdr (assoc project-root +cc--project-includes-alist))
|
||||
(+cc-resolve-include-paths))
|
||||
do (add-to-list (pcase major-mode
|
||||
(`c-mode 'ffap-c-path)
|
||||
(`c++-mode 'ffap-c++-path))
|
||||
(expand-file-name dir project-root)))))
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
;;; lang/cc/config.el --- c, c++, and obj-c -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +cc-default-include-paths (list "include/")
|
||||
"A list of default paths, relative to a project root, to search for headers in
|
||||
C/C++. Paths can be absolute. This is ignored if your project has a compilation
|
||||
database.")
|
||||
(defvar +cc-default-include-paths
|
||||
(list "include"
|
||||
"includes")
|
||||
"A list of default relative paths which will be searched for up from the
|
||||
current file, to be passed to irony as extra header search paths. Paths can be
|
||||
absolute. This is ignored if your project has a compilation database.
|
||||
|
||||
This is ignored by ccls.")
|
||||
|
||||
(defvar +cc-default-header-file-mode 'c-mode
|
||||
"Fallback major mode for .h files if all other heuristics fail (in
|
||||
|
@ -20,7 +24,9 @@ database.")
|
|||
"-stdlib=libc++")))
|
||||
(objc-mode . nil))
|
||||
"A list of default compiler options for the C family. These are ignored if a
|
||||
compilation database is present in the project.")
|
||||
compilation database is present in the project.
|
||||
|
||||
This is ignored by ccls.")
|
||||
|
||||
|
||||
;;
|
||||
|
@ -42,8 +48,13 @@ compilation database is present in the project.")
|
|||
;; Activate `c-mode', `c++-mode' or `objc-mode' depending on heuristics
|
||||
(add-to-list 'auto-mode-alist '("\\.h\\'" . +cc-c-c++-objc-mode))
|
||||
|
||||
;; Ensure find-file-at-point works in C modes, must be added before irony
|
||||
;; and/or lsp hooks are run.
|
||||
(add-hook! (c-mode-local-vars c++-mode-local-vars objc-mode-local-vars)
|
||||
#'+cc|init-ffap-integration)
|
||||
|
||||
:config
|
||||
(set-electric! '(c-mode c++-mode objc-mode java-mode) :chars '(?\n ?\}))
|
||||
(set-electric! '(c-mode c++-mode objc-mode java-mode) :chars '(?\n ?\} ?\{))
|
||||
(set-docsets! 'c-mode "C")
|
||||
(set-docsets! 'c++-mode "C++" "Boost")
|
||||
|
||||
|
@ -69,12 +80,11 @@ compilation database is present in the project.")
|
|||
|
||||
;;; Better fontification (also see `modern-cpp-font-lock')
|
||||
(add-hook 'c-mode-common-hook #'rainbow-delimiters-mode)
|
||||
(add-hook! '(c-mode-hook c++-mode-hook) #'+cc|fontify-constants)
|
||||
(add-hook! (c-mode c++-mode) #'+cc|fontify-constants)
|
||||
|
||||
;; Custom style, based off of linux
|
||||
(unless (assoc "doom" c-style-alist)
|
||||
(push '("doom"
|
||||
(c-basic-offset . tab-width)
|
||||
(c-add-style
|
||||
"doom" '((c-basic-offset . tab-width)
|
||||
(c-comment-only-line-offset . 0)
|
||||
(c-hanging-braces-alist (brace-list-open)
|
||||
(brace-entry-open)
|
||||
|
@ -102,8 +112,7 @@ compilation database is present in the project.")
|
|||
;; another level
|
||||
(access-label . -)
|
||||
(inclass +cc-c++-lineup-inclass +)
|
||||
(label . 0)))
|
||||
c-style-alist))
|
||||
(label . 0))))
|
||||
|
||||
;;; Keybindings
|
||||
;; Smartparens and cc-mode both try to autoclose angle-brackets intelligently.
|
||||
|
@ -131,16 +140,17 @@ compilation database is present in the project.")
|
|||
(setq irony-server-install-prefix (concat doom-etc-dir "irony-server/"))
|
||||
:init
|
||||
(defun +cc|init-irony-mode ()
|
||||
(when (and (memq major-mode '(c-mode c++-mode objc-mode))
|
||||
(file-directory-p irony-server-install-prefix))
|
||||
(irony-mode +1)))
|
||||
(add-hook 'c-mode-common-hook #'+cc|init-irony-mode)
|
||||
(if (file-directory-p irony-server-install-prefix)
|
||||
(irony-mode +1)
|
||||
(message "Irony server isn't installed")))
|
||||
(add-hook! (c-mode-local-vars c++-mode-local-vars objc-mode-local-vars)
|
||||
#'+cc|init-irony-mode)
|
||||
:config
|
||||
(setq irony-cdb-search-directory-list '("." "build" "build-conda"))
|
||||
|
||||
;; Initialize compilation database, if present. Otherwise, fall back on
|
||||
;; `+cc-default-compiler-options'.
|
||||
(add-hook 'irony-mode-hook #'+cc|irony-init-compile-options)
|
||||
(add-hook 'irony-mode-hook #'+cc|init-irony-compile-options)
|
||||
|
||||
(def-package! irony-eldoc
|
||||
:hook (irony-mode . irony-eldoc))
|
||||
|
@ -188,10 +198,11 @@ compilation database is present in the project.")
|
|||
:init
|
||||
(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 "rdm"))
|
||||
(when (and (require 'rtags nil t)
|
||||
(rtags-executable-find rtags-rdm-binary-name))
|
||||
(rtags-start-process-unless-running)))
|
||||
(add-hook 'c-mode-common-hook #'+cc|init-rtags)
|
||||
(add-hook! (c-mode-local-vars c++-mode-local-vars objc-mode-local-vars)
|
||||
#'+cc|init-rtags)
|
||||
:config
|
||||
(setq rtags-autostart-diagnostics t
|
||||
rtags-use-bookmarks nil
|
||||
|
@ -210,7 +221,6 @@ compilation database is present in the project.")
|
|||
:definition #'rtags-find-symbol-at-point
|
||||
:references #'rtags-find-references-at-point)
|
||||
|
||||
(add-hook 'doom-cleanup-hook #'+cc|cleanup-rtags)
|
||||
(add-hook! 'kill-emacs-hook (ignore-errors (rtags-cancel-process)))
|
||||
|
||||
;; Use rtags-imenu instead of imenu/counsel-imenu
|
||||
|
@ -224,17 +234,16 @@ compilation database is present in the project.")
|
|||
;;
|
||||
;; LSP
|
||||
|
||||
(def-package! cquery
|
||||
(def-package! ccls
|
||||
:when (featurep! +lsp)
|
||||
:hook ((c-mode c++-mode objc-mode) . +lsp|init-cquery)
|
||||
:hook ((c-mode-local-vars c++-mode-local-vars objc-mode-local-vars) . +cc|init-ccls)
|
||||
:config
|
||||
(defun +lsp|init-cquery ()
|
||||
(defun +cc|init-ccls ()
|
||||
(setq-local company-transformers nil)
|
||||
(setq-local company-lsp-async t)
|
||||
(setq-local company-lsp-cache-candidates nil)
|
||||
(condition-case nil
|
||||
(lsp)
|
||||
(user-error nil)))
|
||||
(setq cquery-extra-init-params
|
||||
'(:index (:comments 2)
|
||||
:cacheFormat "msgpack"
|
||||
:completion (:detailedLabel t))))
|
||||
(lsp))
|
||||
(after! projectile
|
||||
(add-to-list 'projectile-globally-ignored-directories ".ccls-cache")
|
||||
(add-to-list 'projectile-project-root-files-bottom-up ".ccls-root")
|
||||
(add-to-list 'projectile-project-root-files-top-down-recurring "compile_commands.json")))
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; lang/cc/doctor.el
|
||||
|
||||
;; rtags
|
||||
(let ((bins (cl-remove-if #'executable-find '("rdm" "rc"))))
|
||||
(when (/= (length bins) 0)
|
||||
(warn! "Couldn't find the rtag client and/or server programs %s. Disabling rtags support" bins)))
|
||||
(when (require 'rtags nil t)
|
||||
;; rtags
|
||||
(let ((bins (cl-remove-if #'executable-find `(,rtags-rdm-binary-name ,rtags-rc-binary-name))))
|
||||
(when (/= (length bins) 0)
|
||||
(warn! "Couldn't find the rtag client and/or server programs %s. Disabling rtags support" bins))))
|
||||
|
||||
;; irony server
|
||||
(when (require 'irony nil t)
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
(package! company-glsl :recipe (:fetcher github :repo "Kaali/company-glsl"))))
|
||||
|
||||
(if (featurep! +lsp)
|
||||
(package! cquery)
|
||||
(package! ccls)
|
||||
(when (package! irony)
|
||||
(package! irony-eldoc)
|
||||
(when (featurep! :tools flycheck)
|
||||
|
|
|
@ -1,110 +1,112 @@
|
|||
;;; lang/clojure/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; `clojure-mode'
|
||||
(after! clojure-mode
|
||||
(add-hook 'clojure-mode-hook #'rainbow-delimiters-mode)
|
||||
(add-hook 'clojure-mode-hook #'rainbow-delimiters-mode)
|
||||
|
||||
|
||||
(def-package! cider
|
||||
;; NOTE: if you don't have an org directory set (the dir doesn't exist),
|
||||
;; cider jack in won't work.
|
||||
:commands (cider-jack-in cider-jack-in-clojurescript)
|
||||
:hook (clojure-mode-local-vars . cider-mode)
|
||||
:init
|
||||
(set-repl-handler! 'clojure-mode #'+clojure/repl)
|
||||
(set-eval-handler! 'clojure-mode #'cider-eval-region)
|
||||
(set-lookup-handlers! 'clojure-mode
|
||||
:definition #'cider-find-dwim
|
||||
:documentation #'cider-doc)
|
||||
(add-hook 'cider-mode-hook #'eldoc-mode)
|
||||
:config
|
||||
(set-popup-rules!
|
||||
'(("^\\*cider-error*" :ignore t)
|
||||
("^\\*cider-repl" :quit nil)
|
||||
("^\\*cider-repl-history" :vslot 2 :ttl nil)))
|
||||
|
||||
(def-package! cider
|
||||
;; NOTE: if you don't have an org directory set (the dir doesn't exist),
|
||||
;; cider jack in won't work.
|
||||
:commands (cider-jack-in cider-jack-in-clojurescript)
|
||||
:hook (clojure-mode . cider-mode)
|
||||
:init
|
||||
(set-repl-handler! 'clojure-mode #'+clojure/repl)
|
||||
(set-eval-handler! 'clojure-mode #'cider-eval-region)
|
||||
(set-lookup-handlers! 'clojure-mode
|
||||
:definition #'cider-find-dwim
|
||||
:documentation #'cider-doc)
|
||||
(add-hook 'cider-mode-hook #'eldoc-mode)
|
||||
:config
|
||||
(setq nrepl-hide-special-buffers t
|
||||
nrepl-log-messages nil
|
||||
cider-font-lock-dynamically '(macro core function var)
|
||||
cider-overlays-use-font-lock t
|
||||
cider-prompt-for-symbol nil
|
||||
cider-repl-display-help-banner nil
|
||||
cider-repl-history-display-duplicates nil
|
||||
cider-repl-history-display-style 'one-line
|
||||
cider-repl-history-file (concat doom-cache-dir "cider-repl-history")
|
||||
cider-repl-history-highlight-current-entry t
|
||||
cider-repl-history-quit-action 'delete-and-restore
|
||||
cider-repl-history-highlight-inserted-item t
|
||||
cider-repl-history-size 1000
|
||||
cider-repl-pop-to-buffer-on-connect 'display-only
|
||||
cider-repl-result-prefix ";; => "
|
||||
cider-repl-print-length 100
|
||||
cider-repl-use-clojure-font-lock t
|
||||
cider-repl-use-pretty-printing t
|
||||
cider-repl-wrap-history nil
|
||||
cider-stacktrace-default-filters '(tooling dup))
|
||||
|
||||
(map! (:localleader
|
||||
(:map clojure-mode-map
|
||||
"'" #'cider-jack-in
|
||||
"\"" #'cider-jack-in-clojurescript
|
||||
(setq nrepl-hide-special-buffers t
|
||||
nrepl-log-messages nil
|
||||
cider-font-lock-dynamically '(macro core function var)
|
||||
cider-overlays-use-font-lock t
|
||||
cider-prompt-for-symbol nil
|
||||
cider-repl-display-help-banner nil
|
||||
cider-repl-history-display-duplicates nil
|
||||
cider-repl-history-display-style 'one-line
|
||||
cider-repl-history-file (concat doom-cache-dir "cider-repl-history")
|
||||
cider-repl-history-highlight-current-entry t
|
||||
cider-repl-history-quit-action 'delete-and-restore
|
||||
cider-repl-history-highlight-inserted-item t
|
||||
cider-repl-history-size 1000
|
||||
cider-repl-pop-to-buffer-on-connect 'display-only
|
||||
cider-repl-result-prefix ";; => "
|
||||
cider-repl-print-length 100
|
||||
cider-repl-use-clojure-font-lock t
|
||||
cider-repl-use-pretty-printing t
|
||||
cider-repl-wrap-history nil
|
||||
cider-stacktrace-default-filters '(tooling dup))
|
||||
|
||||
(:prefix ("e" . "eval")
|
||||
"d" #'cider-eval-defun-at-point
|
||||
"D" #'cider-insert-defun-in-repl
|
||||
"e" #'cider-eval-last-sexp
|
||||
"E" #'cider-insert-last-sexp-in-repl
|
||||
"r" #'cider-eval-region
|
||||
"R" #'cider-insert-region-in-repl
|
||||
"u" #'cider-undef)
|
||||
(:prefix ("g" . "go/jump")
|
||||
"b" #'cider-pop-back
|
||||
"g" #'cider-find-var
|
||||
"n" #'cider-find-ns)
|
||||
(:prefix ("h" . "help")
|
||||
"n" #'cider-find-ns
|
||||
"a" #'cider-apropos
|
||||
"d" #'cider-doc
|
||||
"g" #'cider-grimoire-web
|
||||
"j" #'cider-javadoc)
|
||||
(:prefix ("i" . "inspect")
|
||||
"i" #'cider-inspect
|
||||
"r" #'cider-inspect-last-result)
|
||||
(:prefix ("m" . "macro")
|
||||
"e" #'cider-macroexpand-1
|
||||
"E" #'cider-macroexpand-al)
|
||||
(:prefix ("n" . "namespace")
|
||||
"n" #'cider-browse-ns
|
||||
"N" #'cider-browse-ns-all)
|
||||
(:prefix ("r" . "repl")
|
||||
"n" #'cider-repl-set-ns
|
||||
"q" #'cider-quit
|
||||
"r" #'cider-refresh
|
||||
"R" #'cider-restart
|
||||
"b" #'cider-switch-to-repl-buffer
|
||||
"B" #'+clojure/cider-switch-to-repl-buffer-and-switch-ns
|
||||
"c" #'cider-repl-clear-buffer)))
|
||||
(map! (:localleader
|
||||
(:map clojure-mode-map
|
||||
"'" #'cider-jack-in
|
||||
"\"" #'cider-jack-in-clojurescript
|
||||
|
||||
(:when (featurep! :feature evil +everywhere)
|
||||
:map cider-repl-mode-map
|
||||
:i [S-return] #'cider-repl-newline-and-indent
|
||||
:map cider-repl-history-mode-map
|
||||
:i [return] #'cider-repl-history-insert-and-quit
|
||||
:i "q" #'cider-repl-history-quit
|
||||
:i "l" #'cider-repl-history-occur
|
||||
:i "s" #'cider-repl-history-search-forward
|
||||
:i "r" #'cider-repl-history-search-backward
|
||||
:i "U" #'cider-repl-history-undo-other-window)))
|
||||
(:prefix ("e" . "eval")
|
||||
"d" #'cider-eval-defun-at-point
|
||||
"D" #'cider-insert-defun-in-repl
|
||||
"e" #'cider-eval-last-sexp
|
||||
"E" #'cider-insert-last-sexp-in-repl
|
||||
"r" #'cider-eval-region
|
||||
"R" #'cider-insert-region-in-repl
|
||||
"u" #'cider-undef)
|
||||
(:prefix ("g" . "go/jump")
|
||||
"b" #'cider-pop-back
|
||||
"g" #'cider-find-var
|
||||
"n" #'cider-find-ns)
|
||||
(:prefix ("h" . "help")
|
||||
"n" #'cider-find-ns
|
||||
"a" #'cider-apropos
|
||||
"d" #'cider-doc
|
||||
"g" #'cider-grimoire-web
|
||||
"j" #'cider-javadoc)
|
||||
(:prefix ("i" . "inspect")
|
||||
"i" #'cider-inspect
|
||||
"r" #'cider-inspect-last-result)
|
||||
(:prefix ("m" . "macro")
|
||||
"e" #'cider-macroexpand-1
|
||||
"E" #'cider-macroexpand-al)
|
||||
(:prefix ("n" . "namespace")
|
||||
"n" #'cider-browse-ns
|
||||
"N" #'cider-browse-ns-all)
|
||||
(:prefix ("r" . "repl")
|
||||
"n" #'cider-repl-set-ns
|
||||
"q" #'cider-quit
|
||||
"r" #'cider-refresh
|
||||
"R" #'cider-restart
|
||||
"b" #'cider-switch-to-repl-buffer
|
||||
"B" #'+clojure/cider-switch-to-repl-buffer-and-switch-ns
|
||||
"c" #'cider-repl-clear-buffer)))
|
||||
|
||||
(def-package! clj-refactor
|
||||
:hook (clojure-mode . clj-refactor-mode)
|
||||
:init
|
||||
(set-lookup-handlers! 'clojure-mode
|
||||
:references #'cljr-find-usages)
|
||||
:config
|
||||
(map! :map clojure-mode-map
|
||||
:localleader
|
||||
:desc "refactor" "R" #'hydra-cljr-help-menu/body))
|
||||
(:when (featurep! :feature evil +everywhere)
|
||||
:map cider-repl-mode-map
|
||||
:i [S-return] #'cider-repl-newline-and-indent
|
||||
:map cider-repl-history-mode-map
|
||||
:i [return] #'cider-repl-history-insert-and-quit
|
||||
:i "q" #'cider-repl-history-quit
|
||||
:i "l" #'cider-repl-history-occur
|
||||
:i "s" #'cider-repl-history-search-forward
|
||||
:i "r" #'cider-repl-history-search-backward
|
||||
:i "U" #'cider-repl-history-undo-other-window)))
|
||||
|
||||
(def-package! flycheck-joker
|
||||
:when (featurep! :tools flycheck)
|
||||
:after flycheck))
|
||||
|
||||
(def-package! clj-refactor
|
||||
:hook (clojure-mode . clj-refactor-mode)
|
||||
:init
|
||||
(set-lookup-handlers! 'clojure-mode
|
||||
:references #'cljr-find-usages)
|
||||
:config
|
||||
(map! :map clojure-mode-map
|
||||
:localleader
|
||||
:desc "refactor" "R" #'hydra-cljr-help-menu/body))
|
||||
|
||||
|
||||
(def-package! flycheck-joker
|
||||
:when (featurep! :tools flycheck)
|
||||
:after flycheck)
|
||||
|
|
|
@ -3,8 +3,11 @@
|
|||
;; `coq'
|
||||
(setq proof-electric-terminator-enable t)
|
||||
|
||||
;; We've replaced coq-mode abbrevs with yasnippet snippets (in the snippets
|
||||
;; library included with Doom).
|
||||
(setq coq-mode-abbrev-table '())
|
||||
|
||||
|
||||
(after! company-coq
|
||||
(set-popup-rule! "^\\*\\(?:response\\|goals\\)\\*" :ignore t)
|
||||
(set-lookup-handlers! 'company-coq-mode
|
||||
|
|
|
@ -3,20 +3,10 @@
|
|||
(def-package! elixir-mode
|
||||
:defer t
|
||||
:init
|
||||
;; Disable default smartparens config; there are too many, they're intrusive
|
||||
;; and we only want a subset of them (defined below).
|
||||
;; Disable default smartparens config. There are too many pairs; we only want
|
||||
;; a subset of them (defined below).
|
||||
(provide 'smartparens-elixir)
|
||||
:config
|
||||
;; ...and only complete the basics
|
||||
(after! smartparens
|
||||
(sp-with-modes 'elixir-mode
|
||||
(sp-local-pair "do" "end"
|
||||
:when '(("RET" "<evil-ret>"))
|
||||
:unless '(sp-in-comment-p sp-in-string-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))))
|
||||
|
||||
(set-pretty-symbols! 'elixir-mode
|
||||
;; Functional
|
||||
:def "def"
|
||||
|
@ -30,6 +20,16 @@
|
|||
:for "for"
|
||||
:return "return" :yield "use")
|
||||
|
||||
;; ...and only complete the basics
|
||||
(after! smartparens
|
||||
(sp-with-modes 'elixir-mode
|
||||
(sp-local-pair "do" "end"
|
||||
:when '(("RET" "<evil-ret>"))
|
||||
:unless '(sp-in-comment-p sp-in-string-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))))
|
||||
|
||||
(def-package! alchemist-company
|
||||
:when (featurep! :completion company)
|
||||
:commands alchemist-company
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
(after! elm-mode
|
||||
(add-hook 'elm-mode-hook #'rainbow-delimiters-mode)
|
||||
|
||||
(set-company-backend! 'elm-mode 'company-elm)
|
||||
(set-repl-handler! 'elm-mode #'run-elm-interactive)
|
||||
(set-pretty-symbols! 'elm-mode
|
||||
|
@ -22,4 +23,3 @@
|
|||
:when (featurep! :tools flycheck)
|
||||
:after elm-mode
|
||||
:config (add-to-list 'flycheck-checkers 'elm nil #'eq))
|
||||
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
to a pop up buffer."
|
||||
(require 'pp)
|
||||
(let ((result
|
||||
(let ((debug-on-error t))
|
||||
(let ((debug-on-error t)
|
||||
(doom--current-module (ignore-errors (doom-module-from-path buffer-file-name))))
|
||||
(eval (read
|
||||
(concat "(progn "
|
||||
(buffer-substring-no-properties beg end)
|
||||
|
@ -97,16 +98,17 @@ library/userland functions"
|
|||
(defun +emacs-lisp|extend-imenu ()
|
||||
"Improve imenu support with better expression regexps and Doom-specific forms."
|
||||
(setq imenu-generic-expression
|
||||
'(("Evil Commands" "^\\s-*(evil-define-\\(?:command\\|operator\\|motion\\) +\\(\\_<[^ ()\n]+\\_>\\)" 1)
|
||||
'(("Evil commands" "^\\s-*(evil-define-\\(?:command\\|operator\\|motion\\) +\\(\\_<[^ ()\n]+\\_>\\)" 1)
|
||||
("Unit tests" "^\\s-*(\\(?:ert-deftest\\|describe\\) +\"\\([^\")]+\\)\"" 1)
|
||||
("Package" "^\\s-*(\\(?:def-\\)?package! +\\(\\_<[^ ()\n]+\\_>\\)" 1)
|
||||
("Package" "^\\s-*;;;###package\\s-+\\(\\_<[^ ()\n]+\\_>\\)$" 1)
|
||||
("Major modes" "^\\s-*(define-derived-mode +\\([^ ()\n]+\\)" 1)
|
||||
("Modelines" "^\\s-*(def-modeline! +\\([^ ()\n]+\\)" 1)
|
||||
("Modeline Segments" "^\\s-*(def-modeline-segment! +\\([^ ()\n]+\\)" 1)
|
||||
("Modeline segments" "^\\s-*(def-modeline-segment! +\\([^ ()\n]+\\)" 1)
|
||||
("Advice" "^\\s-*(def\\(?:\\(?:ine-\\)?advice\\))")
|
||||
("Modes" "^\\s-*(define-\\(?:global\\(?:ized\\)?-minor\\|generic\\|minor\\)-mode +\\([^ ()\n]+\\)" 1)
|
||||
("Macros" "^\\s-*(\\(?:cl-\\)?def\\(?:ine-compile-macro\\|macro\\) +\\([^ )\n]+\\)" 1)
|
||||
("Inline Functions" "\\s-*(\\(?:cl-\\)?defsubst +\\([^ )\n]+\\)" 1)
|
||||
("Inline functions" "\\s-*(\\(?:cl-\\)?defsubst +\\([^ )\n]+\\)" 1)
|
||||
("Functions" "^\\s-*(\\(?:cl-\\)?def\\(?:un\\|un\\*\\|method\\|generic\\|-memoized!\\) +\\([^ ,)\n]+\\)" 1)
|
||||
("Variables" "^\\s-*(\\(def\\(?:c\\(?:onst\\(?:ant\\)?\\|ustom\\)\\|ine-symbol-macro\\|parameter\\|var\\(?:-local\\)?\\)\\)\\s-+\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)" 2)
|
||||
("Types" "^\\s-*(\\(cl-def\\(?:struct\\|type\\)\\|def\\(?:class\\|face\\|group\\|ine-\\(?:condition\\|error\\|widget\\)\\|package\\|struct\\|t\\(?:\\(?:hem\\|yp\\)e\\)\\)\\)\\s-+'?\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)" 2))))
|
||||
|
@ -121,3 +123,11 @@ library/userland functions"
|
|||
if (file-in-directory-p buffer-file-name dir)
|
||||
return t)))
|
||||
(flycheck-mode -1)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp-lookup-documentation (thing)
|
||||
"Lookup THING with `helpful-variable' if it's a variable, `helpful-callable'
|
||||
if it's callable, `apropos' otherwise."
|
||||
(if thing
|
||||
(doom/describe-symbol thing)
|
||||
(call-interactively #'doom/describe-symbol)))
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
(defvar +emacs-lisp-enable-extra-fontification t
|
||||
"If non-nil, highlight special forms, and defined functions and variables.")
|
||||
|
||||
(defvar +emacs-lisp-outline-regexp "[ \t]*;;;;* [^ \t\n]"
|
||||
"Regexp to use for `outline-regexp' in `emacs-lisp-mode'.
|
||||
This marks a foldable marker for `outline-minor-mode' in elisp buffers.")
|
||||
|
||||
|
||||
;; `elisp-mode' is loaded at startup. In order to lazy load its config we need
|
||||
;; to pretend it isn't loaded
|
||||
(defer-feature! elisp-mode emacs-lisp-mode)
|
||||
|
@ -11,14 +16,14 @@
|
|||
;;
|
||||
;; Config
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.Cask\\'" . emacs-lisp-mode))
|
||||
|
||||
(after! elisp-mode
|
||||
(def-package! elisp-mode
|
||||
:mode ("\\.Cask\\'" . emacs-lisp-mode)
|
||||
:config
|
||||
(set-repl-handler! 'emacs-lisp-mode #'+emacs-lisp/open-repl)
|
||||
(set-eval-handler! 'emacs-lisp-mode #'+emacs-lisp-eval)
|
||||
(set-lookup-handlers! 'emacs-lisp-mode
|
||||
:definition #'elisp-def
|
||||
:documentation #'info-lookup-symbol)
|
||||
:documentation #'+emacs-lisp-lookup-documentation)
|
||||
(set-docsets! 'emacs-lisp-mode "Emacs Lisp")
|
||||
(set-pretty-symbols! 'emacs-lisp-mode :lambda "lambda")
|
||||
(set-rotate-patterns! 'emacs-lisp-mode
|
||||
|
@ -35,14 +40,15 @@
|
|||
mode-name "Elisp"
|
||||
;; Don't treat autoloads or sexp openers as outline headers, we have
|
||||
;; hideshow for that.
|
||||
outline-regexp ";;;;* [^ \t\n]")
|
||||
outline-regexp +emacs-lisp-outline-regexp)
|
||||
|
||||
;; variable-width indentation is superior in elisp
|
||||
(add-to-list 'doom-detect-indentation-excluded-modes 'emacs-lisp-mode nil #'eq)
|
||||
|
||||
(add-hook! 'emacs-lisp-mode-hook
|
||||
#'(;; 3rd-party functionality
|
||||
auto-compile-on-save-mode outline-minor-mode
|
||||
auto-compile-on-save-mode
|
||||
outline-minor-mode
|
||||
;; initialization
|
||||
+emacs-lisp|extend-imenu))
|
||||
|
||||
|
@ -54,7 +60,7 @@
|
|||
(font-lock-add-keywords
|
||||
'emacs-lisp-mode
|
||||
(append `(;; custom Doom cookies
|
||||
("^;;;###\\(autodef\\|if\\)[ \n]" (1 font-lock-warning-face t)))
|
||||
("^;;;###\\(autodef\\|if\\|package\\)[ \n]" (1 font-lock-warning-face t)))
|
||||
;; highlight defined, special variables & functions
|
||||
(when +emacs-lisp-enable-extra-fontification
|
||||
`((+emacs-lisp-highlight-vars-and-faces . +emacs-lisp--face)))))
|
||||
|
@ -104,6 +110,7 @@
|
|||
|
||||
;; `overseer'
|
||||
(autoload 'overseer-test "overseer" nil t)
|
||||
(remove-hook 'emacs-lisp-mode-hook 'overseer-enable-mode)
|
||||
|
||||
|
||||
(def-package! flycheck-cask
|
||||
|
@ -114,12 +121,20 @@
|
|||
(add-hook 'flycheck-mode-hook #'flycheck-cask-setup nil t)))
|
||||
|
||||
|
||||
(def-package! elisp-demos
|
||||
:defer t
|
||||
:init
|
||||
(advice-add 'describe-function-1 :after #'elisp-demos-advice-describe-function-1)
|
||||
(advice-add 'helpful-update :after #'elisp-demos-advice-helpful-update))
|
||||
|
||||
|
||||
;;
|
||||
;; Project modes
|
||||
|
||||
(def-project-mode! +emacs-lisp-ert-mode
|
||||
:modes (emacs-lisp-mode)
|
||||
:match "/test[/-].+\\.el$")
|
||||
:match "/test[/-].+\\.el$"
|
||||
:add-hooks (overseer-enable-mode))
|
||||
|
||||
(associate! buttercup-minor-mode
|
||||
:modes (emacs-lisp-mode)
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/emacs-lisp/packages.el
|
||||
|
||||
(package! elisp-mode :built-in t)
|
||||
|
||||
(package! auto-compile)
|
||||
(package! highlight-quoted)
|
||||
(package! macrostep)
|
||||
(package! overseer)
|
||||
(package! elisp-def)
|
||||
(package! elisp-demos)
|
||||
|
||||
(when (featurep! :tools flycheck)
|
||||
(package! flycheck-cask))
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
;;; private/erlang/config.el -*- lexical-binding: t; -*-
|
||||
;;; lang/erlang/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(dolist (regexp '("\\.erlang$"
|
||||
;; rebar files
|
||||
"/rebar\\.config\\(?:\\.script\\)?$"
|
||||
;; erlang configs
|
||||
"/\\(?:app\\|sys\\)\\.config$"))
|
||||
(add-to-list 'auto-mode-alist (cons regexp 'erlang-mode)))
|
||||
(def-package! erlang
|
||||
:mode ("\\.erlang$" . erlang-mode)
|
||||
:mode ("/rebar\\.config\\(?:\\.script\\)?$" . erlang-mode)
|
||||
:mode ("/\\(?:app\\|sys\\)\\.config$" . erlang-mode))
|
||||
|
||||
|
||||
(def-package! flycheck-rebar3
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
:config
|
||||
(setq ess-offset-continued 'straight
|
||||
ess-expression-offset 2
|
||||
ess-use-flymake (not (featurep! :tools flycheck))
|
||||
ess-nuke-trailing-whitespace-p t
|
||||
ess-default-style 'DEFAULT
|
||||
ess-history-directory (expand-file-name "ess-history/" doom-cache-dir))
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
"goimports"))))
|
||||
|
||||
(if (featurep! +lsp)
|
||||
(add-hook 'go-mode-hook #'+lsp|init)
|
||||
(add-hook 'go-mode-hook #'lsp!)
|
||||
(add-hook 'go-mode-hook #'go-eldoc-setup))
|
||||
|
||||
(map! :map go-mode-map
|
||||
|
|
8
modules/lang/haskell/+lsp.el
Normal file
8
modules/lang/haskell/+lsp.el
Normal file
|
@ -0,0 +1,8 @@
|
|||
;;; lang/haskell/+lsp.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! lsp-haskell
|
||||
:after haskell-mode
|
||||
:init (add-hook 'haskell-mode-hook #'lsp!)
|
||||
:config
|
||||
;; Does some strange indentation if it pastes in the snippet
|
||||
(setq-hook! 'haskell-mode-hook yas-indent-line 'fixed))
|
|
@ -1,23 +1,26 @@
|
|||
;;; lang/haskell/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(cond ((featurep! +intero) (load! "+intero"))
|
||||
((featurep! +dante) (load! "+dante")))
|
||||
((featurep! +dante) (load! "+dante"))
|
||||
((featurep! +lsp) (load! "+lsp")))
|
||||
|
||||
|
||||
;;
|
||||
;; Common packages
|
||||
|
||||
(after! haskell-mode
|
||||
(setq haskell-process-suggest-remove-import-lines t ; warnings for redundant imports etc
|
||||
haskell-process-auto-import-loaded-modules t)
|
||||
(when (featurep! :tools flycheck)
|
||||
(setq haskell-process-show-overlays nil)) ; flycheck makes this unnecessary
|
||||
(add-hook! 'haskell-mode-hook
|
||||
#'(haskell-collapse-mode ; support folding haskell code blocks
|
||||
interactive-haskell-mode))
|
||||
haskell-process-auto-import-loaded-modules t
|
||||
haskell-process-show-overlays (not (featurep! :tools flycheck))) ; redundant with flycheck
|
||||
|
||||
(set-lookup-handlers! 'haskell-mode :definition #'haskell-mode-jump-to-def-or-tag)
|
||||
(set-file-template! 'haskell-mode :trigger #'haskell-auto-insert-module-template :project t)
|
||||
(set-repl-handler! '(haskell-mode haskell-cabal-mode literate-haskell-mode) #'+haskell/open-repl)
|
||||
|
||||
(add-hook! 'haskell-mode-hook
|
||||
#'(haskell-collapse-mode ; support folding haskell code blocks
|
||||
interactive-haskell-mode))
|
||||
|
||||
(add-to-list 'completion-ignored-extensions ".hi")
|
||||
|
||||
(map! :localleader
|
||||
|
|
|
@ -7,4 +7,6 @@
|
|||
(package! dante)
|
||||
(package! attrap))
|
||||
((featurep! +intero)
|
||||
(package! intero)))
|
||||
(package! intero))
|
||||
((featurep! +lsp)
|
||||
(package! lsp-haskell)))
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
(def-package! lsp-java
|
||||
:after-call java-mode
|
||||
:init (add-hook 'java-mode-hook #'+lsp|init)
|
||||
:init (add-hook 'java-mode-hook #'lsp!)
|
||||
:config
|
||||
;; TODO keybinds
|
||||
;; TODO treemacs integration (?)
|
||||
|
|
|
@ -23,11 +23,8 @@ If the depth is 2, the first two directories are removed: net.lissner.game.")
|
|||
|
||||
(add-hook 'java-mode-hook #'rainbow-delimiters-mode)
|
||||
|
||||
(cond ((featurep! +lsp) (load! "+lsp"))
|
||||
((featurep! +meghanada) (load! "+meghanada"))
|
||||
;; TODO lang/java +lsp (lsp-java?)
|
||||
;; ((featurep! +lsp) (load! "+lsp"))
|
||||
)
|
||||
(cond ((featurep! +lsp) (load! "+lsp"))
|
||||
((featurep! +meghanada) (load! "+meghanada")))
|
||||
|
||||
|
||||
;;
|
||||
|
|
|
@ -54,6 +54,9 @@
|
|||
(set-electric! 'js2-mode :chars '(?\} ?\) ?. ?:))
|
||||
(set-repl-handler! 'js2-mode #'+javascript/open-repl)
|
||||
|
||||
(after! projectile
|
||||
(add-to-list 'projectile-globally-ignored-directories "node_modules"))
|
||||
|
||||
(map! :map js2-mode-map
|
||||
:localleader
|
||||
"S" #'+javascript/skewer-this-buffer))
|
||||
|
@ -123,7 +126,7 @@
|
|||
;; Tools
|
||||
|
||||
(when (featurep! +lsp)
|
||||
(add-hook! (js2-mode rjsx-mode typescript-mode) #'+lsp|init))
|
||||
(add-hook! (js2-mode rjsx-mode typescript-mode) #'lsp!))
|
||||
|
||||
|
||||
(def-package! tide
|
||||
|
@ -157,14 +160,15 @@
|
|||
;; navigation
|
||||
(set-lookup-handlers! 'tide-mode :async t
|
||||
:definition #'tide-jump-to-definition
|
||||
:references #'tide-references
|
||||
:documentation #'tide-documentation-at-point)
|
||||
:references #'tide-references)
|
||||
;; resolve to `doom-project-root' if `tide-project-root' fails
|
||||
(advice-add #'tide-project-root :override #'+javascript*tide-project-root)
|
||||
;; cleanup tsserver when no tide buffers are left
|
||||
(add-hook! 'tide-mode-hook
|
||||
(add-hook 'kill-buffer-hook #'+javascript|cleanup-tide-processes nil t))
|
||||
|
||||
(define-key tide-mode-map [remap +lookup/documentation] #'tide-documentation-at-point)
|
||||
|
||||
(map! :localleader
|
||||
:map tide-mode-map
|
||||
"R" #'tide-restart-server
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
;;; lang/latex/+ref.el -*- lexical-binding: t; -*-
|
||||
|
||||
(when (stringp +latex-bibtex-file)
|
||||
(setq bibtex-completion-bibliography (list (expand-file-name +latex-bibtex-file))
|
||||
reftex-default-bibliography bibtex-completion-bibliography))
|
||||
|
||||
|
||||
(def-package! reftex
|
||||
:hook (LaTeX-mode . reftex-mode)
|
||||
:config
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; lang/latex/+viewers.el -*- lexical-binding: t; -*-
|
||||
|
||||
(cl-block 'viewer
|
||||
(catch 'found-viewer
|
||||
(dolist (viewer +latex-viewers)
|
||||
(if (pcase viewer
|
||||
(`skim
|
||||
|
@ -33,7 +33,7 @@
|
|||
;; Update PDF buffers after successful LaTeX runs
|
||||
(add-hook 'TeX-after-compilation-finished-function #'TeX-revert-document-buffer))))
|
||||
|
||||
(cl-return-from 'viewer)))
|
||||
(throw 'found-viewer t)))
|
||||
|
||||
;; fall back to latex-preview-pane
|
||||
(add-to-list 'TeX-view-program-list '("preview-pane" latex-preview-pane-mode))
|
||||
|
@ -44,7 +44,6 @@
|
|||
(setq latex-preview-pane-multifile-mode 'auctex)
|
||||
|
||||
(define-key! doc-view-mode-map
|
||||
(kbd "ESC") #'delete-window
|
||||
"q" #'delete-window
|
||||
"k" (λ! (quit-window) (delete-window))))
|
||||
|
||||
"ESC" #'delete-window
|
||||
"q" #'delete-window
|
||||
"k" (λ! (quit-window) (delete-window))))
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
(let* ((offset LaTeX-indent-level)
|
||||
(contin (or (and (boundp '+latex-indent-level-item-continuation)
|
||||
+latex-indent-level-item-continuation)
|
||||
(* 4 LaTeX-indent-level)))
|
||||
(* 4 offset)))
|
||||
(re-beg "\\\\begin{")
|
||||
(re-end "\\\\end{")
|
||||
(re-env "\\(itemize\\|\\enumerate\\|description\\)")
|
||||
|
@ -37,8 +37,7 @@
|
|||
indent)
|
||||
((looking-at "\\\\item")
|
||||
(+ offset indent))
|
||||
(t
|
||||
(+ contin indent))))))
|
||||
((+ contin indent))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +latex-symbols-company-backend (command &optional arg &rest _ignored)
|
||||
|
|
|
@ -54,6 +54,8 @@ If no viewers are found, `latex-preview-pane' is used.")
|
|||
(add-hook 'TeX-mode-hook #'visual-line-mode)
|
||||
;; Fold TeX macros
|
||||
(add-hook 'TeX-mode-hook #'TeX-fold-mode)
|
||||
;; Enable rainbow mode after applying styles to the buffer
|
||||
(add-hook 'TeX-mode-hook #'rainbow-delimiters-mode)
|
||||
;; display output of latex commands in popup
|
||||
(set-popup-rule! " output\\*$" :size 15)
|
||||
;; Do not prompt for Master files, this allows auto-insert to add templates to
|
||||
|
@ -63,10 +65,7 @@ If no viewers are found, `latex-preview-pane' is used.")
|
|||
(remove-hook 'find-file-hook
|
||||
(cl-find-if #'byte-code-function-p find-file-hook)
|
||||
'local))
|
||||
;; Enable rainbow mode after applying styles to the buffer
|
||||
(add-hook 'TeX-update-style-hook #'rainbow-delimiters-mode)
|
||||
(when (featurep! :tools flyspell)
|
||||
(add-hook 'latex-mode-local-vars-hook #'flyspell-mode))
|
||||
(add-hook 'latex-mode-local-vars-hook #'flyspell-mode!)
|
||||
;; All these excess pairs dramatically slow down typing in latex buffers, so
|
||||
;; we remove them. Let snippets do their job.
|
||||
(after! smartparens-latex
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
(let ((delim "~~"))
|
||||
(if (markdown-use-region-p)
|
||||
;; Active region
|
||||
(cl-destructuring-bind (beg end)
|
||||
(cl-destructuring-bind (beg . end)
|
||||
(markdown-unwrap-things-in-region
|
||||
(region-beginning) (region-end)
|
||||
+markdown--regex-del 2 4)
|
||||
|
@ -20,3 +20,23 @@
|
|||
(if (thing-at-point-looking-at +markdown--regex-del)
|
||||
(markdown-unwrap-thing-at-point nil 2 4)
|
||||
(markdown-wrap-or-insert delim delim 'word nil nil)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +markdown-flyspell-word-p ()
|
||||
"Return t if point is on a word that should be spell checked.
|
||||
|
||||
Return nil if on a link url, markup, html, or references."
|
||||
(let ((faces (doom-enlist (get-text-property (point) 'face))))
|
||||
(or (and (memq 'font-lock-comment-face faces)
|
||||
(memq 'markdown-code-face faces))
|
||||
(not (cl-loop with unsafe-faces = '(markdown-reference-face
|
||||
markdown-url-face
|
||||
markdown-markup-face
|
||||
markdown-comment-face
|
||||
markdown-html-attr-name-face
|
||||
markdown-html-attr-value-face
|
||||
markdown-html-tag-name-face
|
||||
markdown-code-face)
|
||||
for face in faces
|
||||
if (memq face unsafe-faces)
|
||||
return t)))))
|
||||
|
|
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