Merge branch 'develop'
* develop: (145 commits) v2.0.9 bump tools/neotree: refresh pane when jumping to it Fix doom module file templates when emacs.d is a symlink Update changelog ibuffer-use-other-window = t (hand off to popup system) Improve docstring for doom-real-buffer-functions Conform unit test macros to naming scheme Move doom*quit-window to core-editor feature/snippets: use default yas-snippet-dirs (harmless) lang/org: wrap smartparens config in after! Fix file template for Doom module readmes Fix some file-templates not being inserted lang/cc: fix irony-mode complaining in non-C modes, like php-mode Update & reformat module readmes for v2.0.9 Minor, general refactor & comment updates +jump/documentation: always prompt for provider with online fallback core-projects: refactor projectile var init Refactor doom/info Fix interactive usage of doom//byte-compile-core Fix async package functions not running from right cwd ...
This commit is contained in:
commit
5dacbb7cb1
88 changed files with 2547 additions and 2018 deletions
39
.github/ISSUE_TEMPLATE
vendored
Normal file
39
.github/ISSUE_TEMPLATE
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
Here are some things you should try before filing a bug report:
|
||||
|
||||
+ Run `make install` to ensure all plugins are installed.
|
||||
+ `void-function` or `void-variable` errors could signal an out-of-date autoloads file. Run `make autoloads` or `M-x doom//reload-autoloads` to update it.
|
||||
+ Scan for common OS/environment issues with `make doctor`.
|
||||
+ Never debug byte-compiled code. It will interfere in subtle ways. Clean up \*.elc files with `make clean` or `M-x doom//clean-byte-compiled-files`.
|
||||
+ Check [the FAQ](https://github.com/hlissner/doom-emacs/wiki/FAQ#troubleshooting) to see if your issue is mentioned.
|
||||
+ Check the relevant module's README.org, if one exists. There may be extra steps to getting certain features to work.
|
||||
|
||||
If none of those help, remove this section and fill out the four sections in the template below.
|
||||
|
||||
---
|
||||
|
||||
### Observed behavior
|
||||
|
||||
Describe what happened. Any aids you can include (that you think could be relevant) are a tremendous help; like a screencast gif, video, or link to your customizations for Doom (e.g. a repo or a pastebin).
|
||||
|
||||
### Expected behavior
|
||||
|
||||
Describe what you _expected_ to happen.
|
||||
|
||||
### Steps to reproduce
|
||||
|
||||
1. Select these example steps,
|
||||
2. Delete them,
|
||||
3. And replace them with precise steps to reproduce your issue.
|
||||
|
||||
### System information
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
```
|
||||
Replace this line with the output of *one* of these commands:
|
||||
|
||||
+ `M-x doom/info` (from inside Emacs)
|
||||
+ `DEBUG=1 make doctor` (command line)
|
||||
```
|
||||
</details>
|
5
.github/PULL_REQUEST_TEMPLATE
vendored
Normal file
5
.github/PULL_REQUEST_TEMPLATE
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
Thank you for contributing to Doom!
|
||||
|
||||
Before you submit this PR, please make sure your PR is targeted at develop, not
|
||||
master (unless this is a fix for a critical error). Then replace this message
|
||||
with a description of your changes.
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,6 +2,7 @@
|
|||
.cask/
|
||||
var/
|
||||
/init.el
|
||||
modules/private/
|
||||
|
||||
# emacs tempfiles that shouldn't be there
|
||||
.mc-lists.el
|
||||
|
|
|
@ -12,6 +12,91 @@
|
|||
- [[#200-jan-17-2017][2.0.0 (Jan 17, 2017)]]
|
||||
|
||||
* Unreleased (develop)
|
||||
+ *Module changes:*
|
||||
+ Add =private/default= to replace =private/hlissner=, which is a more generic
|
||||
"starter" module for new users. My private module is now at
|
||||
[[https://github.com/hlissner/doom-emacs-private][hlissner/doom-emacs-private]].
|
||||
+ =general=
|
||||
+ Fix "peculiar error" messages when running =bin/doom-doctor=, caused by
|
||||
poorly thought out error handling (see [[https://github.com/hlissner/doom-emacs/issues/175][#175]]).
|
||||
+ Fix ~doom/am-i-secure~ command.
|
||||
+ Add unicode symbols to package management commands. Looks a little nicer <3.
|
||||
+ Transform =recentf= entries into their absolute paths with symlinks resolved
|
||||
(using ~file-truename~).
|
||||
+ Local data and cache files are no longer host-namespaced. Originally, this
|
||||
was meant to facilitate using the same config files (symlinked) across
|
||||
different computers (e.g. via dropbox). Byte-compiled packages on one
|
||||
computer would cause errors on another, so I abandoned this practice, making
|
||||
~doom-host-dir~ unnecessary.
|
||||
+ Fix an issue during live byte-compilation (with auto-compile-on-save-mode)
|
||||
where ~gc-cons-threshold~ would get set to 304mb in the user's active
|
||||
session, causing freezes and stuttering.
|
||||
+ Improve error handling when byte compiling Doom. It now cleans up after
|
||||
itself if something goes wrong, with improved error handling overall.
|
||||
+ Fix =stringp= error thrown by ~doom-fetch~ in noninteractive sessions.
|
||||
+ =core= Improve GPG integration by setting ~epa-file-encrypt-to~ to
|
||||
~user-mail-address~, and ~epa-pinentry-mode~ to ~'loopback~ (so that Emacs
|
||||
will prompt you for the passphrase in the minibuffer).
|
||||
+ =core-packages= Fix ~doom-module-pairs~ returning pairs in arbitrary order,
|
||||
causing load order errors. This is because the ~hash-table-values~ function
|
||||
in Emacs 25 and under uses ~maphash~, which reverses the hash-table, while
|
||||
newer versions use ~cl-loop~, which doesn't.
|
||||
+ =core-packages= Fix ~doom//*~ not running from the correct
|
||||
default-directory, causing errors.
|
||||
+ =core-ui= Fix cryptic missing-font errors (also, they are warnings now).
|
||||
+ =core-ui= Account for Emacs 26 line numbers when calculating
|
||||
~visual-fill-column-width~.
|
||||
+ =core-editor= the =KILL= argument for ~quit-window &optional KILL WINDOW~
|
||||
has been flipped and now kills the window's buffer by default.
|
||||
+ =core-projects= Add ~doom-project-find-file~ and ~doom-project-browse~ for
|
||||
interactively fuzzy-finding and opening files in a directory/project.
|
||||
+ Add ~doom/info~ command for collecting information about your system and
|
||||
session and puts it in the clipboard. This is to make it easier for those
|
||||
reporting bugs to easily include it.
|
||||
+ Fix ibuffer windows not being handed off to popup system (see [[https://github.com/hlissner/doom-emacs/issues/309][#309]]).
|
||||
+ =feature=
|
||||
+ =file-templates=
|
||||
+ Add a file template for fish shell scripts (thanks to [[https://github.com/amosbird][amosbird]]).
|
||||
+ Fix some file templates not being inserted, like module README.org files.
|
||||
+ =version-control= When evil-mode is available, start git commit message
|
||||
buffers in insert mode (see [[https://github.com/hlissner/doom-emacs/issues/300][#300]]).
|
||||
+ =jump= Always prompt for provider when no major-mode specific online jumper
|
||||
is defined (for ~+jump/online~ and ~+jump/documentation~).
|
||||
+ =ui=
|
||||
+ =doom-dashboard=
|
||||
+ Fix ~whitespace-mode~ and ~show-trailing-whitespace~ turning the dashboard
|
||||
into a Christmas tree.
|
||||
+ Add the ~+doom-dashboard-pwd-policy~ option, giving you control over how
|
||||
~default-directory~ is set in the dashboard. By default this is set to
|
||||
~'last-project~, meaning the dashboard's cwd will match the project of the
|
||||
last buffer you killed.
|
||||
+ =completion=
|
||||
+ =ivy= Fix TAB only half-triggering auto-completion (see [[https://github.com/hlissner/doom-emacs/issues/303][#303]]).
|
||||
+ =lang=
|
||||
+ =cc=
|
||||
+ Add =rtags= support for better code navigation. This replaces gxtag and
|
||||
etag support. Also includes automatic management of the rdm daemon.
|
||||
+ Improved support for JSON compilation databases. Irony-mode (and by
|
||||
extension its flycheck and company plugins will now pick them up with more
|
||||
consistency). This ensures all these tools run with the same compile
|
||||
options as your project.
|
||||
+ New ~+cc/reload-compile-db~ commands forcibly refreshes the compilation db
|
||||
of your current project, updating irony and running rtags daemon, if any.
|
||||
+ The ~+cc-include-paths~ and ~+cc-compiler-options~ options have been
|
||||
renamed to ~+cc-default-include-paths~ and ~+cc-default-compiler-options~
|
||||
for clarity.
|
||||
+ Fix irony-mode complaining when it is enabled in non-C major-modes.
|
||||
+ =org=
|
||||
+ Change repo source for org-plus-contrib to emacsmirror.
|
||||
+ Fix ~+org-dir~ being resolved too soon, robbing the user of the
|
||||
opportunity to change it in their private module.
|
||||
+ Fix ~invalid file location~ error when capturing to a TODO template.
|
||||
+ Prevent =org-plus-contrib= from being installed on Emacs 26+, as 9.1.4 is
|
||||
included with it.
|
||||
+ Fix invalid function errors when drag'n'dropping files into org buffers
|
||||
(see [[https://github.com/hlissner/doom-emacs/issues/307][#307]]).
|
||||
+ =java= Fix Doom install meghanada server while byte compiling your Emacs
|
||||
configuration.
|
||||
|
||||
* 2.0.8 (Dec 09, 2017)
|
||||
+ *Module changes:*
|
||||
|
|
184
bin/doom-doctor
184
bin/doom-doctor
|
@ -8,6 +8,7 @@
|
|||
;; In case it isn't defined (in really old versions of Emacs, like the one that
|
||||
;; ships with MacOS).
|
||||
(defvar user-emacs-directory (expand-file-name "~/.emacs.d/"))
|
||||
(defvar doom-debug-mode (getenv "DEBUG"))
|
||||
|
||||
(unless (equal (expand-file-name user-emacs-directory)
|
||||
(expand-file-name "~/.emacs.d/"))
|
||||
|
@ -15,14 +16,20 @@
|
|||
|
||||
(require 'pp)
|
||||
|
||||
(defsubst string-trim-right (string &optional regexp)
|
||||
(if (string-match (concat "\\(?:" (or regexp "[ \t\n\r]+") "\\)\\'") string)
|
||||
(replace-match "" t t string)
|
||||
string))
|
||||
|
||||
;;
|
||||
(defvar doom-init-p nil)
|
||||
(defvar doom-errors 0)
|
||||
(defmacro check! (cond &rest body)
|
||||
(declare (indent defun))
|
||||
`(when ,cond
|
||||
,@body
|
||||
(setq doom-errors (1+ doom-errors))))
|
||||
`(let ((it ,cond))
|
||||
(when it
|
||||
,@body
|
||||
(setq doom-errors (1+ doom-errors)))))
|
||||
|
||||
(defun indented (spc msg)
|
||||
(declare (indent defun))
|
||||
|
@ -57,26 +64,18 @@
|
|||
"\n")))
|
||||
(buffer-string)))
|
||||
|
||||
(defmacro wait-for! (var if-body &optional else-body)
|
||||
(declare (indent defun))
|
||||
`(let ((i 0))
|
||||
(while (and (not ,var)
|
||||
(< i 5))
|
||||
(sleep-for 1)
|
||||
(setq i (1+ i)))
|
||||
(if ,var
|
||||
,if-body
|
||||
,else-body)))
|
||||
(defun sh (cmd)
|
||||
(string-trim-right (shell-command-to-string cmd)))
|
||||
|
||||
(defun color (code msg &rest args)
|
||||
(format "\e[%dm%s\e[%dm" code (apply #'format msg args) 0))
|
||||
|
||||
(defalias 'msg! #'message)
|
||||
(defmacro error! (&rest args) `(message (color 1 (color 31 ,@args))))
|
||||
(defmacro warn! (&rest args) `(message (color 1 (color 33 ,@args))))
|
||||
(defmacro success! (&rest args) `(message (color 1 (color 32 ,@args))))
|
||||
(defmacro log! (&rest args) `(if doom-debug-mode (message (color 34 ,@args))))
|
||||
(defmacro explain! (&rest args) `(message (indented 2 (autofill ,@args))))
|
||||
(defmacro error! (&rest args) `(msg! (color 1 (color 31 ,@args))))
|
||||
(defmacro warn! (&rest args) `(msg! (color 1 (color 33 ,@args))))
|
||||
(defmacro success! (&rest args) `(msg! (color 1 (color 32 ,@args))))
|
||||
(defmacro section! (&rest args) `(msg! (color 34 ,@args)))
|
||||
(defmacro explain! (&rest args) `(msg! (indented 2 (autofill ,@args))))
|
||||
|
||||
;;; Polyfills
|
||||
;; early versions of emacs won't have this
|
||||
|
@ -88,15 +87,21 @@
|
|||
|
||||
;; --- start a'doctorin' --------------------------------------
|
||||
|
||||
(msg! "%s\nRunning Emacs v%s, commit %s"
|
||||
(msg! "%s\nRunning Emacs v%s, commit %s\n"
|
||||
(color 1 "DOOM Doctor")
|
||||
(color 1 emacs-version)
|
||||
(if (executable-find "git")
|
||||
(shell-command-to-string "git rev-parse HEAD")
|
||||
(sh "git rev-parse HEAD")
|
||||
"n/a"))
|
||||
|
||||
(msg! "shell: %s%s"
|
||||
(getenv "SHELL")
|
||||
(if (equal (getenv "SHELL") (sh "echo $SHELL"))
|
||||
""
|
||||
(color 31 " (mismatch)")))
|
||||
(when (boundp 'system-configuration-features)
|
||||
(msg! "Compiled with:\n%s" (indented 2 (autofill system-configuration-features))))
|
||||
(msg! "uname -a:\n%s" (indented 2 (autofill (shell-command-to-string "uname -a"))))
|
||||
(msg! "uname -a:\n%s\n" (indented 2 (autofill (sh "uname -a"))))
|
||||
|
||||
(let (doom-core-packages doom-debug-mode)
|
||||
(condition-case ex
|
||||
|
@ -108,11 +113,10 @@
|
|||
(doom|finalize)
|
||||
(success! "Attempt to load DOOM: success! Loaded v%s" doom-version)
|
||||
(when (executable-find "git")
|
||||
(msg! "Revision %s"
|
||||
(or (ignore-errors
|
||||
(let ((default-directory user-emacs-directory))
|
||||
(shell-command-to-string "git rev-parse HEAD")))
|
||||
"\n"))))
|
||||
(msg! "Revision %s\n"
|
||||
(ignore-errors
|
||||
(let ((default-directory user-emacs-directory))
|
||||
(sh "git rev-parse HEAD"))))))
|
||||
('error (warn! "Attempt to load DOOM: failed\n %s\n"
|
||||
(or (cdr-safe ex) (car ex))))))
|
||||
|
||||
|
@ -120,7 +124,7 @@
|
|||
|
||||
;; --- is emacs set up properly? ------------------------------
|
||||
|
||||
(log! "test-emacs")
|
||||
(section! "test-emacs")
|
||||
(check! (version< emacs-version "25.1")
|
||||
(error! "Important: Emacs %s detected [%s]" emacs-version (executable-find "emacs"))
|
||||
(explain!
|
||||
|
@ -133,13 +137,13 @@
|
|||
;; --- is the environment set up properly? --------------------
|
||||
|
||||
;; windows? windows
|
||||
(log! "test-windows")
|
||||
(section! "test-windows")
|
||||
(check! (memq system-type '(windows-nt ms-dos cygwin))
|
||||
(warn! "Warning: Windows detected")
|
||||
(explain! "DOOM was designed for MacOS and Linux. Expect a bumpy ride!"))
|
||||
|
||||
;; are all default fonts present
|
||||
(log! "test-fonts")
|
||||
(section! "test-fonts")
|
||||
(if (not (fboundp 'find-font))
|
||||
(progn
|
||||
(warn! "Warning: unable to detect font")
|
||||
|
@ -162,19 +166,19 @@
|
|||
"case, ignore this warning."))))))
|
||||
|
||||
;; gnutls-cli & openssl
|
||||
(log! "test-gnutls")
|
||||
(section! "test-gnutls")
|
||||
(cond ((executable-find "gnutls-cli"))
|
||||
((executable-find "openssl")
|
||||
(let* ((output (shell-command-to-string "openssl ciphers -v"))
|
||||
(let* ((output (sh "openssl ciphers -v"))
|
||||
(protocols
|
||||
(let (protos)
|
||||
(mapcar (lambda (row)
|
||||
(add-to-list 'protos (cadr (split-string row " " t))))
|
||||
(split-string (shell-command-to-string "openssl ciphers -v") "\n"))
|
||||
(split-string (sh "openssl ciphers -v") "\n"))
|
||||
(delq nil protos))))
|
||||
(check! (not (or (member "TLSv1.1" protocols)
|
||||
(member "TLSv1.2" protocols)))
|
||||
(let ((version (cadr (split-string (shell-command-to-string "openssl version") " " t))))
|
||||
(let ((version (cadr (split-string (sh "openssl version") " " t))))
|
||||
(warn! "Warning: couldn't find gnutls-cli, and OpenSSL is out-of-date (v%s)" version)
|
||||
(explain!
|
||||
"This may not affect your Emacs experience, but there are security "
|
||||
|
@ -198,7 +202,7 @@
|
|||
"network, provider, government, neckbearded mother-in-laws, geeky roommates, "
|
||||
"or just about anyone who knows more about computers than you do!"))))
|
||||
|
||||
(log! "test-tls")
|
||||
(section! "test-tls")
|
||||
(cond ((not (string-match-p "\\_<GNUTLS\\_>" system-configuration-features))
|
||||
(warn! "Warning: You didn't install Emacs with gnutls support")
|
||||
(explain!
|
||||
|
@ -211,53 +215,50 @@
|
|||
" brew tap d12frosted/emacs-plus"
|
||||
" brew install emacs-plus"))))
|
||||
|
||||
((not (fboundp 'url-retrieve-synchronously))
|
||||
(error! "Can't find url-retrieve-synchronously function. Are you running Emacs 24+?"))
|
||||
|
||||
((or (executable-find "gnutls-cli")
|
||||
(executable-find "openssl"))
|
||||
(let ((tls-checktrust t)
|
||||
(gnutls-verify-error t))
|
||||
(dolist (url '("https://elpa.gnu.org"
|
||||
"https://melpa.org"))
|
||||
(condition-case-unless-debug ex
|
||||
(let (result)
|
||||
(let ((inhibit-message t))
|
||||
(url-retrieve url (lambda (status &rest _) (setq result status))))
|
||||
(wait-for! result
|
||||
(when (getenv "DEBUG")
|
||||
(success! "Verified %s" (nth 2 (split-string url "/"))))
|
||||
(signal 'timed-out url)))
|
||||
('timed-out
|
||||
(error! "Timed out trying to contact %s" ex))
|
||||
('error
|
||||
(check! t
|
||||
(error! "Rejected %s" url)
|
||||
(explain! (pp-to-string ex))))))
|
||||
(dolist (url '("https://elpa.gnu.org" "https://melpa.org"))
|
||||
(check! (condition-case-unless-debug e
|
||||
(if (let ((inhibit-message t)) (url-retrieve-synchronously url))
|
||||
(ignore (success! "Validated %s" url))
|
||||
'empty)
|
||||
('timed-out 'timeout)
|
||||
('error e))
|
||||
(pcase it
|
||||
(`empty (error! "Couldn't reach %s" url))
|
||||
(`timeout (error! "Timed out trying to contact %s" ex))
|
||||
(_
|
||||
(error! "Failed to validate %s" url)
|
||||
(when doom-debug-mode
|
||||
(explain! (pp-to-string it)))))))
|
||||
(dolist (url '("https://self-signed.badssl.com"
|
||||
"https://wrong.host.badssl.com/"))
|
||||
(condition-case-unless-debug ex
|
||||
(let (result)
|
||||
(let ((inhibit-message t))
|
||||
(url-retrieve url (lambda (status &rest _) (setq result status))))
|
||||
(wait-for! result
|
||||
(check! t
|
||||
(warn! "Verified %s (this shouldn't happen!)" (nth 2 (split-string url "/")))
|
||||
(explain! (pp-to-string result)))
|
||||
(signal 'timed-out url)))
|
||||
('timed-out
|
||||
(error! "Timed out trying to contact %s" ex))
|
||||
('error
|
||||
(when (getenv "DEBUG")
|
||||
(success! "Rejected %s (a good thing!)" url)
|
||||
(explain! (pp-to-string ex))))))))
|
||||
(check! (condition-case-unless-debug e
|
||||
(if (let ((inhibit-message t)) (url-retrieve-synchronously url))
|
||||
t
|
||||
'empty)
|
||||
('timed-out 'timeout)
|
||||
('error (ignore (success! "Successfully rejected %s" url))))
|
||||
(pcase it
|
||||
(`empty (error! "Couldn't reach %s" url))
|
||||
(`timeout (error! "Timed out trying to contact %s" ex))
|
||||
(_
|
||||
(error! "Validated %s (this shouldn't happen!)" url)))))))
|
||||
|
||||
(t
|
||||
(error! "Nope!")))
|
||||
|
||||
;; bsd vs gnu tar
|
||||
(log! "test-tar")
|
||||
(section! "test-tar")
|
||||
(let ((tar-bin (or (executable-find "gtar")
|
||||
(executable-find "tar"))))
|
||||
(if tar-bin
|
||||
(check! (not (string-match-p "(GNU tar)" (shell-command-to-string (format "%s --version" tar-bin))))
|
||||
(check! (not (string-match-p "(GNU tar)" (sh (format "%s --version" tar-bin))))
|
||||
(warn! "Warning: BSD tar detected")
|
||||
(explain!
|
||||
"QUELPA (through package-build) uses the system tar to build plugins, but it "
|
||||
|
@ -275,50 +276,51 @@
|
|||
|
||||
;; --- report! ------------------------------------------------
|
||||
|
||||
(when (getenv "DEBUG")
|
||||
(when doom-debug-mode
|
||||
(msg! "\n====\nHave some debug information:\n")
|
||||
|
||||
(when (bound-and-true-p doom-modules)
|
||||
(msg! " + enabled modules:\n%s"
|
||||
(indented 4
|
||||
(columns 3 23
|
||||
(mapcar (lambda (x) (format "+%s" x))
|
||||
(mapcar #'cdr (doom-module-pairs)))))))
|
||||
(indented 4
|
||||
(columns 3 23
|
||||
(mapcar (lambda (x) (format "+%s" x))
|
||||
(mapcar #'cdr (doom-module-pairs)))))))
|
||||
|
||||
(when (and (bound-and-true-p doom-packages)
|
||||
(require 'package nil t))
|
||||
(msg! " + enabled packages:\n%s"
|
||||
(indented 4
|
||||
(columns 2 35
|
||||
(mapcar (lambda (pkg)
|
||||
(let ((desc (cadr (assq pkg package-alist))))
|
||||
(when desc
|
||||
(package-desc-full-name desc))))
|
||||
(sort (mapcar #'car doom-packages) #'string-lessp))))))
|
||||
(indented 4
|
||||
(columns 2 35
|
||||
(delq nil
|
||||
(mapcar (lambda (pkg)
|
||||
(let ((desc (cadr (assq pkg package-alist))))
|
||||
(when desc
|
||||
(package-desc-full-name desc))))
|
||||
(sort (mapcar #'car doom-packages) #'string-lessp)))))))
|
||||
|
||||
(msg! " + byte-compiled files:\n%s"
|
||||
(indented 4
|
||||
(columns 2 39
|
||||
(let ((files (append (directory-files-recursively doom-core-dir ".elc$")
|
||||
(directory-files-recursively doom-modules-dir ".elc$"))))
|
||||
(or (and files (mapcar (lambda (file) (file-relative-name file doom-emacs-dir))
|
||||
(nreverse files)))
|
||||
(list "n/a"))))))
|
||||
(indented 4
|
||||
(columns 2 39
|
||||
(let ((files (append (directory-files-recursively doom-core-dir ".elc$")
|
||||
(directory-files-recursively doom-modules-dir ".elc$"))))
|
||||
(or (and files (mapcar (lambda (file) (file-relative-name file doom-emacs-dir))
|
||||
(nreverse files)))
|
||||
(list "n/a"))))))
|
||||
|
||||
(msg! " + exec-path:\n%s"
|
||||
(indented 4
|
||||
(columns 1 79 exec-path)))
|
||||
(indented 4
|
||||
(columns 1 79 exec-path)))
|
||||
|
||||
(msg! " + PATH:\n%s"
|
||||
(indented 4
|
||||
(columns 1 79 (split-string (getenv "PATH") ":")))))
|
||||
(indented 4
|
||||
(columns 1 79 (split-string (getenv "PATH") ":")))))
|
||||
|
||||
;;
|
||||
(if (= doom-errors 0)
|
||||
(success! "Everything seems fine, happy Emacs'ing!")
|
||||
(message "\n----")
|
||||
(warn! "There were issues!")
|
||||
(unless (getenv "DEBUG")
|
||||
(unless doom-debug-mode
|
||||
(msg! "\nHopefully these can help you find problems. If not, run this doctor again with DEBUG=1:")
|
||||
(msg! "\n DEBUG=1 make doctor\n")
|
||||
(msg! "And file a bug report with its output at https://github.com/hlissner/.emacs.d/issues")))
|
||||
|
|
|
@ -4,8 +4,12 @@
|
|||
|
||||
;;;###autoload
|
||||
(defvar doom-real-buffer-functions '()
|
||||
"A list of functions that are run to determine if a buffer is real.")
|
||||
"A list of predicate functions run to determine if a buffer is real. These
|
||||
functions are iterated over with one argument, the buffer in question. If any
|
||||
function returns non-nil, the procession stops and the buffer is qualified as
|
||||
real.")
|
||||
|
||||
;;;###autoload
|
||||
(defvar-local doom-real-buffer-p nil
|
||||
"If non-nil, this buffer should be considered real no matter what.")
|
||||
|
||||
|
@ -14,36 +18,17 @@
|
|||
"The name of the buffer to fall back to if no other buffers exist (will create
|
||||
it if it doesn't exist).")
|
||||
|
||||
|
||||
;;
|
||||
;; Functions
|
||||
;;
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-fallback-buffer ()
|
||||
"Returns the fallback buffer, creating it if necessary. By default this is the
|
||||
scratch buffer."
|
||||
(get-buffer-create doom-fallback-buffer))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-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 "r")
|
||||
(cond ((region-active-p)
|
||||
(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))))
|
||||
|
||||
|
||||
;; Buffer Life and Death ;;;;;;;;;;;;;;;
|
||||
;;;###autoload
|
||||
(defalias 'doom-buffer-list #'buffer-list)
|
||||
|
||||
|
@ -66,6 +51,28 @@ If no project is active, return all buffers."
|
|||
if (doom-real-buffer-p buf)
|
||||
collect buf))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-real-buffer-p (&optional buffer-or-name)
|
||||
"Returns t if BUFFER-OR-NAME is a 'real' buffer. The complete criteria for a
|
||||
real buffer is:
|
||||
|
||||
1. The buffer-local value of `doom-real-buffer-p' (variable) is non-nil OR
|
||||
2. Any function in `doom-real-buffer-functions' must return non-nil when
|
||||
passed this buffer OR
|
||||
3. The current buffer:
|
||||
a) has a `buffer-file-name' defined AND
|
||||
b) is not in a popup window (see `doom-popup-p') AND
|
||||
c) is not a special buffer (its name isn't something like *Help*)
|
||||
|
||||
If BUFFER-OR-NAME is omitted or nil, the current buffer is tested."
|
||||
(when-let* ((buf (ignore-errors (window-normalize-buffer buffer-or-name))))
|
||||
(or (buffer-local-value 'doom-real-buffer-p buf)
|
||||
(run-hook-with-args-until-success 'doom-real-buffer-functions buf)
|
||||
(not (or (doom-popup-p buf)
|
||||
(minibufferp buf)
|
||||
(string-match-p "^\\s-*\\*" (buffer-name buf))
|
||||
(not (buffer-file-name buf)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-buffers-in-mode (modes &optional buffer-list derived-p)
|
||||
"Return a list of buffers whose `major-mode' is `eq' to MODE(S).
|
||||
|
@ -112,8 +119,7 @@ If DERIVED-P, test with `derived-mode-p', otherwise use `eq'."
|
|||
"Switch to the next buffer N times (previous, if N < 0), skipping over unreal
|
||||
buffers. If there's nothing left, switch to `doom-fallback-buffer'. See
|
||||
`doom-real-buffer-p' for what 'real' means."
|
||||
(let ((buffers (delq (current-buffer) (doom-real-buffer-list)))
|
||||
(project-dir (doom-project-root)))
|
||||
(let ((buffers (delq (current-buffer) (doom-real-buffer-list))))
|
||||
(cond ((or (not buffers)
|
||||
(zerop (% n (1+ (length buffers)))))
|
||||
(switch-to-buffer (doom-fallback-buffer) nil t))
|
||||
|
@ -130,96 +136,49 @@ buffers. If there's nothing left, switch to `doom-fallback-buffer'. See
|
|||
do
|
||||
(dotimes (_i (abs n))
|
||||
(funcall move-func)))))
|
||||
(when (eq (current-buffer) (doom-fallback-buffer))
|
||||
(cd project-dir))
|
||||
(force-mode-line-update)
|
||||
(current-buffer)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-real-buffer-p (&optional buffer-or-name)
|
||||
"Returns t if BUFFER-OR-NAME is a 'real' buffer. The complete criteria for a
|
||||
real buffer is:
|
||||
|
||||
1. The buffer-local value of `doom-real-buffer-p' (variable) is non-nil OR
|
||||
2. Any function in `doom-real-buffer-functions' must return non-nil when
|
||||
passed this buffer OR
|
||||
3. The current buffer:
|
||||
a) has a `buffer-file-name' defined AND
|
||||
b) is not in a popup window (see `doom-popup-p') AND
|
||||
c) is not a special buffer (its name isn't something like *Help*)
|
||||
|
||||
If BUFFER-OR-NAME is omitted or nil, the current buffer is tested."
|
||||
(when-let* ((buf (ignore-errors (window-normalize-buffer buffer-or-name))))
|
||||
(or (buffer-local-value 'doom-real-buffer-p buf)
|
||||
(run-hook-with-args-until-success 'doom-real-buffer-functions buf)
|
||||
(not (or (doom-popup-p buf)
|
||||
(minibufferp buf)
|
||||
(string-match-p "^\\s-*\\*" (buffer-name buf))
|
||||
(not (buffer-file-name buf)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/next-buffer ()
|
||||
"Switch to the next real buffer, skipping non-real buffers. See
|
||||
`doom-real-buffer-p' for what 'real' means."
|
||||
(interactive)
|
||||
(doom--cycle-real-buffers +1))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/previous-buffer ()
|
||||
"Switch to the previous real buffer, skipping non-real buffers. See
|
||||
`doom-real-buffer-p' for what 'real' means."
|
||||
(interactive)
|
||||
(doom--cycle-real-buffers -1))
|
||||
(defun doom-set-buffer-real (buffer flag)
|
||||
"Forcibly mark BUFFER as FLAG (non-nil = real)."
|
||||
(with-current-buffer buffer
|
||||
(setq doom-real-buffer-p flag)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-kill-buffer (&optional buffer dont-save)
|
||||
"Kill BUFFER (falls back to current buffer if omitted) then switch to a real
|
||||
buffer. If the buffer is present in another window, only bury it.
|
||||
"Kill BUFFER (defaults to current buffer), but make sure we land on a real
|
||||
buffer. Bury the buffer if the buffer is present in another window.
|
||||
|
||||
Will prompt to save unsaved buffers when attempting to kill them, unless
|
||||
DONT-SAVE is non-nil.
|
||||
|
||||
See `doom-real-buffer-p' for what 'real' means."
|
||||
(setq buffer (or buffer (current-buffer)))
|
||||
(when (and (bufferp buffer) (buffer-live-p buffer))
|
||||
(let ((buffer-win (get-buffer-window buffer))
|
||||
(only-buffer-window-p (= 1 (length (get-buffer-window-list buffer nil t)))))
|
||||
;; deal with unsaved buffers
|
||||
(when (and only-buffer-window-p
|
||||
(buffer-file-name buffer)
|
||||
(unless buffer
|
||||
(setq buffer (current-buffer)))
|
||||
(when (and (bufferp buffer)
|
||||
(buffer-live-p buffer))
|
||||
(let ((buffer-win (get-buffer-window buffer)))
|
||||
;; deal with modified buffers
|
||||
(when (and (buffer-file-name buffer)
|
||||
(buffer-modified-p buffer))
|
||||
(with-current-buffer buffer
|
||||
(if (and (not dont-save)
|
||||
(yes-or-no-p "Buffer is unsaved, save it?"))
|
||||
(save-buffer)
|
||||
(set-buffer-modified-p nil))))
|
||||
(if buffer-win
|
||||
;; deal with dedicated windows
|
||||
(if (window-dedicated-p buffer-win)
|
||||
(unless (window--delete buffer-win t t)
|
||||
(split-window buffer-win)
|
||||
(window--delete buffer-win t t))
|
||||
;; cycle to a real buffer
|
||||
(with-selected-window buffer-win
|
||||
(doom--cycle-real-buffers -1)
|
||||
(when buffer-win
|
||||
(unrecord-window-buffer buffer-win buffer))
|
||||
(when only-buffer-window-p
|
||||
(kill-buffer buffer)))
|
||||
(not (eq (current-buffer) buffer)))
|
||||
(kill-buffer buffer)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-force-kill-buffer (&optional buffer dont-save)
|
||||
"Kill BUFFER globally and ensure all windows previously showing BUFFER have
|
||||
switched to a real buffer."
|
||||
(interactive)
|
||||
(let* ((buffer (or buffer (current-buffer)))
|
||||
(windows (get-buffer-window-list buffer nil t)))
|
||||
(doom-kill-buffer buffer dont-save)
|
||||
(dolist (win windows)
|
||||
(with-selected-window win
|
||||
(unless (doom-real-buffer-p)
|
||||
(doom/previous-buffer))))))
|
||||
;; kill the buffer (or close dedicated window)
|
||||
(cond ((not buffer-win)
|
||||
(kill-buffer buffer))
|
||||
((window-dedicated-p buffer-win)
|
||||
(unless (window--delete buffer-win t t)
|
||||
(split-window buffer-win)
|
||||
(window--delete buffer-win t t)))
|
||||
(t ; cycle to a real buffer
|
||||
(with-selected-window buffer-win
|
||||
(doom--cycle-real-buffers -1)
|
||||
(kill-buffer buffer)))))
|
||||
(not (eq (current-buffer) buffer))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-kill-buffer-and-windows (buffer)
|
||||
|
@ -229,23 +188,6 @@ switched to a real buffer."
|
|||
(delete-window window)))
|
||||
(kill-buffer buffer))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-kill-process-buffers ()
|
||||
"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))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-kill-matching-buffers (pattern &optional buffer-list)
|
||||
"Kill all buffers (in current workspace OR in BUFFER-LIST) that match the
|
||||
|
@ -254,13 +196,33 @@ regex PATTERN. Returns the number of killed buffers."
|
|||
(dolist (buf buffers (length buffers))
|
||||
(doom-kill-buffer buf t))))
|
||||
|
||||
|
||||
;;
|
||||
;; Interactive commands
|
||||
;;
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/kill-this-buffer ()
|
||||
(defun doom/kill-this-buffer (&optional interactive-p)
|
||||
"Use `doom-kill-buffer' on the current buffer."
|
||||
(interactive)
|
||||
(when (and (not (doom-kill-buffer)) (called-interactively-p 'interactive))
|
||||
(interactive (list 'interactive))
|
||||
(when (and (not (doom-kill-buffer)) interactive-p)
|
||||
(message "Nowhere left to go!")))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/kill-this-buffer-in-all-windows (buffer &optional dont-save)
|
||||
"Kill BUFFER globally and ensure all windows previously showing this buffer
|
||||
have switched to a real buffer.
|
||||
|
||||
If DONT-SAVE, don't prompt to save modified buffers (discarding their changes)."
|
||||
(interactive
|
||||
(list (current-buffer) current-prefix-arg))
|
||||
(cl-assert (bufferp buffer) t)
|
||||
(let ((windows (get-buffer-window-list buffer nil t)))
|
||||
(doom-kill-buffer buffer dont-save)
|
||||
(cl-loop for win in windows
|
||||
if (doom-real-buffer-p (window-buffer win))
|
||||
do (with-selected-window win (doom/previous-buffer)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/kill-all-buffers (&optional project-p)
|
||||
"Kill all buffers and closes their windows.
|
||||
|
@ -305,18 +267,46 @@ project."
|
|||
(message "Killed %s buffers" n))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/cleanup-buffers (&optional all-p)
|
||||
"Clean up buried and inactive process buffers in the current workspace."
|
||||
(defun doom/cleanup-session (&optional all-p)
|
||||
"Clean up buried buries and orphaned processes in the current workspace. If
|
||||
ALL-P (universal argument), clean them up globally."
|
||||
(interactive "P")
|
||||
(run-hooks 'doom-cleanup-hook)
|
||||
(let ((buffers (doom-buried-buffers (if all-p (buffer-list))))
|
||||
(n 0))
|
||||
(n 0)
|
||||
kill-buffer-query-functions)
|
||||
(mapc #'kill-buffer buffers)
|
||||
(setq n (+ n (length buffers) (doom-kill-process-buffers)))
|
||||
(setq n (+ n (length buffers) (doom/cleanup-processes)))
|
||||
(when (called-interactively-p 'interactive)
|
||||
(message "Cleaned up %s buffers" n))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-set-buffer-real (buffer flag)
|
||||
"Forcibly mark a buffer's real property, no matter what."
|
||||
(with-current-buffer buffer
|
||||
(setq doom-real-buffer-p flag)))
|
||||
(defun doom/cleanup-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))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/next-buffer ()
|
||||
"Switch to the next real buffer, skipping non-real buffers. See
|
||||
`doom-real-buffer-p' for what 'real' means."
|
||||
(interactive)
|
||||
(doom--cycle-real-buffers +1))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/previous-buffer ()
|
||||
"Switch to the previous real buffer, skipping non-real buffers. See
|
||||
`doom-real-buffer-p' for what 'real' means."
|
||||
(interactive)
|
||||
(doom--cycle-real-buffers -1))
|
||||
|
|
|
@ -65,7 +65,7 @@ selection of all minor-modes, active or not."
|
|||
in '("https://wrong.host.badssl.com/"
|
||||
"https://self-signed.badssl.com/")
|
||||
if (condition-case _e
|
||||
(url-retrieve bad (lambda (_retrieved) t))
|
||||
(url-retrieve-synchronously bad)
|
||||
(error nil))
|
||||
collect bad)))
|
||||
(error (format "tls seems to be misconfigured (it got %s)."
|
||||
|
@ -86,3 +86,15 @@ selection of all minor-modes, active or not."
|
|||
(profiler-report)
|
||||
(profiler-stop))
|
||||
(setq doom--profiler (not doom--profiler)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/info ()
|
||||
"Collects information about this session of Doom Emacs and copies it to the
|
||||
clipboard. Helpful when filing bug reports!"
|
||||
(interactive)
|
||||
(with-temp-buffer
|
||||
(message "Producing information about your system...")
|
||||
(call-process (expand-file-name "bin/doom-doctor" doom-emacs-dir) nil t)
|
||||
(ansi-color-apply-on-region (point-min) (point-max))
|
||||
(kill-new (buffer-string))
|
||||
(message "Done. Copied to clipboard!")))
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
;;;###autoload
|
||||
(defun doom/sudo-find-file (file)
|
||||
"Open a file as root."
|
||||
"Open FILE as root."
|
||||
(interactive
|
||||
(list (read-file-name "Open as root: ")))
|
||||
(find-file (if (file-writable-p file)
|
||||
|
@ -218,8 +218,29 @@ consistent throughout a selected region, depending on `indent-tab-mode'."
|
|||
(tabify beg end)
|
||||
(untabify beg end)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/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 "r")
|
||||
(cond ((region-active-p)
|
||||
(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|enable-delete-trailing-whitespace ()
|
||||
"Attaches `delete-trailing-whitespace' to a buffer-local `before-save-hook'."
|
||||
(add-hook 'before-save-hook #'delete-trailing-whitespace nil t))
|
||||
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
;;; core/autoload/packages.el -*- lexical-binding: t; -*-
|
||||
|
||||
(require 'use-package)
|
||||
(require 'quelpa)
|
||||
|
||||
(defvar doom--last-refresh nil)
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-refresh-packages (&optional force-p)
|
||||
"Refresh ELPA packages."
|
||||
(doom-initialize)
|
||||
(when force-p
|
||||
(doom-refresh-clear-cache))
|
||||
(unless (or (persistent-soft-fetch 'last-pkg-refresh "emacs")
|
||||
|
@ -31,13 +33,14 @@
|
|||
"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."
|
||||
(cl-assert (symbolp name) t)
|
||||
(doom-initialize)
|
||||
(cond ((and (or (quelpa-setup-p)
|
||||
(error "Could not initialize quelpa"))
|
||||
(assq name quelpa-cache))
|
||||
'quelpa)
|
||||
((assq name package-alist)
|
||||
'elpa)
|
||||
((package-built-in-p name)
|
||||
'emacs)
|
||||
((not noerror)
|
||||
(error "%s package is not installed" name))))
|
||||
|
||||
|
@ -84,7 +87,7 @@ installed with. Returns nil otherwise, or if package isn't installed."
|
|||
(doom-initialize-packages)
|
||||
(and (package-installed-p name)
|
||||
(let* ((plist (cdr (assq name doom-packages)))
|
||||
(old-backend (doom-package-backend name t))
|
||||
(old-backend (doom-package-backend name 'noerror))
|
||||
(new-backend (if (plist-get plist :recipe) 'quelpa 'elpa)))
|
||||
(not (eq old-backend new-backend)))))
|
||||
|
||||
|
@ -114,14 +117,12 @@ If INSTALLED-ONLY-P, only return packages that are installed."
|
|||
;;;###autoload
|
||||
(defun doom-get-depending-on (name)
|
||||
"Return a list of packages that depend on the package named NAME."
|
||||
(doom-initialize)
|
||||
(when-let* ((desc (cadr (assq name package-alist))))
|
||||
(mapcar #'package-desc-name (package--used-elsewhere-p desc nil t))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-get-dependencies-for (name &optional only)
|
||||
"Return a list of dependencies for a package."
|
||||
(doom-initialize)
|
||||
(package--get-deps name only))
|
||||
|
||||
;;;###autoload
|
||||
|
@ -156,8 +157,9 @@ Used by `doom//packages-update'."
|
|||
(load ,(expand-file-name "core.el" doom-core-dir)))
|
||||
(doom-package-outdated-p ',pkg)))
|
||||
futures))
|
||||
(append (delq nil (mapcar #'doom-package-outdated-p elpa-pkgs))
|
||||
(delq nil (mapcar #'async-get (reverse futures)))))))
|
||||
(delq nil
|
||||
(append (mapcar #'doom-package-outdated-p elpa-pkgs)
|
||||
(mapcar #'async-get (reverse futures)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-get-orphaned-packages ()
|
||||
|
@ -170,7 +172,8 @@ Used by `doom//packages-autoremove'."
|
|||
(append (mapcar #'car doom-packages) doom-core-packages)))
|
||||
(append (package--removable-packages)
|
||||
(cl-loop for pkg in package-selected-packages
|
||||
if (doom-package-different-backend-p pkg)
|
||||
if (and (doom-package-different-backend-p pkg)
|
||||
(not (package-built-in-p pkg)))
|
||||
collect pkg))))
|
||||
|
||||
;;;###autoload
|
||||
|
@ -213,7 +216,6 @@ Used by `doom//packages-install'."
|
|||
(symbol-name (car other))))
|
||||
|
||||
(defun doom--packages-choose (prompt)
|
||||
(doom-initialize)
|
||||
(let ((table (cl-loop for pkg in package-alist
|
||||
unless (package-built-in-p (cdr pkg))
|
||||
collect (cons (package-desc-full-name (cdr pkg))
|
||||
|
@ -269,7 +271,6 @@ example; the package name can be omitted)."
|
|||
(defun doom-update-package (name &optional force-p)
|
||||
"Updates package NAME (a symbol) if it is out of date, using quelpa or
|
||||
package.el as appropriate."
|
||||
(doom-initialize)
|
||||
(unless (package-installed-p name)
|
||||
(user-error "%s isn't installed" name))
|
||||
(when (doom-package-different-backend-p name)
|
||||
|
@ -298,7 +299,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'."
|
||||
(doom-initialize)
|
||||
(unless (package-installed-p name)
|
||||
(user-error "%s isn't installed" name))
|
||||
(let ((inhibit-message (not doom-debug-mode))
|
||||
|
@ -318,13 +318,14 @@ package.el as appropriate."
|
|||
|
||||
|
||||
;;
|
||||
;; Interactive commands
|
||||
;; Batch/interactive commands
|
||||
;;
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//packages-install ()
|
||||
"Interactive command for installing missing packages."
|
||||
(interactive)
|
||||
(message! "Looking for packages to install...")
|
||||
(let ((packages (doom-get-missing-packages)))
|
||||
(cond ((not packages)
|
||||
(message! (green "No packages to install!")))
|
||||
|
@ -354,20 +355,20 @@ package.el as appropriate."
|
|||
(dolist (pkg packages)
|
||||
(message! "Installing %s" (car pkg))
|
||||
(doom--condition-case!
|
||||
(message! " %s%s"
|
||||
(message! "%s%s"
|
||||
(cond ((and (package-installed-p (car pkg))
|
||||
(not (doom-package-different-backend-p (car pkg))))
|
||||
(dark (white "ALREADY INSTALLED")))
|
||||
(dark (white "⚠ ALREADY INSTALLED")))
|
||||
((doom-install-package (car pkg) (cdr pkg))
|
||||
(green "DONE"))
|
||||
(green "✓ DONE"))
|
||||
(t
|
||||
(red "FAILED")))
|
||||
(red "✕ FAILED")))
|
||||
(if (plist-member (cdr pkg) :pin)
|
||||
(format " [pinned: %s]" (plist-get (cdr pkg) :pin))
|
||||
"")))))
|
||||
""))))
|
||||
|
||||
(message! (bold (green "Finished!")))
|
||||
(doom//reload-load-path))))
|
||||
(message! (bold (green "Finished!")))
|
||||
(doom//reload-load-path)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom//packages-update ()
|
||||
|
@ -404,8 +405,7 @@ package.el as appropriate."
|
|||
(message!
|
||||
(let ((result (doom-update-package (car pkg) t)))
|
||||
(color (if result 'green 'red)
|
||||
" %s"
|
||||
(if result "DONE" "FAILED"))))))
|
||||
(if result "✓ DONE" "✕ FAILED"))))))
|
||||
|
||||
(message! (bold (green "Finished!")))
|
||||
(doom//reload-load-path)))))
|
||||
|
@ -414,29 +414,28 @@ package.el as appropriate."
|
|||
(defun doom//packages-autoremove ()
|
||||
"Interactive command for auto-removing orphaned packages."
|
||||
(interactive)
|
||||
(message! "Looking for orphaned packages...")
|
||||
(let ((packages (doom-get-orphaned-packages)))
|
||||
(cond ((not packages)
|
||||
(message! (green "No unused packages to remove")))
|
||||
|
||||
((not (or (getenv "YES")
|
||||
(y-or-n-p
|
||||
(format "%s packages will be deleted:\n\n%s\n\nProceed?"
|
||||
(length packages)
|
||||
(mapconcat
|
||||
(lambda (sym)
|
||||
(format
|
||||
"+ %s (%s)"
|
||||
sym
|
||||
(let ((backend (doom-package-backend sym)))
|
||||
(if (doom-package-different-backend-p sym)
|
||||
(if (eq backend 'quelpa)
|
||||
"QUELPA->ELPA"
|
||||
"ELPA->QUELPA")
|
||||
(if (eq backend 'quelpa)
|
||||
"QUELPA"
|
||||
"ELPA")))))
|
||||
(sort (cl-copy-list packages) #'string-lessp)
|
||||
"\n")))))
|
||||
((not
|
||||
(or (getenv "YES")
|
||||
(y-or-n-p
|
||||
(format
|
||||
"%s packages will be deleted:\n\n%s\n\nProceed?"
|
||||
(length packages)
|
||||
(mapconcat
|
||||
(lambda (sym)
|
||||
(format "+ %s (%s)" sym
|
||||
(let ((backend (doom-package-backend sym)))
|
||||
(if (doom-package-different-backend-p sym)
|
||||
(if (eq backend 'quelpa)
|
||||
"QUELPA->ELPA"
|
||||
"ELPA->QUELPA")
|
||||
(upcase (symbol-name backend))))))
|
||||
(sort (cl-copy-list packages) #'string-lessp)
|
||||
"\n")))))
|
||||
(message! (yellow "Aborted!")))
|
||||
|
||||
(t
|
||||
|
@ -446,13 +445,17 @@ package.el as appropriate."
|
|||
(let ((result (doom-delete-package pkg t)))
|
||||
(color (if result 'green 'red)
|
||||
"%s %s"
|
||||
(if result "Removed" "Failed to remove")
|
||||
(if result "✓ Removed" "✕ Failed to remove")
|
||||
pkg)))))
|
||||
|
||||
(message! (bold (green "Finished!")))
|
||||
(doom//reload-load-path)))))
|
||||
|
||||
|
||||
;;
|
||||
;; Interactive commands
|
||||
;;
|
||||
|
||||
;;;###autoload
|
||||
(defalias 'doom/install-package #'package-install)
|
||||
|
||||
|
@ -478,7 +481,9 @@ Use this interactively. Use `doom-delete-package' for direct calls."
|
|||
(if (package-installed-p package)
|
||||
(if (y-or-n-p (format "%s will be deleted. Confirm?" package))
|
||||
(message "%s %s"
|
||||
(if (doom-delete-package package t) "Deleted" "Failed to delete")
|
||||
(if (doom-delete-package package t)
|
||||
"Deleted"
|
||||
"Failed to delete")
|
||||
package)
|
||||
(message "Aborted"))
|
||||
(message "%s isn't installed" package))))
|
||||
|
|
|
@ -239,7 +239,7 @@ without leaving any trace behind (muahaha)."
|
|||
(if (featurep 'evil)
|
||||
#'evil-force-normal-state
|
||||
#'keyboard-quit))
|
||||
(delete-window)))
|
||||
(quit-restore-window nil 'kill)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/popup-this-buffer ()
|
||||
|
@ -413,12 +413,4 @@ properties."
|
|||
(when (doom-popup-p window)
|
||||
(setq doom-popup-windows (delq window doom-popup-windows))
|
||||
(when doom-popup-remember-history
|
||||
(setq doom-popup-history (list (doom--popup-data window))))
|
||||
(let ((autokill-p (and (not doom-popup-inhibit-autokill)
|
||||
(doom-popup-property :autokill window))))
|
||||
(with-selected-window window
|
||||
(doom-popup-mode -1)
|
||||
(when autokill-p
|
||||
(when-let* ((process (get-buffer-process (current-buffer))))
|
||||
(set-process-query-on-exit-flag process nil))
|
||||
(kill-buffer (current-buffer)))))))
|
||||
(setq doom-popup-history (list (doom--popup-data window))))))
|
||||
|
|
|
@ -48,8 +48,8 @@ is given, returns t if it matches the current system, and nil otherwise."
|
|||
Requires the corresponding client, e.g. git for git repos, hg for mercurial,
|
||||
etc."
|
||||
(let* ((command (pcase fetcher
|
||||
(:github "git clone --depth 1 --recursive https://github.com/%s.git")
|
||||
(:git "git clone --depth 1 --recursive %s")
|
||||
(:github "git clone --recursive https://github.com/%s.git")
|
||||
(:git "git clone --recursive %s")
|
||||
(:gist "git clone https://gist.github.com/%s.git")
|
||||
;; TODO Add hg
|
||||
(_ (error "%s is not a valid fetcher" fetcher))))
|
||||
|
@ -61,8 +61,8 @@ etc."
|
|||
(error "%s couldn't be found" command))
|
||||
(unless (file-directory-p dest)
|
||||
(funcall (if noninteractive
|
||||
(lambda (&rest args) (princ (shell-command-to-string args)))
|
||||
(lambda (c) (princ (shell-command-to-string c)))
|
||||
#'async-shell-command)
|
||||
(format "%s %s %s" bin args (shell-quote-argument dest)))
|
||||
(message! "Cloning %s -> %s" location dest))))
|
||||
(message! "Cloning %s -> %s" location (file-relative-name dest)))))
|
||||
|
||||
|
|
|
@ -74,17 +74,32 @@ If neither is available, run all tests in all enabled modules."
|
|||
(defmacro def-test! (name &rest body)
|
||||
"Define a namespaced ERT test."
|
||||
(declare (indent defun) (doc-string 2))
|
||||
(unless (plist-get body :disabled)
|
||||
(let (plist)
|
||||
(while (keywordp (car body))
|
||||
(push (pop body) plist))
|
||||
(setq plist (reverse plist))
|
||||
(when (plist-get plist :skip)
|
||||
(setq body `((ert-skip nil) ,@body)))
|
||||
(when-let* ((modes (doom-enlist (plist-get plist :minor-mode))))
|
||||
(dolist (mode modes)
|
||||
(setq body `((with-minor-mode!! ,mode ,@body)))))
|
||||
(when-let* ((before (plist-get plist :before)))
|
||||
(setq body `(,@before ,@body)))
|
||||
(when-let* ((after (plist-get plist :after)))
|
||||
(setq body `(,@body @after)))
|
||||
`(ert-deftest
|
||||
,(cl-loop with path = (file-relative-name (file-name-sans-extension load-file-name)
|
||||
doom-emacs-dir)
|
||||
for (rep . with) in '(("/test/" . "/") ("/" . ":"))
|
||||
do (setq path (replace-regexp-in-string rep with path t t))
|
||||
finally return (intern (format "%s::%s" path name))) ()
|
||||
()
|
||||
,@body)))
|
||||
finally return (intern (format "%s::%s" path name)))
|
||||
()
|
||||
(with-temp-buffer
|
||||
(save-mark-and-excursion
|
||||
(save-window-excursion
|
||||
,@body))))))
|
||||
|
||||
(defmacro should-buffer! (initial expected &rest body)
|
||||
(defmacro should-buffer!! (initial expected &rest body)
|
||||
"Test that a buffer with INITIAL text, run BODY, then test it against EXPECTED.
|
||||
|
||||
INITIAL will recognize cursor markers in the form {[0-9]}. A {0} marker marks
|
||||
|
@ -112,7 +127,7 @@ against."
|
|||
(lambda (m1 m2) (< (marker-position m1)
|
||||
(marker-position m2))))
|
||||
(when (equal (caar marker-list) "0")
|
||||
(goto-char! 0)))
|
||||
(goto-char!! 0)))
|
||||
,@body
|
||||
(let ((result-text (buffer-substring-no-properties (point-min) (point-max)))
|
||||
(point (point))
|
||||
|
@ -130,15 +145,22 @@ against."
|
|||
(should (equal expected-text result-text))
|
||||
(should same-point)))))))
|
||||
|
||||
(defmacro goto-char! (index)
|
||||
"Meant to be used with `should-buffer!'. Will move the cursor to one of the
|
||||
cursor markers. e.g. Go to marker {2} with (goto-char! 2)."
|
||||
`(goto-char (point! ,index)))
|
||||
(defmacro goto-char!! (index)
|
||||
"Meant to be used with `should-buffer!!'. Will move the cursor to one of the
|
||||
cursor markers. e.g. Go to marker {2} with (goto-char!! 2)."
|
||||
`(goto-char (point!! ,index)))
|
||||
|
||||
(defmacro point! (index)
|
||||
"Meant to be used with `should-buffer!'. Returns the position of a cursor
|
||||
marker. e.g. {2} can be retrieved with (point! 2)."
|
||||
(defmacro point!! (index)
|
||||
"Meant to be used with `should-buffer!!'. Returns the position of a cursor
|
||||
marker. e.g. {2} can be retrieved with (point!! 2)."
|
||||
`(cdr (assoc ,(cond ((numberp index) (number-to-string index))
|
||||
((symbolp index) (symbol-name index))
|
||||
((stringp index) index))
|
||||
marker-list)))
|
||||
|
||||
(defmacro with-minor-mode!! (mode &rest body)
|
||||
"TODO"
|
||||
(declare (indent defun))
|
||||
`(progn (,mode +1)
|
||||
,@body
|
||||
(,mode -1)))
|
||||
|
|
|
@ -58,6 +58,12 @@ modes are active and the buffer is read-only.")
|
|||
(ignore (bury-buffer))))
|
||||
(add-hook 'kill-buffer-query-functions #'doom|dont-kill-scratch-buffer)
|
||||
|
||||
;; temporary windows often have q bound to `quit-window', which only buries the
|
||||
;; contained buffer. I rarely don't want that buffer killed, so...
|
||||
(defun doom*quit-window (orig-fn &optional kill window)
|
||||
(funcall orig-fn (not kill) window))
|
||||
(advice-add #'quit-window :around #'doom*quit-window)
|
||||
|
||||
(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
|
||||
|
@ -75,43 +81,6 @@ fundamental-mode) for performance sake."
|
|||
(fundamental-mode))))
|
||||
(add-hook 'find-file-hook #'doom|check-large-file)
|
||||
|
||||
;; Automatic minor modes
|
||||
(defvar doom-auto-minor-mode-alist '()
|
||||
"Alist mapping filename patterns to corresponding minor mode functions, like
|
||||
`auto-mode-alist'. All elements of this alist are checked, meaning you can
|
||||
enable multiple minor modes for the same regexp.")
|
||||
|
||||
(defun doom|enable-minor-mode-maybe ()
|
||||
"Check file name against `doom-auto-minor-mode-alist'."
|
||||
(when buffer-file-name
|
||||
(let ((name buffer-file-name)
|
||||
(remote-id (file-remote-p buffer-file-name))
|
||||
(alist doom-auto-minor-mode-alist))
|
||||
;; Remove backup-suffixes from file name.
|
||||
(setq name (file-name-sans-versions name))
|
||||
;; Remove remote file name identification.
|
||||
(when (and (stringp remote-id)
|
||||
(string-match-p (regexp-quote remote-id) name))
|
||||
(setq name (substring name (match-end 0))))
|
||||
(while (and alist (caar alist) (cdar alist))
|
||||
(if (string-match-p (caar alist) name)
|
||||
(funcall (cdar alist) 1))
|
||||
(setq alist (cdr alist))))))
|
||||
(add-hook 'find-file-hook #'doom|enable-minor-mode-maybe)
|
||||
|
||||
(defun doom*set-indirect-buffer-filename (orig-fn base-buffer name &optional clone)
|
||||
"In indirect buffers, `buffer-file-name' is nil, which can cause problems
|
||||
with functions that require it (like modeline segments)."
|
||||
(let ((file-name (buffer-file-name base-buffer))
|
||||
(buffer (funcall orig-fn base-buffer name clone)))
|
||||
(when (and file-name buffer)
|
||||
(with-current-buffer buffer
|
||||
(unless buffer-file-name
|
||||
(setq buffer-file-name file-name
|
||||
buffer-file-truename (file-truename file-name)))))
|
||||
buffer))
|
||||
(advice-add #'make-indirect-buffer :around #'doom*set-indirect-buffer-filename)
|
||||
|
||||
(push '("/LICENSE$" . text-mode) auto-mode-alist)
|
||||
|
||||
|
||||
|
@ -138,16 +107,15 @@ with functions that require it (like modeline segments)."
|
|||
(def-package! recentf
|
||||
:hook (doom-init . recentf-mode)
|
||||
:config
|
||||
(setq recentf-save-file (concat doom-etc-dir "recentf")
|
||||
(setq recentf-save-file (concat doom-cache-dir "recentf")
|
||||
recentf-max-menu-items 0
|
||||
recentf-max-saved-items 300
|
||||
recentf-filename-handlers '(file-truename)
|
||||
recentf-exclude
|
||||
(list "^/tmp/" "^/ssh:" "\\.?ido\\.last$" "\\.revive$" "/TAGS$"
|
||||
"^/var/folders/.+$"
|
||||
;; ignore private DOOM temp files (but not all of them)
|
||||
(concat "^" (replace-regexp-in-string
|
||||
(concat "@" (regexp-quote (system-name)))
|
||||
"@" (abbreviate-file-name doom-host-dir))))))
|
||||
(concat "^" (file-truename doom-local-dir)))))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -206,8 +174,8 @@ extension, try to guess one."
|
|||
|
||||
;; Auto-close delimiters and blocks as you type
|
||||
(def-package! smartparens
|
||||
:hook (doom-init . smartparens-global-mode)
|
||||
:config
|
||||
(add-hook 'doom-init-hook #'smartparens-global-mode)
|
||||
(require 'smartparens-config)
|
||||
|
||||
(setq sp-autowrap-region nil ; let evil-surround handle this
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
;;; core-lib.el -*- lexical-binding: t; -*-
|
||||
|
||||
(require 'cl-lib)
|
||||
(require 'subr-x)
|
||||
(load "async-autoloads" nil t)
|
||||
(load "persistent-soft-autoloads" nil t)
|
||||
|
|
|
@ -51,11 +51,6 @@
|
|||
"Non-nil if doom is done initializing (once `doom-post-init-hook' is done). If
|
||||
this is nil after Emacs has started something is wrong.")
|
||||
|
||||
(defvar doom-package-init-p nil
|
||||
"If non-nil, doom's package system has been initialized (by
|
||||
`doom-initialize'). This will be nill if you byte-compile your configuration (as
|
||||
intended).")
|
||||
|
||||
(defvar doom-init-time nil
|
||||
"The time it took, in seconds, for DOOM Emacs to initialize.")
|
||||
|
||||
|
@ -82,7 +77,7 @@ missing) and shouldn't be deleted.")
|
|||
"The load path of built in Emacs libraries.")
|
||||
|
||||
(defvar doom--package-load-path ()
|
||||
"The load path of package libraries installed via ELPA or QUELPA.")
|
||||
"The load path of package libraries installed via ELPA and QUELPA.")
|
||||
|
||||
(defvar doom--base-load-path
|
||||
(append (list doom-core-dir doom-modules-dir)
|
||||
|
@ -135,19 +130,37 @@ are installed.
|
|||
|
||||
If you byte-compile core/core.el, this function will be avoided to speed up
|
||||
startup."
|
||||
;; Called early during initialization; only use native functions!
|
||||
(when (or (not doom-package-init-p) force-p)
|
||||
(setq load-path doom--base-load-path
|
||||
package-activated-list nil)
|
||||
;; Ensure core folders exist
|
||||
(dolist (dir (list doom-local-dir doom-etc-dir doom-cache-dir package-user-dir))
|
||||
(unless (file-directory-p dir)
|
||||
(make-directory dir t)))
|
||||
(condition-case _ (package-initialize t)
|
||||
('error
|
||||
(package-refresh-contents)
|
||||
(setq doom--refreshed-p t)
|
||||
(package-initialize t)))
|
||||
;; Called early during initialization; only use native (and cl-lib) functions!
|
||||
(when (or force-p (not doom-init-p))
|
||||
;; Speed things up with a `load-path' for only the bare essentials
|
||||
(let ((load-path doom--base-load-path))
|
||||
;; Ensure core folders exist, otherwise we get errors
|
||||
(dolist (dir (list doom-local-dir doom-etc-dir doom-cache-dir doom-packages-dir))
|
||||
(unless (file-directory-p dir)
|
||||
(make-directory dir t)))
|
||||
;; Ensure package.el is initialized; we use its state
|
||||
(setq package-activated-list nil)
|
||||
(condition-case _ (package-initialize t)
|
||||
('error (package-refresh-contents)
|
||||
(setq doom--refreshed-p t)
|
||||
(package-initialize t)))
|
||||
;; Ensure core packages are installed
|
||||
(let ((core-packages (cl-remove-if #'package-installed-p doom-core-packages)))
|
||||
(when core-packages
|
||||
(message "Installing core packages")
|
||||
(unless doom--refreshed-p
|
||||
(package-refresh-contents))
|
||||
(dolist (package core-packages)
|
||||
(let ((inhibit-message t))
|
||||
(package-install package))
|
||||
(if (package-installed-p package)
|
||||
(message "✓ Installed %s" package)
|
||||
(error "✕ Couldn't install %s" package)))
|
||||
(message "Installing core packages...done")))
|
||||
(setq doom-init-p t))))
|
||||
|
||||
(defun doom-initialize-load-path (&optional force-p)
|
||||
(when (or force-p (not doom--package-load-path))
|
||||
;; We could let `package-initialize' fill `load-path', but it does more than
|
||||
;; that alone (like load autoload files). If you want something prematurely
|
||||
;; optimizated right, ya gotta do it yourself.
|
||||
|
@ -155,23 +168,7 @@ startup."
|
|||
;; Also, in some edge cases involving package initialization during a
|
||||
;; non-interactive session, `package-initialize' fails to fill `load-path'.
|
||||
(setq doom--package-load-path (directory-files package-user-dir t "^[^.]" t)
|
||||
load-path (append load-path doom--package-load-path))
|
||||
;; Ensure core packages are installed
|
||||
(dolist (pkg doom-core-packages)
|
||||
(unless (package-installed-p pkg)
|
||||
(unless doom--refreshed-p
|
||||
(package-refresh-contents)
|
||||
(setq doom--refreshed-p t))
|
||||
(let ((inhibit-message t))
|
||||
(package-install pkg))
|
||||
(if (package-installed-p pkg)
|
||||
(message "Installed %s" pkg)
|
||||
(error "Couldn't install %s" pkg))))
|
||||
(load "quelpa" nil t)
|
||||
(load "use-package" nil t)
|
||||
(setq doom-package-init-p t)
|
||||
(unless noninteractive
|
||||
(message "Doom initialized"))))
|
||||
load-path (append doom--base-load-path doom--package-load-path))))
|
||||
|
||||
(defun doom-initialize-autoloads ()
|
||||
"Ensures that `doom-autoload-file' exists and is loaded. Otherwise run
|
||||
|
@ -186,39 +183,35 @@ startup."
|
|||
If FORCE-P is non-nil, do it even if they are.
|
||||
|
||||
This aggressively reloads core autoload files."
|
||||
(doom-initialize force-p)
|
||||
(doom-initialize-load-path force-p)
|
||||
(with-temp-buffer ; prevent buffer-local settings from propagating
|
||||
(let ((noninteractive t)
|
||||
(load-prefer-newer t)
|
||||
(load-fn
|
||||
(lambda (file &optional noerror)
|
||||
(condition-case-unless-debug ex
|
||||
(load file noerror :nomessage :nosuffix)
|
||||
('error
|
||||
(error (format "(doom-initialize-packages) %s in %s: %s"
|
||||
(car ex)
|
||||
(file-relative-name file doom-emacs-dir)
|
||||
(error-message-string ex))
|
||||
:error))))))
|
||||
(cl-flet
|
||||
((_load
|
||||
(file &optional noerror interactive)
|
||||
(condition-case-unless-debug ex
|
||||
(let ((load-prefer-newer t)
|
||||
(noninteractive (not interactive)))
|
||||
(load file noerror :nomessage :nosuffix))
|
||||
('error
|
||||
(lwarn 'doom-initialize-packages :warning
|
||||
"%s in %s: %s"
|
||||
(car ex)
|
||||
(file-relative-name file doom-emacs-dir)
|
||||
(error-message-string ex))))))
|
||||
(when (or force-p (not doom-modules))
|
||||
(setq doom-modules nil)
|
||||
(let (noninteractive)
|
||||
(load (concat doom-core-dir "core.el") nil t))
|
||||
(funcall load-fn (expand-file-name "init.el" doom-emacs-dir))
|
||||
(setq doom-modules nil
|
||||
doom-packages nil)
|
||||
(_load (concat doom-core-dir "core.el") nil 'interactive)
|
||||
(_load (expand-file-name "init.el" doom-emacs-dir))
|
||||
(when load-p
|
||||
(let (noninteractive)
|
||||
(funcall load-fn (doom-module-path :private user-login-name "init.el") t))
|
||||
(mapc load-fn (file-expand-wildcards (expand-file-name "autoload/*.el" doom-core-dir)))
|
||||
(cl-loop for (module . submodule) in (doom-module-pairs)
|
||||
for path = (doom-module-path module submodule "config.el")
|
||||
do (funcall load-fn path t))))
|
||||
(mapc #'_load (file-expand-wildcards (expand-file-name "autoload/*.el" doom-core-dir)))
|
||||
(_load (expand-file-name "init.el" doom-emacs-dir) nil 'interactive)))
|
||||
(when (or force-p (not doom-packages))
|
||||
(setq doom-packages nil)
|
||||
(funcall load-fn (expand-file-name "packages.el" doom-core-dir))
|
||||
(_load (expand-file-name "packages.el" doom-core-dir))
|
||||
(cl-loop for (module . submodule) in (doom-module-pairs)
|
||||
for path = (doom-module-path module submodule "packages.el")
|
||||
do (funcall load-fn path t)))))
|
||||
(doom|finalize))
|
||||
do (_load path 'noerror))))))
|
||||
|
||||
(defun doom-initialize-modules (modules)
|
||||
"Adds MODULES to `doom-modules'. MODULES must be in mplist format.
|
||||
|
@ -295,7 +288,7 @@ include all modules, enabled or otherwise."
|
|||
;; Certainly imprecise, especially where custom additions to
|
||||
;; load-path are concerned, but I don't mind a [small] margin of
|
||||
;; error in the plugin count in exchange for faster startup.
|
||||
(- (length load-path) (length doom--base-load-path))
|
||||
(length doom--package-load-path)
|
||||
(hash-table-size doom-modules)
|
||||
(setq doom-init-time (float-time (time-subtract after-init-time before-init-time)))))
|
||||
|
||||
|
@ -313,19 +306,17 @@ MODULES is an malformed plist of modules to load."
|
|||
(doom-initialize-modules modules)
|
||||
`(let (file-name-handler-alist)
|
||||
(setq doom-modules ',doom-modules)
|
||||
|
||||
(unless noninteractive
|
||||
(message "Doom initialized")
|
||||
,@(cl-loop for (module . submodule) in (doom-module-pairs)
|
||||
for module-path = (doom-module-path module submodule)
|
||||
collect `(load! init ,module-path t) into inits
|
||||
collect `(load! config ,module-path t) into configs
|
||||
finally return (append inits configs))
|
||||
|
||||
(when (display-graphic-p)
|
||||
(require 'server)
|
||||
(unless (server-running-p)
|
||||
(server-start)))
|
||||
|
||||
(add-hook 'doom-init-hook #'doom-packages--display-benchmark t)
|
||||
(message "Doom modules initialized"))))
|
||||
|
||||
|
@ -334,7 +325,7 @@ MODULES is an malformed plist of modules to load."
|
|||
;; Ignore package if NAME is in `doom-disabled-packages'
|
||||
(when (and (memq name doom-disabled-packages)
|
||||
(not (memq :disabled plist)))
|
||||
(setq plist (append (list :disabled t) plist)))
|
||||
(setq plist `(:disabled t ,@plist)))
|
||||
;; If byte-compiling, ignore this package if it doesn't meet the condition.
|
||||
;; This avoids false-positive load errors.
|
||||
(unless (and (bound-and-true-p byte-compile-current-file)
|
||||
|
@ -377,31 +368,26 @@ to have them return non-nil (or exploit that to overwrite Doom's config)."
|
|||
"Load a file relative to the current executing file (`load-file-name').
|
||||
|
||||
FILESYM is either a symbol or string representing the file to load. PATH is
|
||||
where to look for the file (a string representing a directory path), by default
|
||||
it is relative to `load-file-name', `byte-compile-current-file' or
|
||||
where to look for the file (a string representing a directory path). If omitted,
|
||||
the lookup is relative to `load-file-name', `byte-compile-current-file' or
|
||||
`buffer-file-name' (in that order).
|
||||
|
||||
If NOERROR is non-nil, don't throw an error if the file doesn't exist."
|
||||
(let ((path (or (and path (or (and (symbolp path) (symbol-value path))
|
||||
(and (stringp path) path)
|
||||
(and (listp path) (eval path))))
|
||||
(cl-assert (symbolp filesym) t)
|
||||
(let ((path (or path
|
||||
(and load-file-name (file-name-directory load-file-name))
|
||||
(and (bound-and-true-p byte-compile-current-file)
|
||||
(file-name-directory byte-compile-current-file))
|
||||
(and buffer-file-name
|
||||
(file-name-directory buffer-file-name))))
|
||||
(filename (cond ((stringp filesym) filesym)
|
||||
((symbolp filesym) (symbol-name filesym))
|
||||
(t (error "load! expected a string or symbol, got %s (a %s)"
|
||||
filesym (type-of filesym))))))
|
||||
(unless path
|
||||
(error "Could not find %s" filename))
|
||||
(file-name-directory buffer-file-name))
|
||||
(error "Could not detect path to look for '%s' in" filesym)))
|
||||
(filename (symbol-name filesym)))
|
||||
(let ((file (expand-file-name (concat filename ".el") path)))
|
||||
(if (file-exists-p file)
|
||||
`(load ,(file-name-sans-extension file) ,noerror
|
||||
,(not doom-debug-mode))
|
||||
(unless noerror
|
||||
(error "Could not load! file %s" file))))))
|
||||
(error "Could not load file '%s' from '%s'" file path))))))
|
||||
|
||||
(defmacro require! (module submodule &optional flags reload-p)
|
||||
"Loads the module specified by MODULE (a property) and SUBMODULE (a symbol).
|
||||
|
@ -507,8 +493,9 @@ loads MODULE SUBMODULE's packages.el file."
|
|||
t)))
|
||||
|
||||
(defun doom-packages--async-run (fn)
|
||||
(let ((compilation-filter-hook
|
||||
(list (lambda () (ansi-color-apply-on-region compilation-filter-start (point))))))
|
||||
(let* ((default-directory doom-emacs-dir)
|
||||
(compilation-filter-hook
|
||||
(list (lambda () (ansi-color-apply-on-region compilation-filter-start (point))))))
|
||||
(compile (format "%s --quick --batch -l core/core.el -f %s"
|
||||
(executable-find "emacs")
|
||||
(symbol-name fn)))
|
||||
|
@ -527,15 +514,14 @@ call `doom/reload-load-path' remotely (through emacsclient)."
|
|||
(interactive)
|
||||
(byte-recompile-file (expand-file-name "core.el" doom-core-dir) t)
|
||||
(cond (noninteractive
|
||||
(message "Reloading...")
|
||||
(require 'server)
|
||||
(when (server-running-p)
|
||||
(message "Reloading active Emacs session...")
|
||||
(server-eval-at server-name '(doom//reload-load-path))))
|
||||
(t
|
||||
(doom-initialize t)
|
||||
(message "Reloaded %d packages" (length doom--package-load-path))
|
||||
(run-with-timer 1 nil #'redraw-display)
|
||||
(run-hooks 'doom-reload-hook))))
|
||||
((let ((noninteractive t))
|
||||
(doom-initialize-load-path t)
|
||||
(message "%d packages reloaded" (length doom--package-load-path))
|
||||
(run-hooks 'doom-reload-hook)))))
|
||||
|
||||
(defun doom//reload-autoloads ()
|
||||
"Refreshes the autoloads.el file, specified by `doom-autoload-file'.
|
||||
|
@ -555,7 +541,7 @@ This should be run whenever init.el or an autoload file is modified. Running
|
|||
;; state. `doom-initialize-packages' will have side effects otherwise.
|
||||
(and (doom-packages--async-run 'doom//reload-autoloads)
|
||||
(load doom-autoload-file))
|
||||
(doom-initialize-packages)
|
||||
(doom-initialize-packages t)
|
||||
(let ((targets
|
||||
(file-expand-wildcards
|
||||
(expand-file-name "autoload/*.el" doom-core-dir))))
|
||||
|
@ -571,13 +557,15 @@ This should be run whenever init.el or an autoload file is modified. Running
|
|||
(delete-file doom-autoload-file)
|
||||
(message "Deleted old autoloads.el"))
|
||||
(dolist (file (reverse targets))
|
||||
(message (cond ((not (doom-packages--read-if-cookies file))
|
||||
"Ignoring %s")
|
||||
((update-file-autoloads file nil doom-autoload-file)
|
||||
"Nothing in %s")
|
||||
(t
|
||||
"Scanned %s"))
|
||||
(file-relative-name file doom-emacs-dir)))
|
||||
(message
|
||||
(cond ((not (doom-packages--read-if-cookies file))
|
||||
"⚠ Ignoring %s")
|
||||
((update-file-autoloads file nil doom-autoload-file)
|
||||
"✕ Nothing in %s")
|
||||
(t
|
||||
"✓ Scanned %s"))
|
||||
(file-relative-name file doom-emacs-dir)))
|
||||
(make-directory (file-name-directory doom-autoload-file) t)
|
||||
(let ((buf (get-file-buffer doom-autoload-file))
|
||||
current-sexp)
|
||||
(unwind-protect
|
||||
|
@ -646,33 +634,42 @@ If RECOMPILE-P is non-nil, only recompile out-of-date files."
|
|||
(error "No targets to compile"))
|
||||
(let ((use-package-expand-minimally t))
|
||||
(push (expand-file-name "init.el" doom-emacs-dir) compile-targets)
|
||||
(dolist (target compile-targets)
|
||||
(when (or (not recompile-p)
|
||||
(let ((elc-file (byte-compile-dest-file target)))
|
||||
(and (file-exists-p elc-file)
|
||||
(file-newer-than-file-p file elc-file))))
|
||||
(let ((result (if (doom-packages--read-if-cookies target)
|
||||
(byte-compile-file target)
|
||||
'no-byte-compile))
|
||||
(short-name (file-relative-name target doom-emacs-dir)))
|
||||
(cl-incf
|
||||
(cond ((eq result 'no-byte-compile)
|
||||
(message! (dark (white "Ignored %s" short-name)))
|
||||
total-noop)
|
||||
((null result)
|
||||
(message! (red "Failed to compile %s" short-name))
|
||||
total-fail)
|
||||
(t
|
||||
(message! (green "Compiled %s" short-name))
|
||||
(quiet! (load target t t))
|
||||
total-ok))))))
|
||||
(message!
|
||||
(bold
|
||||
(color (if (= total-fail 0) 'green 'red)
|
||||
"%s %s file(s) %s"
|
||||
(if recompile-p "Recompiled" "Compiled")
|
||||
(format "%d/%d" total-ok (- (length compile-targets) total-noop))
|
||||
(format "(%s ignored)" total-noop)))))))))
|
||||
(condition-case ex
|
||||
(progn
|
||||
(dolist (target compile-targets)
|
||||
(when (or (not recompile-p)
|
||||
(let ((elc-file (byte-compile-dest-file target)))
|
||||
(and (file-exists-p elc-file)
|
||||
(file-newer-than-file-p file elc-file))))
|
||||
(let ((result (if (doom-packages--read-if-cookies target)
|
||||
(byte-compile-file target)
|
||||
'no-byte-compile))
|
||||
(short-name (file-relative-name target doom-emacs-dir)))
|
||||
(cl-incf
|
||||
(cond ((eq result 'no-byte-compile)
|
||||
(message! (dark (white "⚠ Ignored %s" short-name)))
|
||||
total-noop)
|
||||
((null result)
|
||||
(message! (red "✕ Failed to compile %s" short-name))
|
||||
total-fail)
|
||||
(t
|
||||
(message! (green "✓ Compiled %s" short-name))
|
||||
(quiet! (load target t t))
|
||||
total-ok))))))
|
||||
(message!
|
||||
(bold
|
||||
(color (if (= total-fail 0) 'green 'red)
|
||||
"%s %s file(s) %s"
|
||||
(if recompile-p "Recompiled" "Compiled")
|
||||
(format "%d/%d" total-ok (- (length compile-targets) total-noop))
|
||||
(format "(%s ignored)" total-noop)))))
|
||||
(error
|
||||
(message! (red "\n%%s\n\n%%s\n\n%%s")
|
||||
"There were breaking errors."
|
||||
(error-message-string ex)
|
||||
"Reverting changes...")
|
||||
(doom//clean-byte-compiled-files)
|
||||
(message! (green "Finished (nothing was byte-compiled)")))))))))
|
||||
|
||||
(defun doom//byte-compile-core (&optional recompile-p)
|
||||
"Byte compile the core Doom files.
|
||||
|
@ -683,7 +680,11 @@ likely change core files directly).
|
|||
|
||||
If RECOMPILE-P is non-nil, only recompile out-of-date core files."
|
||||
(interactive "P")
|
||||
(doom//byte-compile (list "core") recompile-p))
|
||||
(if (not noninteractive)
|
||||
;; This is done in another instance to protect the current session's
|
||||
;; state. `doom-initialize-packages' will have side effects otherwise.
|
||||
(doom-packages--async-run 'doom//byte-compile-core)
|
||||
(doom//byte-compile (list "core") recompile-p)))
|
||||
|
||||
(defun doom//byte-recompile-plugins ()
|
||||
"Recompile all installed plugins. If you're getting odd errors after upgrading
|
||||
|
@ -692,18 +693,18 @@ If RECOMPILE-P is non-nil, only recompile out-of-date core files."
|
|||
(byte-recompile-directory package-user-dir 0 t))
|
||||
|
||||
(defun doom//clean-byte-compiled-files ()
|
||||
"Delete all the compiled elc files in your Emacs configuration.
|
||||
|
||||
This excludes compiled packages in `doom-packages-dir'.'"
|
||||
"Delete all the compiled elc files in your Emacs configuration. This excludes
|
||||
compiled packages.'"
|
||||
(interactive)
|
||||
(let ((targets (append (list (expand-file-name "init.elc" doom-emacs-dir))
|
||||
(directory-files-recursively doom-core-dir "\\.elc$")
|
||||
(directory-files-recursively doom-modules-dir "\\.elc$"))))
|
||||
(directory-files-recursively doom-modules-dir "\\.elc$")))
|
||||
(default-directory doom-emacs-dir))
|
||||
(unless (cl-loop for path in targets
|
||||
if (file-exists-p path)
|
||||
collect path
|
||||
and do (delete-file path)
|
||||
and do (message "Deleted %s" (file-relative-name path)))
|
||||
and do (message "✓ Deleted %s" (file-relative-name path)))
|
||||
(message "Everything is clean"))))
|
||||
|
||||
|
||||
|
|
|
@ -87,13 +87,13 @@ recognized by DOOM's popup system. They are:
|
|||
;;
|
||||
;;
|
||||
|
||||
(defvar doom-popup-parameters
|
||||
'(:esc :modeline :transient :fit :align :size)
|
||||
"TODO")
|
||||
;; (defvar doom-popup-parameters
|
||||
;; '(:esc :modeline :transient :fit :align :size)
|
||||
;; "TODO")
|
||||
|
||||
(defvar doom-popup-whitelist
|
||||
'(("^ ?\\*" :size 15 :noselect t :autokill t :autoclose t))
|
||||
"TODO")
|
||||
;; (defvar doom-popup-whitelist
|
||||
;; '(("^ ?\\*" :size 15 :noselect t :autokill t :autoclose t))
|
||||
;; "TODO")
|
||||
|
||||
(defvar doom-popup-blacklist
|
||||
'("^\\*magit")
|
||||
|
@ -122,7 +122,7 @@ recognized by DOOM's popup system. They are:
|
|||
("*Backtrace*" :size 20 :noselect t)
|
||||
("*Warnings*" :size 12 :noselect t :autofit t)
|
||||
("*Messages*" :size 12 :noselect t)
|
||||
("*Help*" :size 0.3)
|
||||
("*Help*" :size 0.3 :autokill t)
|
||||
("^\\*.*Shell Command.*\\*$" :regexp t :size 20 :noselect t :autokill t)
|
||||
(apropos-mode :size 0.3 :autokill t :autoclose t)
|
||||
(Buffer-menu-mode :size 20 :autokill t)
|
||||
|
@ -144,10 +144,20 @@ recognized by DOOM's popup system. They are:
|
|||
(defun doom-display-buffer-action (buffer alist)
|
||||
(shackle-display-buffer buffer alist (shackle-match buffer)))
|
||||
|
||||
(defun doom|autokill-popups ()
|
||||
(or (not (doom-popup-p))
|
||||
(prog1 (when (and (not doom-popup-inhibit-autokill)
|
||||
(plist-get doom-popup-rules :autokill))
|
||||
(doom-popup-mode -1)
|
||||
(when-let* ((process (get-buffer-process (current-buffer))))
|
||||
(set-process-query-on-exit-flag process nil))
|
||||
t))))
|
||||
|
||||
(add-hook! doom-post-init
|
||||
(setq display-buffer-alist
|
||||
(cons '(doom-display-buffer-condition doom-display-buffer-action)
|
||||
display-buffer-alist)))
|
||||
display-buffer-alist))
|
||||
(add-hook 'kill-buffer-query-functions #'doom|autokill-popups))
|
||||
|
||||
;; no modeline in popups
|
||||
(add-hook 'doom-popup-mode-hook #'doom|hide-modeline-in-popup)
|
||||
|
@ -170,7 +180,7 @@ recognized by DOOM's popup system. They are:
|
|||
(define-key map [escape] #'doom/popup-close-maybe)
|
||||
(define-key map (kbd "ESC") #'doom/popup-close-maybe)
|
||||
(define-key map [remap quit-window] #'doom/popup-close-maybe)
|
||||
(define-key map [remap doom/kill-this-buffer] #'delete-window)
|
||||
(define-key map [remap doom/kill-this-buffer] #'doom/popup-close-maybe)
|
||||
(define-key map [remap split-window-right] #'ignore)
|
||||
(define-key map [remap split-window-below] #'ignore)
|
||||
(define-key map [remap split-window-horizontally] #'ignore)
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
;;; core-projects.el -*- lexical-binding: t; -*-
|
||||
|
||||
(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.")
|
||||
|
||||
(def-package! projectile
|
||||
:hook (doom-init . projectile-mode)
|
||||
:init
|
||||
(setq projectile-cache-file (concat doom-cache-dir "projectile.cache")
|
||||
projectile-enable-caching (not noninteractive)
|
||||
|
@ -14,17 +11,23 @@ state are passed in.")
|
|||
projectile-globally-ignored-files '(".DS_Store" "Icon
" "TAGS")
|
||||
projectile-globally-ignored-file-suffixes '(".elc" ".pyc" ".o"))
|
||||
|
||||
(add-hook 'doom-init-hook #'projectile-mode)
|
||||
:config
|
||||
(add-hook 'dired-before-readin-hook #'projectile-track-known-projects-find-file-hook)
|
||||
(add-hook 'find-file-hook #'doom|autoload-project-mode)
|
||||
|
||||
;; a more generic project root file
|
||||
(push ".project" projectile-project-root-files-bottom-up)
|
||||
|
||||
(nconc projectile-globally-ignored-directories (list (abbreviate-file-name doom-local-dir) ".sync"))
|
||||
(nconc projectile-other-file-alist '(("css" . ("scss" "sass" "less" "style"))
|
||||
("scss" . ("css"))
|
||||
("sass" . ("css"))
|
||||
("less" . ("css"))
|
||||
("styl" . ("css"))))
|
||||
(setq projectile-globally-ignored-directories
|
||||
(append projectile-globally-ignored-directories
|
||||
(list (abbreviate-file-name doom-local-dir) ".sync"))
|
||||
projectile-other-file-alist
|
||||
(append projectile-other-file-alist
|
||||
'(("css" . ("scss" "sass" "less" "styl"))
|
||||
("scss" . ("css"))
|
||||
("sass" . ("css"))
|
||||
("less" . ("css"))
|
||||
("styl" . ("css")))))
|
||||
|
||||
;; Projectile root-searching functions can cause an infinite loop on TRAMP
|
||||
;; connections, so disable them.
|
||||
|
@ -76,21 +79,48 @@ which case they're relative to `default-directory'). If they start with a slash,
|
|||
they are absolute."
|
||||
(doom--resolve-path-forms files (doom-project-root)))
|
||||
|
||||
(defun doom-project-find-file (dir)
|
||||
"Fuzzy-find a file under DIR."
|
||||
(let ((default-directory dir)
|
||||
;; Necessary to isolate this search from the current project
|
||||
projectile-project-name
|
||||
projectile-require-project-root
|
||||
projectile-cached-buffer-file-name
|
||||
projectile-cached-project-root)
|
||||
(call-interactively
|
||||
;; completion modules may remap this command
|
||||
(or (command-remapping #'projectile-find-file)
|
||||
#'projectile-find-file))))
|
||||
|
||||
(defun doom-project-browse (dir)
|
||||
"Traverse a file structure starting linearly from DIR."
|
||||
(let ((default-directory dir))
|
||||
(call-interactively
|
||||
;; completion modules may remap this command
|
||||
(or (command-remapping #'find-file)
|
||||
#'find-file))))
|
||||
|
||||
|
||||
;;
|
||||
;; Projects
|
||||
;;
|
||||
|
||||
(defvar-local doom-project nil
|
||||
"A list of project mode to enable. Used for .dir-locals.el.")
|
||||
"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|autoload-project-mode ()
|
||||
"Auto-enable projects listed in `doom-project', which is meant to be set from
|
||||
.dir-locals.el files."
|
||||
(cl-loop for mode in doom-project
|
||||
unless (symbol-value mode)
|
||||
do (funcall mode)))
|
||||
(add-hook 'after-change-major-mode-hook #'doom|autoload-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)))))
|
||||
|
||||
(defmacro def-project-mode! (name &rest plist)
|
||||
"Define a project minor-mode named NAME (a symbol) and declare where and how
|
||||
|
@ -101,8 +131,7 @@ own settings, keymaps, hooks, snippets, etc.
|
|||
|
||||
This creates NAME-hook and NAME-map as well.
|
||||
|
||||
A project can be enabled through .dir-locals.el too, if `doom-project' is set to
|
||||
the name (symbol) of the project mode(s) to enable.
|
||||
A project can be enabled through .dir-locals.el too, by setting `doom-project'.
|
||||
|
||||
PLIST may contain any of these properties, which are all checked to see if NAME
|
||||
should be activated. If they are *all* true, NAME is activated.
|
||||
|
@ -151,7 +180,7 @@ Relevant: `doom-project-hook'."
|
|||
:keymap (make-sparse-keymap)
|
||||
(if (not ,name)
|
||||
,exit-form
|
||||
(run-hook-with-args 'doom-project-hook ',name)
|
||||
(run-hook-with-args 'doom-project-hook ',name ,name)
|
||||
,(when load-form
|
||||
`(unless ,init-var
|
||||
,load-form
|
||||
|
|
|
@ -50,6 +50,7 @@ shorter major mode name in the mode-line. See `doom|set-mode-name'.")
|
|||
max-mini-window-height 0.3
|
||||
mode-line-default-help-echo nil ; disable mode-line mouseovers
|
||||
mouse-yank-at-point t ; middle-click paste at point, not at click
|
||||
ibuffer-use-other-window t
|
||||
resize-mini-windows 'grow-only ; Minibuffer resizing
|
||||
show-help-function nil ; hide :help-echo text
|
||||
split-width-threshold 160 ; favor horizontal splits
|
||||
|
@ -182,9 +183,13 @@ local value, whether or not it's permanent-local. Therefore, we cycle
|
|||
(when (fontp doom-variable-pitch-font)
|
||||
(set-face-attribute 'variable-pitch frame :font doom-variable-pitch-font)))
|
||||
('error
|
||||
(lwarn 'doom-ui :error
|
||||
"Failed to set fonts because %s"
|
||||
(error-message-string ex))))
|
||||
(if (string-prefix-p "Font not available: " (error-message-string ex))
|
||||
(lwarn 'doom-ui :warning
|
||||
"Could not find the '%s' font on your system, falling back to system font"
|
||||
(font-get (caddr ex) :family))
|
||||
(lwarn 'doom-ui :error
|
||||
"Unexpected error while initializing fonts: %s"
|
||||
(error-message-string ex)))))
|
||||
(run-hooks 'doom-init-ui-hook))
|
||||
|
||||
(defun doom|reload-ui-in-daemon (frame)
|
||||
|
@ -224,6 +229,14 @@ local value, whether or not it's permanent-local. Therefore, we cycle
|
|||
(add-hook! '(doom-post-init-hook minibuffer-setup-hook)
|
||||
#'doom|no-fringes-in-minibuffer)
|
||||
|
||||
(defun doom|protect-visible-buffers ()
|
||||
"Don't kill the current buffer if it is visible in another window (bury it
|
||||
instead)."
|
||||
(not (delq (selected-window)
|
||||
(get-buffer-window-list nil nil t))))
|
||||
(add-hook! doom-post-init
|
||||
(add-hook 'kill-buffer-query-functions #'doom|protect-visible-buffers))
|
||||
|
||||
|
||||
;;
|
||||
;; Plugins
|
||||
|
@ -237,14 +250,11 @@ local value, whether or not it's permanent-local. Therefore, we cycle
|
|||
(defun doom*disable-all-the-icons-in-tty (orig-fn &rest args)
|
||||
(when (display-graphic-p)
|
||||
(apply orig-fn args)))
|
||||
|
||||
;; all-the-icons doesn't work in the terminal, so we "disable" it.
|
||||
(advice-add #'all-the-icons-octicon :around #'doom*disable-all-the-icons-in-tty)
|
||||
(advice-add #'all-the-icons-material :around #'doom*disable-all-the-icons-in-tty)
|
||||
(advice-add #'all-the-icons-faicon :around #'doom*disable-all-the-icons-in-tty)
|
||||
(advice-add #'all-the-icons-fileicon :around #'doom*disable-all-the-icons-in-tty)
|
||||
(advice-add #'all-the-icons-wicon :around #'doom*disable-all-the-icons-in-tty)
|
||||
(advice-add #'all-the-icons-alltheicon :around #'doom*disable-all-the-icons-in-tty))
|
||||
(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)))
|
||||
|
||||
(def-package! fringe-helper
|
||||
:commands (fringe-helper-define fringe-helper-convert)
|
||||
|
@ -255,8 +265,7 @@ local value, whether or not it's permanent-local. Therefore, we cycle
|
|||
|
||||
(def-package! hideshow ; built-in
|
||||
:commands (hs-minor-mode hs-toggle-hiding hs-already-hidden-p)
|
||||
:config
|
||||
(setq hs-hide-comments-when-hiding-all nil))
|
||||
:config (setq hs-hide-comments-when-hiding-all nil))
|
||||
|
||||
(def-package! highlight-indentation
|
||||
:commands (highlight-indentation-mode highlight-indentation-current-column-mode))
|
||||
|
@ -306,17 +315,20 @@ local value, whether or not it's permanent-local. Therefore, we cycle
|
|||
;; Helps us distinguish stacked delimiter pairs. Especially in parentheses-drunk
|
||||
;; languages like Lisp.
|
||||
(def-package! rainbow-delimiters
|
||||
:commands rainbow-delimiters-mode
|
||||
:config (setq rainbow-delimiters-max-face-count 3)
|
||||
:init (add-hook 'lisp-mode-hook #'rainbow-delimiters-mode))
|
||||
:hook (lisp-mode . rainbow-delimiters-mode)
|
||||
:config (setq rainbow-delimiters-max-face-count 3))
|
||||
|
||||
;; For a distractions-free-like UI, that dynamically resizes margets and can
|
||||
;; center a buffer.
|
||||
(def-package! visual-fill-column
|
||||
:commands visual-fill-column-mode
|
||||
:config
|
||||
(setq-default visual-fill-column-center-text nil
|
||||
visual-fill-column-width fill-column))
|
||||
(setq-default
|
||||
visual-fill-column-center-text t
|
||||
visual-fill-column-width
|
||||
;; take Emacs 26 line numbers into account
|
||||
(+ (if (boundp 'display-line-numbers) 6 0)
|
||||
fill-column)))
|
||||
|
||||
|
||||
;;
|
||||
|
|
147
core/core.el
147
core/core.el
|
@ -18,14 +18,14 @@
|
|||
;; Autoloaded functions are in core/autoload/*.el and modules/*/*/autoload.el or
|
||||
;; modules/*/*/autoload/*.el.
|
||||
|
||||
(defvar doom-version "2.0.8"
|
||||
(defvar doom-version "2.0.9"
|
||||
"Current version of DOOM emacs.")
|
||||
|
||||
(defvar doom-debug-mode (or (getenv "DEBUG") init-file-debug)
|
||||
"If non-nil, all doom functions will be verbose. Set DEBUG=1 in the command
|
||||
line or use --debug-init to enable this.")
|
||||
|
||||
(defvar doom-emacs-dir (expand-file-name user-emacs-directory)
|
||||
(defvar doom-emacs-dir (file-truename user-emacs-directory)
|
||||
"The path to this emacs.d directory.")
|
||||
|
||||
(defvar doom-core-dir (concat doom-emacs-dir "core/")
|
||||
|
@ -34,38 +34,27 @@ line or use --debug-init to enable this.")
|
|||
(defvar doom-modules-dir (concat doom-emacs-dir "modules/")
|
||||
"Where configuration modules are stored.")
|
||||
|
||||
|
||||
;; Multi-host directories: I namespace `doom-etc-dir' and `doom-cache-dir' with
|
||||
;; host names because I use the same (often symlinked) emacs.d across several
|
||||
;; computers -- often simultaneously. Cache or other temporary files would
|
||||
;; conflict otherwise.
|
||||
|
||||
(defvar doom-local-dir (concat doom-emacs-dir ".local/")
|
||||
"Root directory for local Emacs files. Use this as permanent storage for files
|
||||
that are safe to share across systems (if this config is symlinked across
|
||||
several computers).")
|
||||
|
||||
(defvar doom-host-dir (concat doom-local-dir "@" (system-name))
|
||||
"Directory for hostname-specific file storage. Used by `doom-etc-dir' and
|
||||
`doom-cache-dir'.")
|
||||
(defvar doom-etc-dir (concat doom-local-dir "etc/")
|
||||
"Directory for non-volatile storage.
|
||||
|
||||
(defvar doom-etc-dir (concat doom-host-dir "/etc/")
|
||||
"Host-namespaced directory for non-volatile storage. These are not deleted or
|
||||
tampored with by DOOM functions. Use this for dependencies like servers or
|
||||
config files that are stable (i.e. it should be unlikely that you need to delete
|
||||
them if something goes wrong).")
|
||||
Use this for files that don't change much, like servers binaries, external
|
||||
dependencies or long-term shared data.")
|
||||
|
||||
(defvar doom-cache-dir (concat doom-host-dir "/cache/")
|
||||
"Host-namespaced directory for volatile storage. Deleted when `doom/reset' is
|
||||
called. Use this for transient files that are generated on the fly like caches
|
||||
and temporary files. Anything that may need to be cleared if there are
|
||||
problems.")
|
||||
(defvar doom-cache-dir (concat doom-local-dir "cache/")
|
||||
"Directory for volatile storage.
|
||||
|
||||
Use this for files that change often, like cache files.")
|
||||
|
||||
(defvar doom-packages-dir (concat doom-local-dir "packages/")
|
||||
"Where package.el and quelpa plugins (and their caches) are stored.")
|
||||
|
||||
(defvar doom-autoload-file (concat doom-local-dir "autoloads.el")
|
||||
"Location of the autoloads file generated by `doom/reload-autoloads'.")
|
||||
"Where `doom//reload-autoloads' will generate its autoloads file.")
|
||||
|
||||
(defgroup doom nil
|
||||
"DOOM Emacs, an Emacs configuration for a stubborn, shell-dwelling and
|
||||
|
@ -121,13 +110,14 @@ melodramatic ex-vimmer disappointed with the text-editor status quo."
|
|||
(load custom-file t t)
|
||||
|
||||
;; be quiet at startup; don't load or display anything unnecessary
|
||||
(advice-add #'display-startup-echo-area-message :override #'ignore)
|
||||
(setq inhibit-startup-message t
|
||||
inhibit-startup-echo-area-message user-login-name
|
||||
inhibit-default-init t
|
||||
initial-major-mode 'fundamental-mode
|
||||
initial-scratch-message nil
|
||||
mode-line-format nil)
|
||||
(unless noninteractive
|
||||
(advice-add #'display-startup-echo-area-message :override #'ignore)
|
||||
(setq inhibit-startup-message t
|
||||
inhibit-startup-echo-area-message user-login-name
|
||||
inhibit-default-init t
|
||||
initial-major-mode 'fundamental-mode
|
||||
initial-scratch-message nil
|
||||
mode-line-format nil))
|
||||
|
||||
;; Custom init hooks; clearer than `after-init-hook', `emacs-startup-hook', and
|
||||
;; `window-setup-hook'.
|
||||
|
@ -152,33 +142,23 @@ ability to invoke the debugger in debug mode."
|
|||
(car ex) fn (error-message-string ex))))
|
||||
nil)
|
||||
|
||||
(defun doom|finalize ()
|
||||
(unless (or doom-init-p noninteractive)
|
||||
(dolist (hook '(doom-init-hook doom-post-init-hook))
|
||||
(run-hook-wrapped hook #'doom-try-run-hook hook))
|
||||
(setq doom-init-p t))
|
||||
|
||||
;; Don't keep gc-cons-threshold too high. It helps to stave off the GC while
|
||||
;; Emacs starts up, but afterwards it causes stuttering and random freezes. So
|
||||
;; reset it to a reasonable default.
|
||||
(setq gc-cons-threshold 16777216
|
||||
gc-cons-percentage 0.1
|
||||
file-name-handler-alist doom--file-name-handler-alist)
|
||||
t)
|
||||
|
||||
|
||||
;;;
|
||||
;; Initialize
|
||||
(eval-and-compile
|
||||
(defvar doom--file-name-handler-alist file-name-handler-alist)
|
||||
(setq gc-cons-threshold 402653184
|
||||
gc-cons-percentage 0.6
|
||||
file-name-handler-alist nil)
|
||||
(unless (or after-init-time noninteractive)
|
||||
;; One of the contributors to long startup times is the garbage collector,
|
||||
;; so we up its memory threshold, temporarily. It is reset later in
|
||||
;; `doom|finalize'.
|
||||
(setq gc-cons-threshold 402653184
|
||||
gc-cons-percentage 0.6
|
||||
file-name-handler-alist nil))
|
||||
|
||||
(require 'core-packages (concat doom-core-dir "core-packages"))
|
||||
(eval-when-compile
|
||||
(doom-initialize))
|
||||
(setq load-path (eval-when-compile load-path)
|
||||
(require 'cl-lib)
|
||||
(load (concat doom-core-dir "core-packages") nil t)
|
||||
(setq load-path (eval-when-compile (doom-initialize t)
|
||||
(doom-initialize-load-path t))
|
||||
doom--package-load-path (eval-when-compile doom--package-load-path))
|
||||
|
||||
(load! core-lib)
|
||||
|
@ -195,10 +175,71 @@ ability to invoke the debugger in debug mode."
|
|||
(load! core-popups) ; taming sudden yet inevitable windows
|
||||
(load! core-editor) ; baseline configuration for text editing
|
||||
(load! core-projects) ; making Emacs project-aware
|
||||
(load! core-keybinds))) ; centralized keybind system + which-key
|
||||
(load! core-keybinds)) ; centralized keybind system + which-key
|
||||
|
||||
(add-hook! '(emacs-startup-hook doom-reload-hook)
|
||||
#'doom|finalize)
|
||||
(defun doom|finalize ()
|
||||
"Run `doom-init-hook', `doom-post-init-hook' and reset `gc-cons-threshold',
|
||||
`gc-cons-percentage' and `file-name-handler-alist'."
|
||||
(unless (or (not after-init-time) noninteractive)
|
||||
(dolist (hook '(doom-init-hook doom-post-init-hook))
|
||||
(run-hook-wrapped hook #'doom-try-run-hook hook)))
|
||||
|
||||
;; If you forget to reset this, you'll get stuttering and random freezes!
|
||||
(setq gc-cons-threshold 16777216
|
||||
gc-cons-percentage 0.1
|
||||
file-name-handler-alist doom--file-name-handler-alist)
|
||||
t)
|
||||
|
||||
(add-hook! '(emacs-startup-hook doom-reload-hook)
|
||||
#'doom|finalize))
|
||||
|
||||
|
||||
;;
|
||||
;; Emacs fixes/hacks
|
||||
;;
|
||||
|
||||
;; Automatic minor modes
|
||||
(defvar doom-auto-minor-mode-alist '()
|
||||
"Alist mapping filename patterns to corresponding minor mode functions, like
|
||||
`auto-mode-alist'. All elements of this alist are checked, meaning you can
|
||||
enable multiple minor modes for the same regexp.")
|
||||
|
||||
(defun doom|enable-minor-mode-maybe ()
|
||||
"Check file name against `doom-auto-minor-mode-alist'."
|
||||
(when buffer-file-name
|
||||
(let ((name buffer-file-name)
|
||||
(remote-id (file-remote-p buffer-file-name))
|
||||
(alist doom-auto-minor-mode-alist))
|
||||
;; Remove backup-suffixes from file name.
|
||||
(setq name (file-name-sans-versions name))
|
||||
;; Remove remote file name identification.
|
||||
(when (and (stringp remote-id)
|
||||
(string-match-p (regexp-quote remote-id) name))
|
||||
(setq name (substring name (match-end 0))))
|
||||
(while (and alist (caar alist) (cdar alist))
|
||||
(if (string-match-p (caar alist) name)
|
||||
(funcall (cdar alist) 1))
|
||||
(setq alist (cdr alist))))))
|
||||
(add-hook 'find-file-hook #'doom|enable-minor-mode-maybe)
|
||||
|
||||
(defun doom*set-indirect-buffer-filename (orig-fn base-buffer name &optional clone)
|
||||
"In indirect buffers, `buffer-file-name' is nil, which can cause problems
|
||||
with functions that require it (like modeline segments)."
|
||||
(let ((file-name (buffer-file-name base-buffer))
|
||||
(buffer (funcall orig-fn base-buffer name clone)))
|
||||
(when (and file-name buffer)
|
||||
(with-current-buffer buffer
|
||||
(unless buffer-file-name
|
||||
(setq buffer-file-name file-name
|
||||
buffer-file-truename (file-truename file-name)))))
|
||||
buffer))
|
||||
(advice-add #'make-indirect-buffer :around #'doom*set-indirect-buffer-filename)
|
||||
|
||||
(defun doom*no-authinfo-for-tramp (orig-fn &rest args)
|
||||
"Don't look into .authinfo for local sudo TRAMP buffers."
|
||||
(let ((auth-sources (if (equal tramp-current-method "sudo") nil auth-sources)))
|
||||
(apply orig-fn args)))
|
||||
(advice-add #'tramp-read-passwd :around #'doom*no-authinfo-for-tramp)
|
||||
|
||||
(provide 'core)
|
||||
;;; core.el ends here
|
||||
|
|
|
@ -1,24 +1,23 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; core/test/autoload-buffers.el
|
||||
|
||||
(defmacro -with-temp-buffers! (buffer-args &rest body)
|
||||
(defmacro with-temp-buffers!! (buffer-args &rest body)
|
||||
(declare (indent defun))
|
||||
(let (buffers)
|
||||
(dolist (bsym buffer-args)
|
||||
(push `(,bsym (get-buffer-create ,(symbol-name bsym)))
|
||||
buffers))
|
||||
`(save-window-excursion
|
||||
(cl-flet ((buffer-list
|
||||
(lambda ()
|
||||
(cl-remove-if-not #'buffer-live-p (list ,@(reverse (mapcar #'car buffers)))))))
|
||||
(let* (persp-mode
|
||||
,@buffers)
|
||||
,@body
|
||||
(mapc #'kill-buffer (buffer-list)))))))
|
||||
`(cl-flet ((buffer-list
|
||||
(lambda ()
|
||||
(cl-remove-if-not #'buffer-live-p (list ,@(reverse (mapcar #'car buffers)))))))
|
||||
(let* (persp-mode
|
||||
,@buffers)
|
||||
,@body
|
||||
(mapc #'kill-buffer (buffer-list))))))
|
||||
|
||||
;;
|
||||
(def-test! get-buffers
|
||||
(-with-temp-buffers! (a b c)
|
||||
(with-temp-buffers!! (a b c)
|
||||
(should (cl-every #'buffer-live-p (buffer-list)))
|
||||
(should (equal (buffer-list) (list a b c)))
|
||||
(dolist (buf (list (cons a doom-emacs-dir)
|
||||
|
@ -26,6 +25,7 @@
|
|||
(cons c "/tmp/")))
|
||||
(with-current-buffer (car buf)
|
||||
(setq-local default-directory (cdr buf))))
|
||||
(projectile-mode +1)
|
||||
(with-current-buffer a
|
||||
;; should produce all buffers
|
||||
(let ((buffers (doom-buffer-list)))
|
||||
|
@ -37,11 +37,12 @@
|
|||
;; If no project is available, just get all buffers
|
||||
(with-current-buffer c
|
||||
(let ((buffers (doom-project-buffer-list)))
|
||||
(should (cl-every (lambda (x) (memq x buffers)) (list a b c)))))))
|
||||
(should (cl-every (lambda (x) (memq x buffers)) (list a b c)))))
|
||||
(projectile-mode -1)))
|
||||
|
||||
(def-test! real-buffers
|
||||
(let (doom-real-buffer-functions)
|
||||
(-with-temp-buffers! (a b c d)
|
||||
(with-temp-buffers!! (a b c d)
|
||||
(dolist (buf (list a b))
|
||||
(with-current-buffer buf
|
||||
(setq-local buffer-file-name "x")))
|
||||
|
@ -62,7 +63,7 @@
|
|||
;; `doom-visible-buffers'
|
||||
;; `doom-buried-buffers'
|
||||
(def-test! visible-buffers-and-windows
|
||||
(-with-temp-buffers! (a b c d)
|
||||
(with-temp-buffers!! (a b c d)
|
||||
(switch-to-buffer a)
|
||||
(should (eq (current-buffer) a))
|
||||
(should (eq (selected-window) (get-buffer-window a)))
|
||||
|
@ -77,7 +78,7 @@
|
|||
|
||||
;; `doom-matching-buffers'
|
||||
(def-test! matching-buffers
|
||||
(-with-temp-buffers! (a b c)
|
||||
(with-temp-buffers!! (a b c)
|
||||
(let ((buffers (doom-matching-buffers "^[ac]$")))
|
||||
(should (= 2 (length buffers)))
|
||||
(should (cl-every #'bufferp buffers))
|
||||
|
@ -86,7 +87,7 @@
|
|||
|
||||
;; `doom-buffers-in-mode'
|
||||
(def-test! buffers-in-mode
|
||||
(-with-temp-buffers! (a b c d e)
|
||||
(with-temp-buffers!! (a b c d e)
|
||||
(dolist (buf (list a b))
|
||||
(with-current-buffer buf
|
||||
(emacs-lisp-mode)))
|
||||
|
@ -101,7 +102,7 @@
|
|||
|
||||
;; `doom-kill-buffer'
|
||||
(def-test! kill-buffer
|
||||
(-with-temp-buffers! (a b)
|
||||
(with-temp-buffers!! (a b)
|
||||
(doom-kill-buffer a)
|
||||
(should-not (buffer-live-p a))
|
||||
;; modified buffer
|
||||
|
@ -112,7 +113,7 @@
|
|||
|
||||
;; `doom--cycle-real-buffers'
|
||||
(def-test! kill-buffer-then-show-real-buffer
|
||||
(-with-temp-buffers! (a b c d)
|
||||
(with-temp-buffers!! (a b c d)
|
||||
(dolist (buf (list a b d))
|
||||
(with-current-buffer buf
|
||||
(setq-local buffer-file-name "x")))
|
||||
|
@ -131,4 +132,4 @@
|
|||
;; TODO doom/kill-all-buffers
|
||||
;; TODO doom/kill-other-buffers
|
||||
;; TODO doom/kill-matching-buffers
|
||||
;; TODO doom/cleanup-buffers
|
||||
;; TODO doom/cleanup-session
|
||||
|
|
|
@ -2,18 +2,16 @@
|
|||
;;; core/test/autoload-debug.el
|
||||
|
||||
(def-test! what-face
|
||||
(with-temp-buffer
|
||||
(insert (propertize "Hello " 'face 'font-lock-keyword-face))
|
||||
(insert "world")
|
||||
(insert (propertize "Hello " 'face 'font-lock-keyword-face))
|
||||
(insert "world")
|
||||
|
||||
(should (equal (doom/what-face (point-min)) '((font-lock-keyword-face) ())))
|
||||
(should-not (doom/what-face (point-max)))))
|
||||
(should (equal (doom/what-face (point-min)) '((font-lock-keyword-face) ())))
|
||||
(should-not (doom/what-face (point-max))))
|
||||
|
||||
(def-test! what-face-overlays
|
||||
(with-temp-buffer
|
||||
(insert "Hello world")
|
||||
(let ((ov (make-overlay 1 6)))
|
||||
(overlay-put ov 'face 'font-lock-keyword-face))
|
||||
(insert "Hello world")
|
||||
(let ((ov (make-overlay 1 6)))
|
||||
(overlay-put ov 'face 'font-lock-keyword-face))
|
||||
|
||||
(should (equal (doom/what-face (point-min)) '(() (font-lock-keyword-face))))
|
||||
(should-not (doom/what-face (point-max)))))
|
||||
(should (equal (doom/what-face (point-min)) '(() (font-lock-keyword-face))))
|
||||
(should-not (doom/what-face (point-max))))
|
||||
|
|
|
@ -1,30 +1,21 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; core/test/autoload-package.el
|
||||
|
||||
(defun -new-package (name version &optional reqs)
|
||||
(defun -pkg (name version &optional reqs)
|
||||
(package-desc-create :name name :version version :reqs reqs))
|
||||
|
||||
(defmacro -with-temp-packages! (&rest forms)
|
||||
"Run FORMS in the context of a temporary package setup (as in, it won't
|
||||
affects your Emacs packages)."
|
||||
`(let* ((doom-local-dir ,(expand-file-name "test/.local/" doom-emacs-dir))
|
||||
(doom-packages-dir (concat doom-local-dir "packages/"))
|
||||
(doom-etc-dir (concat doom-local-dir "etc/"))
|
||||
(doom-cache-dir (concat doom-local-dir "cache/"))
|
||||
(package-user-dir (expand-file-name "elpa" doom-packages-dir))
|
||||
package-alist
|
||||
package-archive-contents
|
||||
package-initialize)
|
||||
(package-initialize)
|
||||
,@forms))
|
||||
|
||||
(defmacro -with-packages! (packages package-descs &rest body)
|
||||
`(let ((doom-packages ,packages)
|
||||
(defmacro with-packages!! (packages package-descs &rest body)
|
||||
`(let* ((doom-packages-dir ,(expand-file-name "packages/" (file-name-directory load-file-name)))
|
||||
(package-user-dir ,(expand-file-name "elpa" doom-packages-dir))
|
||||
(quelpa-dir ,(expand-file-name "quelpa" doom-packages-dir)))
|
||||
;; (make-directory doom-packages-dir t)
|
||||
(let ((doom-packages ,packages)
|
||||
(package-alist ,package-descs)
|
||||
doom-core-packages)
|
||||
(cl-letf (((symbol-function 'doom-initialize-packages) (lambda (&rest _)))
|
||||
((symbol-function 'package-installed-p) (lambda (name &rest _) (assq name package-alist))))
|
||||
,@body)))
|
||||
(cl-letf (((symbol-function 'doom-initialize-packages) (lambda (&rest _))))
|
||||
,@body))
|
||||
;; (delete-directory doom-packages-dir t)
|
||||
))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -32,18 +23,19 @@ affects your Emacs packages)."
|
|||
;;
|
||||
|
||||
(def-test! backend-detection
|
||||
(let ((package-alist `((doom-dummy ,(-new-package 'doom-dummy '(20160405 1234)))))
|
||||
(let ((package-alist `((doom-dummy ,(-pkg 'doom-dummy '(20160405 1234)))))
|
||||
(quelpa-cache '((doom-quelpa-dummy :fetcher github :repo "hlissner/does-not-exist")))
|
||||
(quelpa-initialized-p t))
|
||||
(should (eq (doom-package-backend 'doom-dummy) 'elpa))
|
||||
(should (eq (doom-package-backend 'doom-quelpa-dummy) 'quelpa))))
|
||||
(should (eq (doom-package-backend 'doom-quelpa-dummy) 'quelpa))
|
||||
(should (eq (doom-package-backend 'org) 'emacs))))
|
||||
|
||||
(def-test! elpa-outdated-detection
|
||||
(let* ((doom--last-refresh (current-time))
|
||||
(package-alist
|
||||
`((doom-dummy ,(-new-package 'doom-dummy '(20160405 1234)))))
|
||||
`((doom-dummy ,(-pkg 'doom-dummy '(20160405 1234)))))
|
||||
(package-archive-contents
|
||||
`((doom-dummy ,(-new-package 'doom-dummy '(20170405 1234))))))
|
||||
`((doom-dummy ,(-pkg 'doom-dummy '(20170405 1234))))))
|
||||
(cl-letf (((symbol-function 'package-refresh-contents) (lambda (&rest _))))
|
||||
(should (equal (doom-package-outdated-p 'doom-dummy)
|
||||
'(doom-dummy (20160405 1234) (20170405 1234)))))))
|
||||
|
@ -52,7 +44,7 @@ affects your Emacs packages)."
|
|||
|
||||
(def-test! get-packages
|
||||
(let ((quelpa-initialized-p t))
|
||||
(-with-packages!
|
||||
(with-packages!!
|
||||
'((doom-dummy))
|
||||
'((doom-dummy nil)
|
||||
(doom-dummy-unwanted nil)
|
||||
|
@ -62,17 +54,17 @@ affects your Emacs packages)."
|
|||
(def-test! orphaned-packages
|
||||
"Test `doom-get-orphaned-packages', which gets a list of packages that are
|
||||
no longer enabled or depended on."
|
||||
(-with-packages!
|
||||
(with-packages!!
|
||||
'((doom-dummy))
|
||||
`((doom-dummy ,(-new-package 'doom-dummy '(20160405 1234) '((doom-dummy-dep (1 0)))))
|
||||
(doom-dummy-unwanted ,(-new-package 'doom-dummy-unwanted '(20160601 1234)))
|
||||
(doom-dummy-dep ,(-new-package 'doom-dummy-dep '(20160301 1234))))
|
||||
`((doom-dummy ,(-pkg 'doom-dummy '(20160405 1234) '((doom-dummy-dep (1 0)))))
|
||||
(doom-dummy-unwanted ,(-pkg 'doom-dummy-unwanted '(20160601 1234)))
|
||||
(doom-dummy-dep ,(-pkg 'doom-dummy-dep '(20160301 1234))))
|
||||
(should (equal (doom-get-orphaned-packages) '(doom-dummy-unwanted)))))
|
||||
|
||||
(def-test! missing-packages
|
||||
"Test `doom-get-missing-packages, which gets a list of enabled packages that
|
||||
aren't installed."
|
||||
(-with-packages!
|
||||
(with-packages!!
|
||||
'((doom-dummy) (doom-dummy-installed))
|
||||
`((doom-dummy-installed ,(-new-package 'doom-dummy-installed '(20160405 1234))))
|
||||
`((doom-dummy-installed ,(-pkg 'doom-dummy-installed '(20160405 1234))))
|
||||
(should (equal (doom-get-missing-packages) '((doom-dummy))))))
|
||||
|
|
|
@ -147,10 +147,13 @@
|
|||
|
||||
;; --- Settings ---------------------------
|
||||
|
||||
(def-setting! :-test-setting (x) x)
|
||||
|
||||
(def-test! set
|
||||
(should (assq :-test-setting doom-settings))
|
||||
(should (set! :-test-setting t))
|
||||
(let ((inhibit-message t))
|
||||
(should-not (set! :non-existant-setting (error "This shouldn't trigger")))))
|
||||
(eval-and-compile
|
||||
(let (doom-settings)
|
||||
(def-setting! :-test-setting (x) `(setq result ,x))
|
||||
(should (assq :-test-setting doom-settings))
|
||||
(let ((inhibit-message t)
|
||||
result)
|
||||
(set! :-test-setting t)
|
||||
(should result)
|
||||
(set! :non-existant-setting (error "This shouldn't trigger"))))))
|
||||
|
|
43
core/test/core-projects.el
Normal file
43
core/test/core-projects.el
Normal file
|
@ -0,0 +1,43 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; ../core/test/core-projects.el
|
||||
|
||||
(require 'projectile)
|
||||
|
||||
;;
|
||||
;; `doom-project-p'
|
||||
(def-test! project-p
|
||||
:minor-mode projectile-mode
|
||||
(let ((default-directory doom-emacs-dir))
|
||||
(should (doom-project-p)))
|
||||
(let ((default-directory (expand-file-name "~")))
|
||||
(should-not (doom-project-p))))
|
||||
|
||||
;; `doom-project-p'
|
||||
(def-test! project-root
|
||||
:minor-mode projectile-mode
|
||||
;; Should resolve to project root
|
||||
(let ((default-directory doom-core-dir))
|
||||
(should (equal (doom-project-root) doom-emacs-dir)))
|
||||
;; Should resolve to `default-directory' if not a project
|
||||
(let ((default-directory (expand-file-name "~")))
|
||||
(should (equal (doom-project-root) default-directory))))
|
||||
|
||||
;; `doom-project-expand'
|
||||
(def-test! project-expand
|
||||
:minor-mode projectile-mode
|
||||
(let ((default-directory doom-core-dir))
|
||||
(should (equal (doom-project-expand "init.el")
|
||||
(expand-file-name "init.el" (doom-project-root))))))
|
||||
|
||||
;; `doom-project-has!'
|
||||
(def-test! project-has!
|
||||
:minor-mode projectile-mode
|
||||
(let ((default-directory doom-core-dir))
|
||||
;; Resolve from project root
|
||||
(should (doom-project-has! "init.el"))
|
||||
;; Chained file checks
|
||||
(should (doom-project-has! (and "init.el" "LICENSE")))
|
||||
(should (doom-project-has! (or "init.el" "does-not-exist")))
|
||||
(should (doom-project-has! (and "init.el" (or "LICENSE" "does-not-exist"))))
|
||||
;; Should resolve relative paths from `default-directory'
|
||||
(should (doom-project-has! (and "./core.el" "../init.el")))))
|
45
core/test/core-ui.el
Normal file
45
core/test/core-ui.el
Normal file
|
@ -0,0 +1,45 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; ../core/test/core-ui.el
|
||||
|
||||
(defmacro with-temp-windows!! (&rest body)
|
||||
(declare (indent defun))
|
||||
`(progn
|
||||
(delete-other-windows)
|
||||
(cl-flet ((split-window (symbol-function #'split-window-horizontally)))
|
||||
(let ((a (get-buffer-create "a"))
|
||||
(b (get-buffer-create "b"))
|
||||
(split-width-threshold 0)
|
||||
(window-min-width 0))
|
||||
,@body))))
|
||||
|
||||
;;
|
||||
(def-test! set-mode-name
|
||||
(let ((doom-major-mode-names '((text-mode . "abc")
|
||||
(lisp-mode . (lambda () "xyz"))
|
||||
(js-mode . t))))
|
||||
(text-mode)
|
||||
(should (equal mode-name "abc"))
|
||||
(lisp-mode)
|
||||
(should (equal mode-name "xyz"))
|
||||
(should-error (js-mode))))
|
||||
|
||||
(def-test! protect-visible-buffers
|
||||
(with-temp-windows!!
|
||||
(let ((kill-buffer-query-functions '(doom|protect-visible-buffers)))
|
||||
(switch-to-buffer a) (split-window)
|
||||
(switch-to-buffer b) (split-window)
|
||||
(switch-to-buffer a)
|
||||
(should-not (kill-buffer))
|
||||
(select-window (get-buffer-window b))
|
||||
(should (kill-buffer)))))
|
||||
|
||||
(def-test! *quit-window
|
||||
(with-temp-windows!!
|
||||
(let (kill-buffer-query-functions)
|
||||
(switch-to-buffer a) (split-window)
|
||||
(switch-to-buffer b)
|
||||
(save-window-excursion
|
||||
(quit-window t)
|
||||
(should (buffer-live-p b)))
|
||||
(quit-window)
|
||||
(should-not (buffer-live-p b)))))
|
|
@ -130,7 +130,10 @@
|
|||
;twitter ; twitter client https://twitter.com/vnought
|
||||
;write ; emacs as a word processor (latex + org + markdown)
|
||||
|
||||
;; This is the private module of Doom's maintainer; use it as a reference
|
||||
;; Private modules are where you place your personal configuration files.
|
||||
;; By default, they are not tracked. There is one module included here,
|
||||
;; the defaults module. It contains a Spacemacs-inspired keybinding
|
||||
;; scheme and additional ex commands for evil-mode. Use it as a reference
|
||||
;; for your own.
|
||||
:private hlissner)
|
||||
:private default)
|
||||
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
:completion
|
||||
company
|
||||
|
||||
:ui
|
||||
doom-dashboard
|
||||
|
||||
:tools
|
||||
password-store
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
|
||||
|
||||
(def-package! elfeed-org
|
||||
:after elfeed
|
||||
:after (:all org elfeed)
|
||||
:config
|
||||
(setq rmh-elfeed-org-files
|
||||
(let ((default-directory +org-dir))
|
||||
|
|
|
@ -14,20 +14,23 @@ This module adds code-completion support, powered by [[https://github.com/compan
|
|||
- [[#troubleshooting][Troubleshooting]]
|
||||
|
||||
* Install
|
||||
Certain languages may require additional setup, and some languages may have no completion support at all.
|
||||
Some languages require additional setup, and some languages may have no
|
||||
completion support at all.
|
||||
|
||||
Check the README.org in that language's module for details.
|
||||
|
||||
* Configure
|
||||
** Auto-completion
|
||||
By default, I've disabled auto-completion. This is my preference. I prefer to invoke company when I need it by calling ~company-complete~ manually (typically, bound to =C-SPC= in insert mode). However, some may not share my preference.
|
||||
By default, I've disabled auto-completion. This is my preference. I prefer to
|
||||
invoke company when I need it by calling ~company-complete~ manually (typically,
|
||||
bound to =C-SPC= in insert mode). However, some may not share my preference.
|
||||
|
||||
To enable auto-completion you must:
|
||||
|
||||
1. Load ~company~,
|
||||
2. and change ~company-idle-delay~ to a non-nil float (the default is 0.5)
|
||||
|
||||
For example, add the following to your ~modules/private/<username>/config.el~ module:
|
||||
For example:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(require 'company)
|
||||
|
@ -36,8 +39,10 @@ For example, add the following to your ~modules/private/<username>/config.el~ mo
|
|||
#+END_SRC
|
||||
|
||||
* Troubleshooting
|
||||
If completion isn't working for you, please consider the following before posting a bug report:
|
||||
If completion isn't working for you, please consider the following before
|
||||
posting a bug report:
|
||||
|
||||
+ If what you are expecting is popup-as-you-type completion (which is disabled by default), see the "Customize" section above; it includes instructions on how to enable this.
|
||||
+ Certain languages may have extra dependencies in order for auto-completion to work. Please look for that module's README.org for details.
|
||||
+ Some languages don't have any auto-completion support.
|
||||
+ If what you are expecting is popup-as-you-type completion (which is disabled
|
||||
by default), see the "Configure > Auto-completion" section above, which will
|
||||
instruct you on how to enable this.
|
||||
+ Some languages don't have any auto-completion support at all.
|
||||
|
|
|
@ -4,20 +4,21 @@
|
|||
(require! :completion company)
|
||||
(require 'company)
|
||||
|
||||
;;
|
||||
(def-test! set-company-backend
|
||||
(let ((default-backends (default-value 'company-backends)))
|
||||
:minor-mode company-mode
|
||||
(let ((company-backends '(default)))
|
||||
(set! :company-backend 'emacs-lisp-mode '(backend-1))
|
||||
(set! :company-backend 'lisp-interaction-mode 'backend-1 'backend-2)
|
||||
(set! :company-backend 'text-mode 'backend-1)
|
||||
(with-temp-buffer
|
||||
(emacs-lisp-mode)
|
||||
(should (equal (car company-backends) '(backend-1))))
|
||||
(should (equal company-backends '((backend-1) default))))
|
||||
(with-temp-buffer
|
||||
(lisp-interaction-mode)
|
||||
(should (equal company-backends
|
||||
(append '(backend-1 backend-2) default-backends))))
|
||||
(should (equal company-backends '(backend-1 backend-2 default))))
|
||||
(with-temp-buffer
|
||||
(text-mode)
|
||||
(should (eq (car company-backends) 'backend-1)))
|
||||
(should (equal company-backends '(backend-1 default))))
|
||||
;; global backends shouldn't be affected
|
||||
(should (equal company-backends default-backends))))
|
||||
(should (equal company-backends '(default)))))
|
||||
|
|
|
@ -3,11 +3,13 @@
|
|||
This module adds Ivy, a completion backend.
|
||||
|
||||
#+begin_quote
|
||||
I prefer ivy over ido for its flexibility. I prefer ivy over helm because it's lighter.
|
||||
I prefer ivy over ido for its flexibility. I prefer ivy over helm because it's
|
||||
lighter.
|
||||
#+end_quote
|
||||
|
||||
+ Project-wide search & replace powered by ~rg~ or ~ag~
|
||||
+ Project jump-to navigation ala Command-T, Sublime Text's Jump-to-anywhere or Vim's CtrlP plugin.
|
||||
+ Project jump-to navigation ala Command-T, Sublime Text's Jump-to-anywhere or
|
||||
Vim's CtrlP plugin.
|
||||
+ Ivy integration for ~M-x~, ~imenu~, ~recentf~ and others.
|
||||
+ A powerful, interactive in-buffer search using ~swiper~.
|
||||
+ Ivy-powered TODO/FIXME navigation
|
||||
|
@ -28,7 +30,9 @@ I prefer ivy over ido for its flexibility. I prefer ivy over helm because it's l
|
|||
* Install
|
||||
This module optionally depends on [[https://github.com/BurntSushi/ripgrep][ripgrep]] and [[https://github.com/ggreer/the_silver_searcher][the_silver_searcher]].
|
||||
|
||||
~rg~ is faster, but its results aren't deterministic, neither does it support multiline search or full PCRE, that's where ~ag~ is useful.
|
||||
~rg~ is faster, but its results aren't deterministic, neither does it support
|
||||
multiline search or full PCRE (at the time of writing), that's where ~ag~ is
|
||||
useful.
|
||||
|
||||
** MacOS
|
||||
#+BEGIN_SRC sh :tangle (if (doom-system-os 'macos) "yes")
|
||||
|
@ -41,37 +45,58 @@ sudo pacman --needed --noconfirm -S ripgrep the_silver_searcher
|
|||
#+END_SRC
|
||||
|
||||
* Usage
|
||||
Here is some insight into how I use this module. Keep in mind that the referenced commands and keybindings are defined [[/modules/private/hlissner][in my private module]].
|
||||
Here is some insight into how I use this module.
|
||||
|
||||
** Project search & replace
|
||||
Ex interfaces to Ag (the silver searcher) and Rg (ripgrep) are available: ~:ag[!]~ and ~:rg[!]~, or their current-directory counterparts ~:agcwd[!]~ and ~:rgcwd[!]~.
|
||||
There are four Ex interfaces for the silver searcher and ripgrep. They are:
|
||||
|
||||
+ ~:ag[!]~
|
||||
+ ~:agcwd[!]~
|
||||
+ ~:rg[!]~
|
||||
+ ~:rgcwd[!]~
|
||||
|
||||
The optional BANG tells ag/rg to include ignored files in the search. And the
|
||||
\*cwd variant of each command will only search in the current directory
|
||||
(non-recursively).
|
||||
|
||||
[[/../screenshots/modules/completion/ivy/ivy-search.gif]]
|
||||
|
||||
From this session, you can press =S+Tab= to create a writeable occur-buffer in wgrep mode.
|
||||
Now, how do we do text replacements? With the ivy popup open you can press
|
||||
=S+Tab= to create an wgrep buffer out of the results.
|
||||
|
||||
[[/../screenshots/modules/completion/ivy/ivy-search-replace.gif]]
|
||||
|
||||
Make your modifications and press =C-c C-c= to commit them, or =C-c C-k= to abort.
|
||||
Make your modifications and press =C-c C-c= to commit them, or =C-c C-k= to
|
||||
abort.
|
||||
|
||||
** Jump-to-file project navigation
|
||||
Inspired by Sublime Text's jump-to-anywhere, Vim's CtrlP or Unite plugins, and Textmate's Command-T, a marriage of ~projectile~ and ~ivy~ makes this available to you in Emacs. Invoke it with =SPC f /=, =SPC SPC= or ~counsel-projectile-find-file~.
|
||||
Inspired by Sublime Text's jump-to-anywhere, Vim's CtrlP/Unite plugins, and
|
||||
Textmate's Command-T, a marriage of ~projectile~ and ~ivy~ makes this available
|
||||
in Emacs.
|
||||
|
||||
Invoke it with =SPC f /=, =SPC SPC= or ~M-x counsel-projectile-find-file~.
|
||||
|
||||
[[/../screenshots/modules/completion/ivy/ivy-projectile.gif]]
|
||||
|
||||
** In-buffer searching
|
||||
I use ~evil-search~ (invoked by pressing =/= in normal mode) when jumping small/moderate (or predictable) distances. However, there are occasions where I need more feedback, so I turn to ~swiper~ (available directly with =M-x swiper RET=, or via ~:sw[iper]~).
|
||||
I use ~evil-search~ (invoked by pressing =/= in normal mode) when jumping
|
||||
small/moderate (or predictable) distances. However, there are occasions where I
|
||||
need more feedback, so I turn to ~swiper~ (available directly with =M-x swiper
|
||||
RET=, or via ~:sw[iper]~).
|
||||
|
||||
[[/../screenshots/modules/completion/ivy/ivy-swiper.gif]]
|
||||
|
||||
** Task lookup
|
||||
I sprinkle my projects with TODO's & FIXME's. You can navigate to and peruse them via ~M-x +ivy/tasks~ or ~:todo[!]~ (ex command).
|
||||
I sprinkle my projects with TODO's & FIXME's. You can navigate to and peruse
|
||||
them via ~M-x +ivy/tasks~ or ~:todo[!]~ (ex command).
|
||||
|
||||
[[/../screenshots/modules/completion/ivy/ivy-todo.gif]]
|
||||
|
||||
* Appendix
|
||||
** Commands
|
||||
Here is a list of my commonly used commands, their default keybinds (defined in [[../../private/hlissner/+bindings.el][private/hlissner/+bindings.el]]), and their corresponding ex command (defined in [[../../private/hlissner/+commands.el][private/hlissner/+commands.el]]).
|
||||
Here is a list of my commonly used commands, their default keybinds (defined in
|
||||
[[../../private/default/+bindings.el][private/default/+bindings.el]]), and their corresponding ex command (defined in
|
||||
[[../../private/default/+evil-commands.el][private/default/+evil-commands.el]]).
|
||||
|
||||
| command | key / ex command | description |
|
||||
|-------------------------------------+------------------------+------------------------------------------------------------------|
|
||||
|
@ -90,7 +115,8 @@ Here is a list of my commonly used commands, their default keybinds (defined in
|
|||
| ~+ivy:swiper~ | ~:sw[iper] [QUERY]~ | Search current buffer |
|
||||
| ~+ivy:todo~ | ~:todo[!]~ | List all TODO/FIXMEs in project (or current file if BANG) |
|
||||
|
||||
While in a search (e.g. invoked from ~+ivy:ag~ or ~+ivy:rg~), these new keybindings are available to you:
|
||||
While in a search (e.g. invoked from ~+ivy:ag~ or ~+ivy:rg~), these new
|
||||
keybindings are available to you:
|
||||
|
||||
| key | description |
|
||||
|-------------+--------------------------------------------------------------------------------|
|
||||
|
@ -99,10 +125,10 @@ While in a search (e.g. invoked from ~+ivy:ag~ or ~+ivy:rg~), these new keybindi
|
|||
| =M-RET= | Open the selected candidate in other-window |
|
||||
|
||||
** Hacks
|
||||
+ Functions with ivy/counsel equivalents have been globally remapped (like ~find-file~ => ~counsel-find-file~). So a keybinding to ~find-file~ will invoke ~counsel-find-file~ instead.
|
||||
+ ~counsel-[arp]g~'s 3-character limit was reduced to 1 (mainly for the ex command)
|
||||
+ ~counsel-[arp]g~'s parentheses quoting behavior was reversed. Now, if you
|
||||
want literal parentheses, you must escape them: e.g. ~\(match\)~ is literal,
|
||||
~(match)~ is a regexp group.
|
||||
+ Functions with ivy/counsel equivalents have been globally remapped (like
|
||||
~find-file~ => ~counsel-find-file~). So a keybinding to ~find-file~ will
|
||||
invoke ~counsel-find-file~ instead.
|
||||
+ ~counsel-[arp]g~'s 3-character limit was reduced to 1 (mainly for the ex
|
||||
command)
|
||||
|
||||
|
||||
|
|
|
@ -43,8 +43,7 @@ immediately runs it on the current candidate (ending the ivy session)."
|
|||
(after! magit (setq magit-completing-read-function #'ivy-completing-read))
|
||||
(after! yasnippet (push #'+ivy-yas-prompt yas-prompt-functions))
|
||||
|
||||
(map! :map ivy-mode-map
|
||||
[remap apropos] #'counsel-apropos
|
||||
(map! [remap apropos] #'counsel-apropos
|
||||
[remap describe-face] #'counsel-describe-face
|
||||
[remap find-file] #'counsel-find-file
|
||||
[remap switch-to-buffer] #'ivy-switch-buffer
|
||||
|
@ -52,7 +51,6 @@ immediately runs it on the current candidate (ending the ivy session)."
|
|||
[remap recentf-open-files] #'counsel-recentf
|
||||
[remap imenu] #'counsel-imenu
|
||||
[remap bookmark-jump] #'counsel-bookmark
|
||||
[remap projectile-switch-project] #'counsel-projectile-switch-project
|
||||
[remap projectile-find-file] #'counsel-projectile-find-file
|
||||
[remap imenu-anywhere] #'ivy-imenu-anywhere
|
||||
[remap execute-extended-command] #'counsel-M-x
|
||||
|
|
|
@ -1,43 +1,52 @@
|
|||
#+TITLE: :feature eval
|
||||
|
||||
This modules adds support for evaluating code from inside Emacs. This includes REPLs and direct access to the interpreters and compilers of many languages.
|
||||
This modules adds support for evaluating code from inside Emacs, including
|
||||
REPLs.
|
||||
|
||||
* Table of Contents :TOC:
|
||||
- [[#install][Install]]
|
||||
- [[#usage][Usage]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#repls][REPLs]]
|
||||
- [[#code-evaluation][Code Evaluation]]
|
||||
- [[#code-evaluation][*Code Evaluation*]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#repls-1][REPLs]]
|
||||
- [[#code-evaluation-1][Code Evaluation]]
|
||||
|
||||
* Install
|
||||
This module has no external dependencies. However, specific languages may require additional setup.
|
||||
This module has no external dependencies. However, specific languages may
|
||||
require additional setup.
|
||||
|
||||
Check the README.org in that language's module for details.
|
||||
|
||||
* Usage
|
||||
+ *REPLs*
|
||||
Invoked via:
|
||||
+ ~:repl~ (evil ex-command)
|
||||
+ =<leader> o r= in normal mode (or visual mode, which sends the selection to the open REPL)
|
||||
+ ~M-x +eval/open-repl~
|
||||
+ ~M-x +eval/send-region-to-repl~ while a selection (and REPL) is active
|
||||
** REPLs
|
||||
Invoked via:
|
||||
+ ~:repl~ (evil ex-command)
|
||||
+ =<leader> o r= in normal mode (or visual mode, which sends the selection to
|
||||
the open REPL)
|
||||
+ ~M-x +eval/open-repl~
|
||||
+ ~M-x +eval/send-region-to-repl~ while a selection (and REPL) is active
|
||||
|
||||
+ *Code Evaluation*
|
||||
Quickrun can be invoked via:
|
||||
+ ~M-x +eval/buffer~ (or ~gR~, or ~M-r~)
|
||||
+ ~M-x +eval/region~
|
||||
+ ~M-x +eval/region-and-replace~
|
||||
+ Evil users can use the ~gr~ operator to select and run a region.
|
||||
** *Code Evaluation*
|
||||
Quickrun can be invoked via:
|
||||
+ ~M-x +eval/buffer~ (or ~gR~, or ~M-r~)
|
||||
+ ~M-x +eval/region~
|
||||
+ ~M-x +eval/region-and-replace~
|
||||
+ Evil users can use the ~gr~ operator to select and run a region.
|
||||
|
||||
* Configuration
|
||||
** REPLs
|
||||
REPLs are defined for most of the languages Doom supports (check its README.org to see if it does).
|
||||
REPLs are defined for most of the languages Doom supports (check its README.org
|
||||
to see if it does).
|
||||
|
||||
Otherwise, you can define your own for a specified major-mode with the =:repl= setting.
|
||||
Otherwise, you can define your own for a specified major-mode with the =:repl=
|
||||
setting.
|
||||
|
||||
~(set! :repl MAJOR-MODE FUNCTION)~
|
||||
|
||||
FUNCTION must return the repl buffer. Any window changes are ignored, then handed off to shackle (assuming shackle-mode is on) to display in a popup window.
|
||||
FUNCTION must return the repl buffer. Any window changes are ignored, then
|
||||
handed off to shackle (assuming shackle-mode is on) to display in a popup
|
||||
window.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun +emacs-lisp/repl ()
|
||||
|
@ -53,9 +62,14 @@ FUNCTION must return the repl buffer. Any window changes are ignored, then hande
|
|||
#+END_SRC
|
||||
|
||||
** Code Evaluation
|
||||
Run regions or entire buffers with [[https://github.com/syohex/emacs-quickrun][Quickrun]]. Output will be sent to a popup window.
|
||||
Run regions or entire buffers with [[https://github.com/syohex/emacs-quickrun][Quickrun]]. Output is show in a popup window.
|
||||
|
||||
Quickrun includes support for many languages, but occasionally, you'll find a language without support, such as [[https://crystal-lang.org/][Crystal]]. A "runner" can be defined like so:
|
||||
Quickrun includes support for many languages, usually by sending text directly
|
||||
to interpreters or compilers. However, occasionally, you'll find a language
|
||||
without support (like [[https://crystal-lang.org/][Crystal]]), or a language with better Emacs integration
|
||||
(like elisp).
|
||||
|
||||
Here's how you define a "runner":
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(set! :eval 'crystal-mode
|
||||
|
|
|
@ -11,12 +11,14 @@ This holy module brings the vim experience to Emacs.
|
|||
- [[#differences-from-vim][Differences from vim]]
|
||||
|
||||
* Removing evil-mode
|
||||
To get back a more vanilla Emacs experience, remove =:feature evil= from init.el. Evil-specific configuration and keybindings (defined with ~map!~) will be ignored without evil present (and removed when byte-compiling).
|
||||
See the [[https://github.com/hlissner/doom-emacs/wiki/FAQ#remove-vimevil-for-a-more-vanilla-emacs-experience][corresponding question in the FAQ]].
|
||||
|
||||
* Features
|
||||
+ A better ~:g[lobal]~ command with incremental highlighting.
|
||||
+ Adds the ~:al[ign]~ ex command: offers an ex interface to ~align-regexp~ with incremental highlighting.
|
||||
+ Support for more of vim's filename modifiers in ex commands (like ~:p~, ~:p:h~ or ~:t~) than vanilla evil-mode offers.
|
||||
+ Adds the ~:al[ign]~ ex command: offers an ex interface to ~align-regexp~ with
|
||||
incremental highlighting.
|
||||
+ Support for more of vim's filename modifiers in ex commands (like ~:p~, ~:p:h~
|
||||
or ~:t~) than vanilla evil-mode offers.
|
||||
+ A list of new text objects:
|
||||
+ Blocks: ~B~ (from ~evil-textobj-anyblock~)
|
||||
+ Args: ~a~ (from ~evil-args~)
|
||||
|
@ -31,20 +33,29 @@ To get back a more vanilla Emacs experience, remove =:feature evil= from init.el
|
|||
+ =NERDTree= equivalent is available in =:tools neotree=
|
||||
|
||||
** Multiple-cursors
|
||||
Two multiple-cursor implementations exist in this module: ~evil-mc~ and ~evil-multiedit~. Together, these provide the functionality of ~vim-multiple-cursors~.
|
||||
Two multiple-cursor implementations exist in this module: ~evil-mc~ and
|
||||
~evil-multiedit~. Together, these provide the functionality of
|
||||
~vim-multiple-cursors~.
|
||||
|
||||
The former lets you place "clone" cursors. The latter lets you interactively edit many regions from one place (like an interactive version of ~:%s~).
|
||||
The former lets you place "clone" cursors. The latter lets you interactively
|
||||
edit many regions at once (like an interactive version of ~:%s~).
|
||||
|
||||
** A hybrid code-folding system
|
||||
This module combines ~evil-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.
|
||||
This module combines ~evil-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.
|
||||
|
||||
** Hacks
|
||||
+ Automatically moves to new window when splitting
|
||||
+ If in visual mode, =*= and =#= will search for the current selection instead of the word-at-point.
|
||||
+ From visual mode, =*= and =#= will search for the current selection instead of
|
||||
the word-at-point.
|
||||
|
||||
** 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~).
|
||||
+ 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.
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ kills the buffer. If FORCE-P, force the deletion (don't ask for confirmation)."
|
|||
(error "Failed to delete %s" short-path)
|
||||
;; Ensures that windows displaying this buffer will be switched
|
||||
;; to real buffers (`doom-real-buffer-p')
|
||||
(doom-force-kill-buffer buf t)
|
||||
(doom/kill-this-buffer-in-all-windows buf t)
|
||||
(+evil--forget-file fname)
|
||||
(message "Successfully deleted %s" short-path))))))))
|
||||
|
||||
|
|
|
@ -388,8 +388,8 @@ the new algorithm is confusing, like in python or ruby."
|
|||
;;
|
||||
|
||||
;; mc doesn't play well with evil, this attempts to assuage some of its problems
|
||||
;; so that certain plugins (which I have no control over) can still use it in
|
||||
;; relative safety.
|
||||
;; so that any plugins that depend on multiple-cursors (which I have no control
|
||||
;; over) can still use it in relative safety.
|
||||
(after! multiple-cursors-core
|
||||
(map! :map mc/keymap :ne "<escape>" #'mc/keyboard-quit)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; feature/evil/test/autoload-files.el
|
||||
|
||||
(defmacro -with-temp-files! (src dest &rest body)
|
||||
(defmacro with-temp-files!! (src dest &rest body)
|
||||
"Run FORMS in the context of a temporary package setup (as in, it won't
|
||||
affects your Emacs packages)."
|
||||
(declare (indent 2) (doc-string 3))
|
||||
|
@ -23,7 +23,7 @@ affects your Emacs packages)."
|
|||
;;
|
||||
(def-test! move-this-file
|
||||
":mv"
|
||||
(-with-temp-files! "/tmp/doom-buffer" "/tmp/doom-buffer-new"
|
||||
(with-temp-files!! "/tmp/doom-buffer" "/tmp/doom-buffer-new"
|
||||
(should-error (+evil:move-this-file it))
|
||||
(should (+evil:move-this-file other t))
|
||||
(should (file-exists-p other))
|
||||
|
@ -31,7 +31,7 @@ affects your Emacs packages)."
|
|||
|
||||
(def-test! copy-this-file
|
||||
":cp"
|
||||
(-with-temp-files! "/tmp/doom-buffer-2" "/tmp/doom-buffer-2-new"
|
||||
(with-temp-files!! "/tmp/doom-buffer-2" "/tmp/doom-buffer-2-new"
|
||||
(should-error (+evil:copy-this-file it))
|
||||
(should (+evil:copy-this-file other t))
|
||||
(should (file-exists-p other))
|
||||
|
@ -39,7 +39,7 @@ affects your Emacs packages)."
|
|||
|
||||
(def-test! delete-this-file
|
||||
":rm"
|
||||
(-with-temp-files! "/tmp/doom-buffer-3" nil
|
||||
(with-temp-files!! "/tmp/doom-buffer-3" nil
|
||||
(should-error (+evil:delete-this-file "this-file-does-not-exist"))
|
||||
(should (+evil:delete-this-file nil t))
|
||||
(should (not (file-exists-p it)))))
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
(require! :feature evil)
|
||||
|
||||
;;
|
||||
;; `evil-ex-replace-special-filenames'
|
||||
;; NOTE The majority of this function is tested in core/test/core-lib.el, this
|
||||
;; only tests the evil-mode-specific functionality.
|
||||
|
|
|
@ -6,6 +6,11 @@
|
|||
(expand-file-name "templates/" (file-name-directory load-file-name))
|
||||
"The path to a directory of yasnippet folders to use for file templates.")
|
||||
|
||||
|
||||
;;
|
||||
;; Plugins
|
||||
;;
|
||||
|
||||
(def-package! autoinsert ; built-in
|
||||
:defer 1
|
||||
:init
|
||||
|
@ -18,12 +23,16 @@
|
|||
(auto-insert-mode 1)
|
||||
|
||||
(defun +file-templates--expand (key &optional mode project-only)
|
||||
"Auto insert a snippet of yasnippet into new file."
|
||||
"Auto insert a yasnippet snippet into the blank file."
|
||||
(when (if project-only (doom-project-p) t)
|
||||
(require 'yasnippet)
|
||||
(unless yas-minor-mode (yas-minor-mode-on))
|
||||
(unless yas-minor-mode
|
||||
(yas-minor-mode-on))
|
||||
(when (and yas-minor-mode
|
||||
(yas-expand-snippet (yas-lookup-snippet key mode t))
|
||||
(yas-expand-snippet
|
||||
(yas--template-content
|
||||
(cl-find key (yas--all-templates (yas--get-snippet-tables mode))
|
||||
:key #'yas--template-key :test #'equal)))
|
||||
(and (featurep 'evil) evil-mode)
|
||||
(and yas--active-field-overlay
|
||||
(overlay-buffer yas--active-field-overlay)
|
||||
|
@ -56,10 +65,9 @@
|
|||
("\\.el$" "__initfile" emacs-lisp-mode)
|
||||
("/.dir-locals.el$" nil)
|
||||
("-test\\.el$" "__" emacs-ert-mode)
|
||||
("/.emacs.d/.+\\.el$" "__doom-module" emacs-lisp-mode)
|
||||
("/.emacs.d/.+/packages\\.el$" "__doom-packages" emacs-lisp-mode)
|
||||
("/.emacs.d/.+/test\\.el$" "__doom-test" emacs-lisp-mode)
|
||||
("/.emacs.d/.+/README\\.org$" "__doom-readme" org-mode)
|
||||
("/\\(?:.emacs.d\\|doom-emacs\\)?/.+\\.el$" "__doom-module" emacs-lisp-mode)
|
||||
("/\\(?:.emacs.d\\|doom-emacs\\)?/.+/packages\\.el$" "__doom-packages" emacs-lisp-mode)
|
||||
("/\\(?:.emacs.d\\|doom-emacs\\)?/.+/test/.+\\.el$" "__doom-test" emacs-lisp-mode)
|
||||
(snippet-mode "__" snippet-mode)
|
||||
;; Go
|
||||
("\\.go$" "__.go" go-mode)
|
||||
|
@ -82,7 +90,8 @@
|
|||
;; Markdown
|
||||
("\\.md$" "__" markdown-mode)
|
||||
;; Org
|
||||
("\\.org$" "__" org-mode)
|
||||
("\\.org$" "__" org-mode)
|
||||
("/\\(?:.emacs.d\\|doom-emacs\\)?/.+/README\\.org$" "__doom-readme" org-mode)
|
||||
;; PHP
|
||||
("\\.php$" "__" php-mode)
|
||||
("\\.class\\.php$" "__.class.php" php-mode)
|
||||
|
@ -110,5 +119,5 @@
|
|||
("/\\(index\\|main\\)\\.slim$" "__" slim-mode)
|
||||
;; Shell scripts
|
||||
("\\.z?sh$" "__" sh-mode)
|
||||
("\\.fish$" "__" fish-mode)
|
||||
("\\.zunit$" "__zunit" sh-mode))))
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
;;; `(file-relative-name buffer-file-name doom-modules-dir)` -*- lexical-binding: t; -*-
|
||||
;;; `(file-relative-name buffer-file-truename doom-modules-dir)` -*- lexical-binding: t; -*-
|
||||
|
||||
$0
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; `(file-relative-name buffer-file-name doom-modules-dir)`
|
||||
;;; `(file-relative-name buffer-file-truename doom-modules-dir)`
|
||||
|
||||
$0
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; `(file-relative-name buffer-file-name doom-modules-dir)`
|
||||
;;; `(file-relative-name buffer-file-truename doom-modules-dir)`
|
||||
|
||||
$0
|
3
modules/feature/file-templates/templates/fish-mode/__
Normal file
3
modules/feature/file-templates/templates/fish-mode/__
Normal file
|
@ -0,0 +1,3 @@
|
|||
#!/usr/bin/env fish
|
||||
|
||||
$0
|
|
@ -97,7 +97,9 @@ Tries `xref-find-references' and falls back to rg/ag."
|
|||
(cond ((plist-member +jump-current-functions :documentation)
|
||||
(+jump-to :documentation identifier))
|
||||
(t
|
||||
(+jump/online (caar +jump-search-provider-alist) identifier))))
|
||||
(+jump/online
|
||||
identifier
|
||||
(+jump--online-get-provider (not current-prefix-arg))))))
|
||||
|
||||
(defun +jump--online-get-provider (&optional force-p)
|
||||
(or (and (not force-p)
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
"An alist that maps online resources to their search url or a function that
|
||||
produces an url. Used by `+jump/online'.")
|
||||
|
||||
(defconst +jump-search-browser-fn #'browse-url
|
||||
(defvar +jump-search-browser-fn #'browse-url
|
||||
"Function to use to open search urls.")
|
||||
|
||||
(defvar +jump-function-alist nil
|
||||
|
@ -82,6 +82,18 @@ properties:
|
|||
;; Packages
|
||||
;;
|
||||
|
||||
(def-package! ivy-xref
|
||||
:when (featurep! :completion ivy)
|
||||
:after xref
|
||||
:config (setq xref-show-xrefs-function #'ivy-xref-show-xrefs))
|
||||
|
||||
|
||||
(def-package! helm-xref
|
||||
:when (featurep! :completion helm)
|
||||
:after xref
|
||||
:config (setq xref-show-xrefs-function #'helm-xref-show-xrefs))
|
||||
|
||||
|
||||
(def-package! dumb-jump
|
||||
:commands (dumb-jump-go dumb-jump-quick-look
|
||||
dumb-jump-back dumb-jump-result-follow)
|
||||
|
@ -92,28 +104,3 @@ properties:
|
|||
((featurep! :completion helm) 'helm)
|
||||
(t 'popup))))
|
||||
|
||||
|
||||
(def-package! gxref
|
||||
:commands (gxref-xref-backend
|
||||
gxref-create-db
|
||||
gxref-update-db
|
||||
gxref-single-update-db
|
||||
gxref-set-project-dir)
|
||||
:init
|
||||
(setq-default xref-backend-functions '(gxref-xref-backend t)))
|
||||
|
||||
|
||||
;; (def-package! ggtags
|
||||
;; :commands (ggtags-find-tag-dwim
|
||||
;; ggtags-find-tag-mouse
|
||||
;; ggtags-find-definition
|
||||
;; ggtags-find-reference
|
||||
;; ggtags-find-other-symbol
|
||||
;; ggtags-find-tag-regexp
|
||||
;; ggtags-idutils-query
|
||||
;; ggtags-grep
|
||||
;; ggtags-find-file
|
||||
;; ggtags-query-replace
|
||||
;; ggtags-delete-tags
|
||||
;; ggtags-explain-tags))
|
||||
|
||||
|
|
|
@ -2,10 +2,7 @@
|
|||
;;; feature/jump/packages.el
|
||||
|
||||
(package! dumb-jump)
|
||||
(package! gxref)
|
||||
;; (package! ggtags)
|
||||
;; (cond ((featurep! :completion ivy)
|
||||
;; (package! counsel-gtags))
|
||||
;; ((featurep! :completion helm)
|
||||
;; (package! helm-gtags)))
|
||||
|
||||
(when (featurep! :completion ivy)
|
||||
(package! ivy-xref))
|
||||
(when (featurep! :completion helm)
|
||||
(package! helm-xref))
|
||||
|
|
|
@ -8,20 +8,5 @@ This module adds snippets to Emacs, powered by yasnippet.
|
|||
* Install
|
||||
There are no extra dependencies for this module.
|
||||
|
||||
By default, this module uses the snippet library included with yasnippet.
|
||||
|
||||
For the best experience, I'd suggest installing mine from https://github.com/hlissner/emacs-snippets -- they have been tailored specifically for Doom.
|
||||
|
||||
1. Clone the repo to your private module:
|
||||
#+BEGIN_SRC bash
|
||||
git clone https://github.com/hlissner/emacs-snippets ~/.emacs.d/modules/private/$(whoami)/snippets
|
||||
#+END_SRC
|
||||
2. Tell yasnippet where to look for them:
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
;; modules/private/{USERNAME}/config.el
|
||||
(after! yasnippet
|
||||
(setq yas-snippet-dirs
|
||||
(append (list (expand-file-name "snippets/" (file-name-directory load-file-name)))
|
||||
(delq 'yas-installed-snippets-dir yas-snippet-dirs))))
|
||||
#+END_SRC
|
||||
|
||||
By default, =private/default= installs a snippet library tailored exclusively
|
||||
for Doom Emacs.
|
||||
|
|
|
@ -11,8 +11,6 @@
|
|||
(defvar yas-minor-mode-map (make-sparse-keymap))
|
||||
|
||||
:init
|
||||
(setq yas-snippet-dirs '(yas-installed-snippets-dir))
|
||||
|
||||
;; Ensure `yas-reload-all' is called as late as possible. Other modules could
|
||||
;; have additional configuration for yasnippet. For example, file-templates.
|
||||
(add-transient-hook! 'yas-minor-mode-hook (yas-reload-all))
|
||||
|
@ -21,11 +19,9 @@
|
|||
#'yas-minor-mode-on)
|
||||
|
||||
:config
|
||||
(setq yas-verbosity 0
|
||||
yas-indent-line 'auto
|
||||
(setq yas-verbosity (if doom-debug-mode 3 0)
|
||||
yas-also-auto-indent-first-line t
|
||||
yas-prompt-functions '(yas-completing-prompt yas-ido-prompt yas-no-prompt)
|
||||
yas-use-menu nil
|
||||
yas-prompt-functions (delq 'yas-dropdown-prompt yas-prompt-functions)
|
||||
;; Allow nested snippets
|
||||
yas-triggers-in-field t)
|
||||
|
||||
|
@ -40,27 +36,8 @@
|
|||
;; fix an error caused by smartparens interfering with yasnippet bindings
|
||||
(advice-add #'yas-expand :before #'sp-remove-active-pair-overlay)
|
||||
|
||||
(after! evil
|
||||
;; Exit snippets on ESC in normal mode
|
||||
(add-hook '+evil-esc-hook #'yas-exit-all-snippets)
|
||||
;; Once you're in normal mode, you're out
|
||||
(add-hook 'evil-normal-state-entry-hook #'yas-abort-snippet)
|
||||
;; Strip out whitespace before a line selection
|
||||
(defun +snippets|yas-before-expand ()
|
||||
"Strip out the shitespace before a line selection."
|
||||
(when (and (evil-visual-state-p)
|
||||
(eq (evil-visual-type) 'line))
|
||||
(setq yas-selected-text
|
||||
(replace-regexp-in-string
|
||||
"\\(^\\s-*\\|\n? $\\)" ""
|
||||
(buffer-substring-no-properties evil-visual-beginning
|
||||
evil-visual-end)))))
|
||||
(add-hook 'yas-before-expand-snippet-hook #'+snippets|yas-before-expand)
|
||||
|
||||
(defun +snippets|yas-after-expand ()
|
||||
"Fix previous hook persisting yas-selected-text between expansions."
|
||||
(setq yas-selected-text nil))
|
||||
(add-hook 'yas-after-exit-snippet-hook #'+snippets|yas-after-expand)))
|
||||
;; Exit snippets on ESC from normal mode
|
||||
(add-hook '+evil-esc-hook #'yas-exit-all-snippets))
|
||||
|
||||
|
||||
(def-package! auto-yasnippet
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
;;; feature/version-control/+git.el -*- lexical-binding: t; -*-
|
||||
;;;###if (not (featurep! -git))
|
||||
|
||||
(when (featurep! :feature evil)
|
||||
(add-hook 'git-commit-mode-hook #'evil-insert-state))
|
||||
|
||||
|
||||
(def-package! gitconfig-mode
|
||||
:mode "/\\.?git/?config$"
|
||||
:mode "/\\.gitmodules$")
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
#+TITLE: :feature workspaces
|
||||
|
||||
This module adds support for workspaces, powered by persp_mode, as well as a unified API for manipulating them.
|
||||
This module adds support for workspaces, powered by persp_mode, as well as a API
|
||||
for manipulating them.
|
||||
|
||||
#+begin_quote
|
||||
There are many ways to use workspaces. Some use them to group buffers/windows by project or categories (views, models, logic, etc). I use them differently: on a per-task basis, which may traverse multiple projects or aspects, but are tied to an objective. For example: implement a specific feature or fix a certain bug; sometimes unrelated to the project at hand.
|
||||
There are many ways to use workspaces. I spawn a workspace per task. Say I'm
|
||||
working in the main workspace, when I realize there is a bug in another part of
|
||||
my project. I open a new workspace and deal with it in there. In the meantime, I
|
||||
need to check my email, so mu4e gets its own workspace.
|
||||
|
||||
Once I've completed the task, I close the workspace and return to main.
|
||||
#+end_quote
|
||||
|
||||
* Table of Contents :TOC:
|
||||
|
@ -22,25 +28,33 @@ This module has no additional dependencies.
|
|||
|
||||
* Features
|
||||
** Isolated buffer-list
|
||||
When persp-mode is active, ~doom-buffer-list~ becomes workspace-restricted. You can overcome this by using ~buffer-list~.
|
||||
When persp-mode is active, ~doom-buffer-list~ becomes workspace-restricted. You
|
||||
can overcome this by using ~buffer-list~.
|
||||
|
||||
** Automatic workspaces
|
||||
A workspace is automatically created (and switched to) when you:
|
||||
|
||||
+ Create a new frame (with =make-frame=; bound to =M-N= by default)
|
||||
+ Switch to a project using ~projectile-switch-project~ (or its ivy/helm equivalents)
|
||||
+ Create a new frame (with =make-frame=; bound to =M-N= by default).
|
||||
+ Switch to a project using ~projectile-switch-project~.
|
||||
|
||||
** Session persistence
|
||||
By default, your session is autosaved when you quit Emacs (or disable ~persp-mode~). You can load a previous session with ~M-x +workspace/load-session~ or ~:sl[oad]~ (ex command).
|
||||
By default, your session is autosaved when you quit Emacs (or disable
|
||||
~persp-mode~). You can load a previous session with ~M-x
|
||||
+workspace/load-session~ or ~:sl[oad]~ (ex command).
|
||||
|
||||
You can supply either a name to load a specific session to replace your current one.
|
||||
You can supply either a name to load a specific session to replace your current
|
||||
one.
|
||||
|
||||
** Workspace persistence
|
||||
If you'd like to save a specific workspace, use ~M-x +workspace/save~, which can be loaded into the current session (as another workspace) with ~M-x +workspace/load~.
|
||||
If you'd like to save a specific workspace, use ~M-x +workspace/save~, which can
|
||||
be loaded into the current session (as another workspace) with ~M-x
|
||||
+workspace/load~.
|
||||
|
||||
* Appendix
|
||||
** Commands & Keybindings
|
||||
Here is a list of available commands, their default keybindings (defined in private/hlissner/+bindings.el), and corresponding ex commands (if any -- defined in private/hlissner/+commands.el).
|
||||
Here is a list of available commands, their default keybindings (defined in
|
||||
[[../../private/default/+bindings.el][private/default/+bindings.el]]), and corresponding ex commands (if any -- defined
|
||||
in [[../../private/default/+evil-commands.el][private/default/+evil-commands.el]]).
|
||||
|
||||
| command | key / ex command | description |
|
||||
|---------------------------+----------------------------+------------------------------------------------------------|
|
||||
|
|
|
@ -310,7 +310,7 @@ workspace to delete."
|
|||
(doom/kill-all-buffers)
|
||||
(let ((fallback-buf (doom-fallback-buffer)))
|
||||
(switch-to-buffer fallback-buf)
|
||||
(doom/cleanup-buffers)))
|
||||
(doom/cleanup-session)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +workspace/kill-session-and-quit ()
|
||||
|
|
|
@ -47,10 +47,22 @@ renamed.")
|
|||
|
||||
;; per-frame and per-project workspaces
|
||||
(setq persp-init-new-frame-behaviour-override nil
|
||||
persp-interactive-init-frame-behaviour-override #'+workspace-on-new-frame
|
||||
projectile-switch-project-action #'projectile-find-file)
|
||||
persp-interactive-init-frame-behaviour-override #'+workspace-on-new-frame)
|
||||
(add-hook 'delete-frame-functions #'+workspaces|delete-associated-workspace-maybe)
|
||||
(advice-add #'projectile-switch-project-by-name :around #'+workspaces*switch-project-by-name)
|
||||
|
||||
(defun +workspaces|per-project (&optional root)
|
||||
"Open a new workspace when switching to another project.
|
||||
|
||||
Ensures the scratch (or dashboard) buffers are CDed into the project's root."
|
||||
(when persp-mode
|
||||
(let ((cwd default-directory))
|
||||
(+workspace-switch (projectile-project-name) t)
|
||||
(switch-to-buffer (doom-fallback-buffer))
|
||||
(setq default-directory cwd)
|
||||
(+workspace-message
|
||||
(format "Switched to '%s' in new workspace" (+workspace-current-name))
|
||||
'success))))
|
||||
(setq projectile-switch-project-action #'+workspaces|per-project)
|
||||
|
||||
;; only auto-save when real buffers are present
|
||||
(advice-add #'persp-asave-on-exit :around #'+workspaces*autosave-real-buffers)
|
||||
|
@ -68,7 +80,10 @@ renamed.")
|
|||
(remove-hook 'delayed-warnings-hook #'display-delayed-warnings)
|
||||
(defun +workspaces|init (&optional frame)
|
||||
(unless persp-mode
|
||||
(persp-mode +1))
|
||||
(persp-mode +1)
|
||||
;; Ensure `persp-kill-buffer-query-function' is last in kill-buffer-query-functions
|
||||
(remove-hook 'kill-buffer-query-functions 'persp-kill-buffer-query-function)
|
||||
(add-hook 'kill-buffer-query-functions 'persp-kill-buffer-query-function t))
|
||||
(let ((frame (or frame (selected-frame))))
|
||||
(unless noninteractive
|
||||
;; The default perspective persp-mode makes (defined by
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
(require! :feature workspaces)
|
||||
|
||||
(defmacro -with-workspace! (buffer-args &rest body)
|
||||
(defmacro with-workspace!! (buffer-args &rest body)
|
||||
(declare (indent defun))
|
||||
(let ((buffers
|
||||
(cl-loop for bsym in buffer-args
|
||||
|
@ -27,14 +27,19 @@
|
|||
|
||||
;;
|
||||
(def-test! init
|
||||
(-with-workspace! ()
|
||||
(with-workspace!! ()
|
||||
(should (equal (+workspace-current-name) +workspaces-main))))
|
||||
|
||||
(def-test! advice
|
||||
(should (advice-member-p #'+workspaces*auto-add-buffer #'switch-to-buffer)))
|
||||
(def-test! auto-add-buffer-to-persp
|
||||
(let ((a (generate-new-buffer "a")))
|
||||
(doom-set-buffer-real a t)
|
||||
(with-workspace!! ()
|
||||
(should-not (+workspace-contains-buffer-p a))
|
||||
(switch-to-buffer a)
|
||||
(should (+workspace-contains-buffer-p a)))))
|
||||
|
||||
(def-test! current
|
||||
(-with-workspace! ()
|
||||
(with-workspace!! ()
|
||||
(should (equal (+workspace-current-name) +workspaces-main))
|
||||
(should (+workspace-exists-p +workspaces-main))
|
||||
(let ((workspace (+workspace-get +workspaces-main))
|
||||
|
@ -45,7 +50,7 @@
|
|||
(should (equal workspace current-workspace)))))
|
||||
|
||||
(def-test! workspace-list
|
||||
(-with-workspace! ()
|
||||
(with-workspace!! ()
|
||||
(should (equal (+workspace-list-names)
|
||||
(list (+workspace-current-name))))
|
||||
(should (equal (+workspace-list)
|
||||
|
@ -53,7 +58,7 @@
|
|||
|
||||
(def-test! workspace-crud
|
||||
"Creating, reading, updating and deleting workspaces."
|
||||
(-with-workspace! ()
|
||||
(with-workspace!! ()
|
||||
(let ((new-workspace-name "*new-test*")
|
||||
(renamed-workspace-name "*old-test*"))
|
||||
(should (+workspace-new new-workspace-name))
|
||||
|
@ -67,14 +72,14 @@
|
|||
(should (= (length (+workspace-list-names)) 1)))))
|
||||
|
||||
(def-test! workspace-switch
|
||||
(-with-workspace! ()
|
||||
(with-workspace!! ()
|
||||
(let ((new-workspace-name "*new-test*"))
|
||||
(should-error (+workspace-switch new-workspace-name))
|
||||
(should (+workspace-switch new-workspace-name t))
|
||||
(should (equal (+workspace-current-name) new-workspace-name)))))
|
||||
|
||||
(def-test! buffer-list
|
||||
(-with-workspace! (a b)
|
||||
(with-workspace!! (a b)
|
||||
(let ((c (get-buffer-create "c"))
|
||||
(d (get-buffer-create "d")))
|
||||
(should (+workspace-contains-buffer-p a))
|
||||
|
|
|
@ -5,26 +5,36 @@ This module adds support for the C-family of languages: C, C++, and Objective-C.
|
|||
+ Code completion (~company-irony~)
|
||||
+ eldoc support (~irony-eldoc~)
|
||||
+ Syntax-checking (~flycheck-irony~)
|
||||
+ Code navigation (~irony~)
|
||||
+ Code navigation (~rtags~)
|
||||
+ File Templates ([[../../feature/file-templates/templates/c-mode][c-mode]], [[../../feature/file-templates/templates/c++-mode][c++-mode]])
|
||||
+ Snippets ([[https://github.com/hlissner/emacs-snippets/tree/master/cc-mode][cc-mode]], [[https://github.com/hlissner/emacs-snippets/tree/master/c-mode][c-mode]], [[https://github.com/hlissner/emacs-snippets/tree/master/c++-mode][c++-mode]])
|
||||
+ Several improvements to C++11 indentation and syntax highlighting.
|
||||
|
||||
#+begin_quote
|
||||
C contends with Haskell and Ruby for my favorite language. That said, it's more accurate to say I write C, but with two or three C++ features.
|
||||
C contends with Haskell and Ruby for my favorite language. That said, it's more
|
||||
accurate to say I write C, but a C++ feature or three.
|
||||
|
||||
The module provides nominal support for Objective-C, which I really only use to inspect generated glue code for iOS mobile apps. Otherwise, I prefer Swift.
|
||||
The module provides nominal support for Objective-C, which I really only use to
|
||||
inspect generated glue code for iOS mobile apps. Otherwise, I prefer Swift.
|
||||
#+end_quote
|
||||
|
||||
* Table of Contents :TOC:
|
||||
- [[#install][Install]]
|
||||
- [[#macos][MacOS]]
|
||||
- [[#arch-linux][Arch Linux]]
|
||||
- [[#irony-server][irony-server]]
|
||||
- [[#rtags][rtags]]
|
||||
- [[#configure][Configure]]
|
||||
- [[#compile-settings][Compile settings]]
|
||||
|
||||
* Install
|
||||
This module requires ~irony-server~ for most of its features, which depends on ~cmake~ and ~libclang~.
|
||||
This module requires:
|
||||
|
||||
** MacOS
|
||||
+ irony-server
|
||||
+ rtags
|
||||
|
||||
** irony-server
|
||||
Irony powers the code completion, eldoc and syntax checking systems.
|
||||
|
||||
*** MacOS
|
||||
Due to linking issues, MacOS users must compile irony-server manually:
|
||||
|
||||
#+BEGIN_SRC sh :tangle (if (doom-system-os 'macos) "yes")
|
||||
|
@ -49,10 +59,46 @@ popd
|
|||
rm -rf irony-mode
|
||||
#+END_SRC
|
||||
|
||||
** Arch Linux
|
||||
*** Arch Linux
|
||||
#+BEGIN_SRC sh :tangle (if (doom-system-os 'arch) "yes")
|
||||
sudo pacman --needed --noconfirm -S clang cmake
|
||||
#+END_SRC
|
||||
|
||||
Then run ~M-x irony-install-server~ in Emacs.
|
||||
|
||||
** rtags
|
||||
Code navigation requires an [[https://github.com/Andersbakken/rtags][rtags]] server (~rdm~) installed and running. This
|
||||
should be available through your OS's package manager.
|
||||
|
||||
This module will auto-start ~rdm~ when you open C/C++ buffers (so long as one
|
||||
isn't already). If you prefer to run it yourself, outside of Emacs:
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
rdm &
|
||||
rc -J $PROJECT_ROOT # loads PROJECT_ROOT's compile_commands.json
|
||||
#+END_SRC
|
||||
|
||||
* Configure
|
||||
** Compile settings
|
||||
By default, a set of default compile settings are defined in
|
||||
~+cc-default-compiler-options~ for C, C++ and Objective C. Irony, rtags and
|
||||
flycheck will fall back to these.
|
||||
|
||||
To make these tools aware of project specific build settings, you need a JSON
|
||||
[[https://sarcasm.github.io/notes/dev/compilation-database.html#ninja][compilation database]] present (i.e. a ~compile_commands.json~ file).
|
||||
|
||||
There are [[https://sarcasm.github.io/notes/dev/compilation-database.html][many ways to generate one]]. I use [[http://www.cmake.org/][CMake]] and [[https://github.com/rizsotto/Bear][bear]]:
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
# For CMake projects
|
||||
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .
|
||||
|
||||
# For non-CMake projects
|
||||
make clean
|
||||
bear make
|
||||
#+END_SRC
|
||||
|
||||
#+begin_quote
|
||||
Use ~M-x +cc/reload-compile-db~ to reload your compile db in an already-open
|
||||
C/C++/ObjC buffer.
|
||||
#+end_quote
|
||||
|
|
|
@ -1,5 +1,24 @@
|
|||
;;; lang/cc/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun +cc/reload-compile-db (&optional force-p)
|
||||
"Reload the current project's JSON compilation database."
|
||||
(interactive "P")
|
||||
(unless (memq major-mode '(c-mode c++-mode objc-mode))
|
||||
(user-error "Not a C/C++/ObjC buffer"))
|
||||
(unless (doom-project-has! "compile_commands.json")
|
||||
(user-error "No compile_commands.json file"))
|
||||
;; first rtag
|
||||
(when (and (featurep 'rtags)
|
||||
rtags-enabled
|
||||
(executable-find "rc"))
|
||||
(with-temp-buffer
|
||||
(message "Reloaded compile commands for rtags daemon")
|
||||
(rtags-call-rc :silent t "-J" (doom-project-root))))
|
||||
;; then irony
|
||||
(when (and (featurep 'irony) irony-mode)
|
||||
(+cc|irony-init-compile-options)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +cc*align-lambda-arglist (orig-fun &rest args)
|
||||
"Improve indentation of continued C++11 lambda function opened as argument."
|
||||
|
@ -66,8 +85,8 @@
|
|||
;;;###autoload
|
||||
(defun +cc|irony-init-compile-options ()
|
||||
"Initialize compiler options for irony-mode. It searches for the nearest
|
||||
compilation database and initailizes it. If none was found, it uses
|
||||
`+cc-c++-compiler-options'.
|
||||
compilation database and initailizes it, otherwise falling back on
|
||||
`+cc-default-compiler-options' and `+cc-default-include-paths'.
|
||||
|
||||
See https://github.com/Sarcasm/irony-mode#compilation-database for details on
|
||||
compilation dbs."
|
||||
|
@ -75,8 +94,8 @@ compilation dbs."
|
|||
(require 'irony-cdb)
|
||||
(unless (irony-cdb-autosetup-compile-options)
|
||||
(irony-cdb--update-compile-options
|
||||
(append (delq nil (cdr-safe (assq major-mode +cc-compiler-options)))
|
||||
(cl-loop for path in +cc-include-paths
|
||||
(append (delq nil (cdr-safe (assq major-mode +cc-default-compiler-options)))
|
||||
(cl-loop for path in +cc-default-include-paths
|
||||
nconc (list "-I" path)))
|
||||
(doom-project-root)))))
|
||||
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
;;; lang/cc/config.el --- c, c++, and obj-c -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +cc-include-paths (list "include/")
|
||||
"A list of paths, relative to a project root, to search for headers in C/C++.
|
||||
Paths can be absolute.
|
||||
(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 JSON
|
||||
compilation database.")
|
||||
|
||||
The purpose of this variable is to ensure syntax checkers and code-completion
|
||||
knows where to look for headers.")
|
||||
|
||||
(defvar +cc-compiler-options
|
||||
(defvar +cc-default-compiler-options
|
||||
`((c-mode . nil)
|
||||
(c++-mode
|
||||
. ,(list "-std=c++11" ; use C++11 by default
|
||||
|
@ -112,12 +110,16 @@ compilation database is present in the project.")
|
|||
:after cc-mode
|
||||
:commands irony-install-server
|
||||
:preface (setq irony-server-install-prefix (concat doom-etc-dir "irony-server/"))
|
||||
:hook ((c-mode c++-mode objc-mode) . irony-mode)
|
||||
:init
|
||||
(defun +cc|init-irony-mode ()
|
||||
(when (memq major-mode '(c-mode c++-mode objc-mode))
|
||||
(irony-mode +1)))
|
||||
(add-hook! (c-mode c++-mode objc-mode) #'+cc|init-irony-mode)
|
||||
:config
|
||||
(unless (file-directory-p irony-server-install-prefix)
|
||||
(warn "irony-mode: server isn't installed; run M-x irony-install-server"))
|
||||
;; Initialize compilation database, if present. Otherwise, fall back on
|
||||
;; `+cc-compiler-options'.
|
||||
;; `+cc-default-compiler-options'.
|
||||
(add-hook 'irony-mode-hook #'+cc|irony-init-compile-options))
|
||||
|
||||
(def-package! irony-eldoc
|
||||
|
@ -144,7 +146,8 @@ compilation database is present in the project.")
|
|||
;;
|
||||
|
||||
(def-package! cmake-mode
|
||||
:mode "CMakeLists\\.txt$"
|
||||
:mode "/CMakeLists\\.txt$"
|
||||
:mode "\\.cmake\\$"
|
||||
:config
|
||||
(set! :company-backend 'cmake-mode '(company-cmake company-yasnippet)))
|
||||
|
||||
|
@ -163,19 +166,76 @@ compilation database is present in the project.")
|
|||
|
||||
|
||||
;;
|
||||
;; Plugins
|
||||
;; Company plugins
|
||||
;;
|
||||
|
||||
(when (featurep! :completion company)
|
||||
(def-package! company-cmake :after cmake-mode)
|
||||
(def-package! company-cmake
|
||||
:when (featurep! :completion company)
|
||||
:after cmake-mode)
|
||||
|
||||
(def-package! company-irony :after irony)
|
||||
(def-package! company-irony
|
||||
:when (featurep! :completion company)
|
||||
:after irony)
|
||||
|
||||
(def-package! company-irony-c-headers :after company-irony)
|
||||
(def-package! company-irony-c-headers
|
||||
:when (featurep! :completion company)
|
||||
:after company-irony)
|
||||
|
||||
(def-package! company-glsl
|
||||
:after glsl-mode
|
||||
:config
|
||||
(if (executable-find "glslangValidator")
|
||||
(warn "glsl-mode: couldn't find glslangValidator, disabling company-glsl")
|
||||
(set! :company-backend 'glsl-mode '(company-glsl)))))
|
||||
(def-package! company-glsl
|
||||
:when (featurep! :completion company)
|
||||
:after glsl-mode
|
||||
:config
|
||||
(if (executable-find "glslangValidator")
|
||||
(warn "glsl-mode: couldn't find glslangValidator, disabling company-glsl")
|
||||
(set! :company-backend 'glsl-mode '(company-glsl))))
|
||||
|
||||
|
||||
;;
|
||||
;; Rtags Support
|
||||
;;
|
||||
|
||||
(def-package! rtags
|
||||
:after cc-mode
|
||||
:config
|
||||
(setq rtags-autostart-diagnostics t
|
||||
rtags-use-bookmarks nil
|
||||
rtags-completions-enabled nil
|
||||
;; If not using ivy or helm to view results, use a pop-up window rather
|
||||
;; than displaying it in the current window...
|
||||
rtags-results-buffer-other-window t
|
||||
;; ...and don't auto-jump to first match before making a selection.
|
||||
rtags-jump-to-first-match nil)
|
||||
|
||||
(let ((bins (cl-remove-if-not #'executable-find '("rdm" "rc"))))
|
||||
(if (/= (length bins) 2)
|
||||
(warn "cc-mode: couldn't find %s, disabling rtags support" bins)
|
||||
(add-hook! (c-mode c++-mode) #'rtags-start-process-unless-running)
|
||||
(set! :jump '(c-mode c++-mode)
|
||||
:definition #'rtags-find-symbol-at-point
|
||||
:references #'rtags-find-references-at-point)))
|
||||
|
||||
(add-hook 'doom-cleanup-hook #'rtags-cancel-process)
|
||||
(add-hook! kill-emacs (ignore-errors (rtags-cancel-process)))
|
||||
|
||||
;; Use rtags-imenu instead of imenu/counsel-imenu
|
||||
(map! :map (c-mode-map c++-mode-map) [remap imenu] #'rtags-imenu)
|
||||
|
||||
(add-hook 'rtags-jump-hook #'evil-set-jump)
|
||||
(add-hook 'rtags-after-find-file-hook #'recenter))
|
||||
|
||||
(def-package! ivy-rtags
|
||||
:when (featurep! :completion ivy)
|
||||
:after rtags
|
||||
:init
|
||||
;; NOTE Ivy integration breaks when rtags is byte-compiled with Emacs 26 or
|
||||
;; later, so we un-byte-compile it before we load it.
|
||||
(eval-when-compile
|
||||
(when (>= emacs-major-version 26)
|
||||
(when-let* ((elc-file (locate-library "rtags.elc" t doom--package-load-path)))
|
||||
(delete-file elc-file))))
|
||||
:config (setq rtags-display-result-backend 'ivy))
|
||||
|
||||
(def-package! helm-rtags
|
||||
:when (featurep! :completion helm)
|
||||
:after rtags
|
||||
:config (setq rtags-display-result-backend 'helm))
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
(package! glsl-mode)
|
||||
(package! irony)
|
||||
(package! irony-eldoc)
|
||||
(package! opencl-mode)
|
||||
(package! modern-cpp-font-lock)
|
||||
(package! opencl-mode)
|
||||
|
||||
(when (featurep! :feature syntax-checker)
|
||||
(package! flycheck-irony))
|
||||
|
@ -19,3 +19,8 @@
|
|||
(package! company-irony)
|
||||
(package! company-irony-c-headers))
|
||||
|
||||
(package! rtags)
|
||||
(when (featurep! :completion ivy)
|
||||
(package! ivy-rtags))
|
||||
(when (featurep! :completion helm)
|
||||
(package! helm-rtags))
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"Evaluate a region and print it to the echo area (if one line long), otherwise
|
||||
to a pop up buffer."
|
||||
(require 'pp)
|
||||
(let ((result (eval (read (buffer-substring-no-properties beg end))))
|
||||
(let ((result (eval (read (concat "(progn " (buffer-substring-no-properties beg end) "\n)"))))
|
||||
(buf (get-buffer-create "*doom eval*"))
|
||||
(inhibit-read-only t)
|
||||
lines)
|
||||
|
|
|
@ -10,19 +10,12 @@
|
|||
meghanada-use-eldoc t
|
||||
meghanada-use-auto-start t)
|
||||
|
||||
(add-hook 'java-mode-hook #'rainbow-delimiters-mode)
|
||||
|
||||
;; Setup on first use
|
||||
(unless (bound-and-true-p byte-compile-current-file)
|
||||
(meghanada-install-server)
|
||||
(if (file-exists-p (meghanada--locate-server-jar))
|
||||
(add-hook! 'meghanada-mode-hook #'(flycheck-mode eldoc-mode))
|
||||
(warn "java-mode: meghanada-server not installed, java-mode will run with reduced functionality")))
|
||||
|
||||
(set! :jump 'java-mode
|
||||
:definition #'meghanada-jump-declaration
|
||||
:references #'meghanada-reference)
|
||||
|
||||
(add-hook! 'meghanada-mode-hook #'(flycheck-mode eldoc-mode))
|
||||
|
||||
;;
|
||||
(def-menu! +java/refactor-menu
|
||||
"Refactoring commands for `java-mode' buffers."
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
;;; lang/java/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(add-hook 'java-mode-hook #'rainbow-delimiters-mode)
|
||||
|
||||
(cond ((featurep! +meghanada) (load! +meghanada))
|
||||
((featurep! +eclim) ; FIXME lang/java +eclim
|
||||
;;(load! +eclim)
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
;; + `+org-attach/url'
|
||||
;; + :org [FILE/URL]
|
||||
|
||||
(defvar +org-attach-dir (expand-file-name ".attach/" +org-dir)
|
||||
(defvar +org-attach-dir ".attach/"
|
||||
"Where to store attachments (relative to current org file).")
|
||||
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
|||
|
||||
(advice-add #'org-download-enable :override #'ignore)
|
||||
:config
|
||||
(setq-default org-download-image-dir +org-attach-dir
|
||||
(setq-default org-download-image-dir org-attach-directory
|
||||
org-download-heading-lvl nil
|
||||
org-download-timestamp "_%Y%m%d_%H%M%S")
|
||||
|
||||
|
@ -61,12 +61,12 @@
|
|||
|
||||
;;
|
||||
(after! org
|
||||
(setq org-attach-directory +org-attach-dir)
|
||||
(setq org-attach-directory (expand-file-name +org-attach-dir +org-dir))
|
||||
|
||||
(push (car (last (split-string +org-attach-dir "/" t)))
|
||||
projectile-globally-ignored-directories)
|
||||
|
||||
(after! recentf
|
||||
(push (format "%s.+$" (regexp-quote +org-attach-dir))
|
||||
(push (format "%s.+$" (regexp-quote org-attach-directory))
|
||||
recentf-exclude)))
|
||||
|
||||
|
|
|
@ -10,16 +10,19 @@
|
|||
;; anywhere I can call org-capture (whether or not Emacs is open/running),
|
||||
;; like, say, from qutebrowser, vimperator, dmenu or a global keybinding.
|
||||
|
||||
(defvar +org-default-todo-file "todo.org"
|
||||
"TODO")
|
||||
|
||||
(defvar +org-default-notes-file "notes.org"
|
||||
"TODO")
|
||||
|
||||
(defvar org-capture-templates
|
||||
'(("t" "Todo" entry
|
||||
(file+headline (expand-file-name "todo.org" +org-dir) "Inbox")
|
||||
(file+headline +org-default-todo-file "Inbox")
|
||||
"* [ ] %?\n%i" :prepend t :kill-buffer t)
|
||||
|
||||
("n" "Notes" entry
|
||||
(file+headline org-default-notes-file "Inbox")
|
||||
(file+headline +org-default-notes-file "Inbox")
|
||||
"* %u %?\n%i" :prepend t :kill-buffer t)))
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
#+TITLE: :lang org
|
||||
|
||||
This module provides support for org-mode.
|
||||
|
||||
+ A custom attachment system that keeps files in a centralized location.
|
||||
+ Drag-and-drop support for images (with inline preview) and media files (drops
|
||||
a file icon and a short link).
|
||||
+ Executable code blocks with support for a variety of languages and tools,
|
||||
including REST requests, SQL, google translate, plantuml, and matlab.
|
||||
+ An org-capture workflow that works from outside Emacs (through the
|
||||
=bin/org-capture= shell script).
|
||||
+ Exported documents are saved to a centralized location.
|
||||
+ A configuration for using org-mode for slide-show presentations, or exporting
|
||||
org files to reveal.js slideshows.
|
||||
+ (TODO) A static site generator based in org-mode and Emacs.
|
||||
|
||||
#+begin_quote
|
||||
org-mode is a beast, and Doom's most difficult module to maintain. And its most
|
||||
important. This module is /highly/ opinionated and experimental; my foray into
|
||||
learning org is a neverending quest.
|
||||
#+end_quote
|
||||
|
||||
* Table of Contents :TOC:
|
||||
- [[#install][Install]]
|
||||
- [[#macos][MacOS]]
|
||||
- [[#arch-linux][Arch Linux]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#usage][Usage]]
|
||||
- [[#appendix][Appendix]]
|
||||
|
||||
* Install
|
||||
Org has no hard dependencies, but there are some things you'll need to make use of Org's more esoteric features.
|
||||
|
||||
+ For inline LaTeX previews, you need ~latex~ and ~dvipng~.
|
||||
+ To run babel code blocks, you need whatever dependencies those languages
|
||||
need. It is recommended you enable the associated module in =lang/= and ensure
|
||||
its dependencies are met.
|
||||
+ The =+crm= module uses a sqlite database to manage your contacts, invoices,
|
||||
and projects; this needs sqlite installed.
|
||||
|
||||
** MacOS
|
||||
#+BEGIN_SRC sh
|
||||
brew cask install mactex
|
||||
brew install sqlite
|
||||
#+END_SRC
|
||||
|
||||
** Arch Linux
|
||||
#+BEGIN_SRC sh
|
||||
sudo pacman --needed --noconfirm -S texlive-core texlive-bin texlive-science sqlite
|
||||
#+END_SRC
|
||||
|
||||
* Configuration
|
||||
(Coming soon)
|
||||
|
||||
* Usage
|
||||
(Coming soon)
|
||||
|
||||
* Appendix
|
||||
(Coming soon)
|
|
@ -78,7 +78,7 @@ the cursor."
|
|||
(defun +org-attach-download-dnd (uri action)
|
||||
"TODO"
|
||||
(if (eq major-mode 'org-mode)
|
||||
(+org-attach:url uri)
|
||||
(+org-attach/uri uri)
|
||||
(let ((dnd-protocol-alist
|
||||
(rassq-delete-all '+org-attach-download-dnd
|
||||
(copy-alist dnd-protocol-alist))))
|
||||
|
@ -98,7 +98,7 @@ the cursor."
|
|||
(delete-region (match-beginning 0) (match-end 0))
|
||||
(newline))
|
||||
(cond ((image-type-from-file-name filename)
|
||||
(when (file-in-directory-p filename +org-attach-dir)
|
||||
(when (file-in-directory-p filename org-attach-directory)
|
||||
(setq filename (file-relative-name filename +org-dir)))
|
||||
(insert
|
||||
(concat (if (= org-download-image-html-width 0)
|
||||
|
@ -113,9 +113,9 @@ the cursor."
|
|||
(t
|
||||
(insert
|
||||
(format "%s [[./%s][%s]] "
|
||||
(org-attach--icon filename)
|
||||
(+org-attach--icon filename)
|
||||
(file-relative-name filename buffer-file-name)
|
||||
(file-name-nondirectory (directory-file-name rel-path)))))))
|
||||
(file-name-nondirectory (directory-file-name filename)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-attach*relative-to-attach-dir (orig-fn &rest args)
|
||||
|
@ -124,9 +124,7 @@ the cursor."
|
|||
(let* ((context (save-match-data (org-element-context)))
|
||||
(file (org-link-unescape (org-element-property :path context)))
|
||||
(default-directory
|
||||
(if (string-prefix-p
|
||||
(concat "./" (car (last (split-string +org-attach-dir "/" t))))
|
||||
file)
|
||||
(if (file-in-directory-p file org-attach-directory)
|
||||
+org-dir
|
||||
default-directory)))
|
||||
(apply orig-fn args))
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
:commands org-crypt-use-before-save-magic
|
||||
:config
|
||||
(setq org-tags-exclude-from-inheritance '("crypt")
|
||||
org-crypt-key user-mail-address
|
||||
epa-file-encrypt-to user-mail-address))
|
||||
org-crypt-key user-mail-address))
|
||||
|
||||
(def-package! org-bullets
|
||||
:commands org-bullets-mode)
|
||||
|
@ -91,12 +90,13 @@ unfold to point on startup."
|
|||
(sp--looking-at-p "\\s-*]")))
|
||||
|
||||
;; make delimiter auto-closing a little more conservative
|
||||
(sp-with-modes 'org-mode
|
||||
(sp-local-pair "*" nil :unless '(sp-point-after-word-p sp-point-before-word-p sp-point-at-bol-p))
|
||||
(sp-local-pair "_" nil :unless '(sp-point-after-word-p sp-point-before-word-p))
|
||||
(sp-local-pair "/" nil :unless '(sp-point-after-word-p sp-point-before-word-p +org-sp-point-in-checkbox-p))
|
||||
(sp-local-pair "~" nil :unless '(sp-point-after-word-p sp-point-before-word-p))
|
||||
(sp-local-pair "=" nil :unless '(sp-point-after-word-p sp-point-before-word-p))))
|
||||
(after! smartparens
|
||||
(sp-with-modes 'org-mode
|
||||
(sp-local-pair "*" nil :unless '(sp-point-after-word-p sp-point-before-word-p sp-point-at-bol-p))
|
||||
(sp-local-pair "_" nil :unless '(sp-point-after-word-p sp-point-before-word-p))
|
||||
(sp-local-pair "/" nil :unless '(sp-point-after-word-p sp-point-before-word-p +org-sp-point-in-checkbox-p))
|
||||
(sp-local-pair "~" nil :unless '(sp-point-after-word-p sp-point-before-word-p))
|
||||
(sp-local-pair "=" nil :unless '(sp-point-after-word-p sp-point-before-word-p)))))
|
||||
|
||||
(defun +org|enable-auto-reformat-tables ()
|
||||
"Realign tables exiting insert mode (`evil-mode')."
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/org/packages.el
|
||||
|
||||
;; NOTE This is an insecure source, but unavoidable if we want org 9.0+ (which
|
||||
;; this module requires). orgmode.org offers no secure access to this repo. If
|
||||
;; this bothers you, comment out this `package!' block and download
|
||||
;; org-plus-contrib from orgmode.org.
|
||||
(package! org-plus-contrib :recipe (:fetcher git :url "http://orgmode.org/org-mode.git"))
|
||||
(when (version< emacs-version "26.1")
|
||||
;; We want org 9.1.x, but the org packaged with Emacs 25.x and under is 8.x.
|
||||
;; The only secure (and reasonably trustworthy) source for this is via
|
||||
;; emacsmirror. Emacs 26+ comes with Org 9.1.4.
|
||||
(package! org-plus-contrib
|
||||
:recipe (:fetcher github :repo "emacsmirror/org" :files (:defaults "contrib/lisp/*.el"))))
|
||||
|
||||
(package! org-bullets :recipe (:fetcher github :repo "hlissner/org-bullets"))
|
||||
(package! toc-org)
|
||||
|
|
|
@ -1,40 +1,40 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/org/test/autoload-org.el
|
||||
|
||||
(defmacro should-org-buffer! (source expected &rest body)
|
||||
`(should-buffer! ,source ,expected
|
||||
(defmacro should-org-buffer!! (source expected &rest body)
|
||||
`(should-buffer!! ,source ,expected
|
||||
(org-mode)
|
||||
,@body))
|
||||
|
||||
|
||||
;;
|
||||
;; `+org/insert-item'
|
||||
(def-test! insert-item-h1
|
||||
"Should append/prepend new first-level headers with an extra newline."
|
||||
(should-org-buffer! ("* {0}Header") ("* Header\n\n* {|}")
|
||||
(should-org-buffer!! ("* {0}Header") ("* Header\n\n* {|}")
|
||||
(+org/insert-item 'below))
|
||||
(should-org-buffer! ("* {0}Header") ("* {|}\n\n* Header")
|
||||
(should-org-buffer!! ("* {0}Header") ("* {|}\n\n* Header")
|
||||
(+org/insert-item 'above)))
|
||||
|
||||
(def-test! insert-item-h2
|
||||
"Should append/prepend new second-level (and higher) headers without an extra
|
||||
newline."
|
||||
(should-org-buffer! ("** {0}Header") ("** Header\n** {|}")
|
||||
(should-org-buffer!! ("** {0}Header") ("** Header\n** {|}")
|
||||
(+org/insert-item 'below))
|
||||
(should-org-buffer! ("** {0}Header") ("** {|}\n** Header")
|
||||
(should-org-buffer!! ("** {0}Header") ("** {|}\n** Header")
|
||||
(+org/insert-item 'above)))
|
||||
|
||||
(def-test! insert-item-plain-list
|
||||
"Should append/prepend new second-level (and higher) headers without an extra
|
||||
newline."
|
||||
(should-org-buffer! ("+ {0}List item") ("+ List item\n+ {|}")
|
||||
(should-org-buffer!! ("+ {0}List item") ("+ List item\n+ {|}")
|
||||
(+org/insert-item 'below))
|
||||
(should-org-buffer! ("+ {0}List item"
|
||||
(should-org-buffer!! ("+ {0}List item"
|
||||
" + Sub item")
|
||||
("+ List item"
|
||||
" + Sub item"
|
||||
"+ {|}")
|
||||
(+org/insert-item 'below))
|
||||
(should-org-buffer! ("+ {0}List item"
|
||||
(should-org-buffer!! ("+ {0}List item"
|
||||
"+ Next item")
|
||||
("+ List item"
|
||||
"+ {|}"
|
||||
|
|
|
@ -5,3 +5,5 @@
|
|||
(require! :lang org)
|
||||
|
||||
(require 'org (locate-library "org" nil doom--package-load-path))
|
||||
|
||||
;;
|
||||
|
|
|
@ -84,8 +84,7 @@
|
|||
:config
|
||||
(unless (executable-find "phpctags")
|
||||
(warn "php-mode: phpctags isn't installed, auto-completion will be gimped"))
|
||||
|
||||
(setq ac-php-tags-path (concat doom-etc-dir "ac-php/")))
|
||||
(setq ac-php-tags-path (concat doom-cache-dir "ac-php/")))
|
||||
|
||||
|
||||
;;
|
||||
|
|
|
@ -5,4 +5,4 @@ Use this directory to store your private configuration modules.
|
|||
Mine is included as a reference. I recommend you neither delete nor rename it, to avoid merge conflicts upstream.
|
||||
|
||||
-----
|
||||
You'll find [[/wiki/Customization][more information about customizing Doom]] on the [[/wiki][wiki]].
|
||||
You'll find [[https://github.com/hlissner/doom-emacs/wiki/Customization][more information about customizing Doom]] on the [[https://github.com/hlissner/doom-emacs/wiki][wiki]].
|
||||
|
|
733
modules/private/default/+bindings.el
Normal file
733
modules/private/default/+bindings.el
Normal file
|
@ -0,0 +1,733 @@
|
|||
;;; private/default/+bindings.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; This files defines a Spacemacs-esque keybinding scheme
|
||||
|
||||
(map! [remap evil-jump-to-tag] #'projectile-find-tag
|
||||
[remap find-tag] #'projectile-find-tag
|
||||
|
||||
;; Ensure there are no conflicts
|
||||
:nmvo doom-leader-key nil
|
||||
:nmvo doom-localleader-key nil
|
||||
|
||||
;; --- Global keybindings ---------------------------
|
||||
;; Make M-x available everywhere
|
||||
:gnvime "M-x" #'execute-extended-command
|
||||
:gnvime "A-x" #'execute-extended-command
|
||||
|
||||
;; A little sandbox to run code in
|
||||
:gnvime "M-;" #'eval-expression
|
||||
:gnvime "M-:" #'doom/open-scratch-buffer
|
||||
|
||||
;; Text-scaling
|
||||
"M-+" (λ! (text-scale-set 0))
|
||||
"M-=" #'text-scale-increase
|
||||
"M--" #'text-scale-decrease
|
||||
|
||||
;; Simple window navigation/manipulation
|
||||
"C-`" #'doom/popup-toggle
|
||||
"C-~" #'doom/popup-raise
|
||||
"M-t" #'+workspace/new
|
||||
"M-T" #'+workspace/display
|
||||
"M-w" #'delete-window
|
||||
"M-W" #'+workspace/close-workspace-or-frame
|
||||
"M-n" #'evil-buffer-new
|
||||
"M-N" #'make-frame
|
||||
"M-1" (λ! (+workspace/switch-to 0))
|
||||
"M-2" (λ! (+workspace/switch-to 1))
|
||||
"M-3" (λ! (+workspace/switch-to 2))
|
||||
"M-4" (λ! (+workspace/switch-to 3))
|
||||
"M-5" (λ! (+workspace/switch-to 4))
|
||||
"M-6" (λ! (+workspace/switch-to 5))
|
||||
"M-7" (λ! (+workspace/switch-to 6))
|
||||
"M-8" (λ! (+workspace/switch-to 7))
|
||||
"M-9" (λ! (+workspace/switch-to 8))
|
||||
"M-0" #'+workspace/switch-to-last
|
||||
|
||||
;; Other sensible, textmate-esque global bindings
|
||||
:ne "M-r" #'+eval/buffer
|
||||
:ne "M-R" #'+eval/region-and-replace
|
||||
:ne "M-b" #'+eval/build
|
||||
:ne "M-a" #'mark-whole-buffer
|
||||
:ne "M-c" #'evil-yank
|
||||
:ne "M-q" (if (daemonp) #'delete-frame #'save-buffers-kill-emacs)
|
||||
:ne "M-f" #'swiper
|
||||
:ne "C-M-f" #'doom/toggle-fullscreen
|
||||
:n "M-s" #'save-buffer
|
||||
:m "A-j" #'+default:multi-next-line
|
||||
:m "A-k" #'+default:multi-previous-line
|
||||
:nv "C-SPC" #'+evil:fold-toggle
|
||||
:gnvimer "M-v" #'clipboard-yank
|
||||
;; Easier window navigation
|
||||
:en "C-h" #'evil-window-left
|
||||
:en "C-j" #'evil-window-down
|
||||
:en "C-k" #'evil-window-up
|
||||
:en "C-l" #'evil-window-right
|
||||
|
||||
"C-x p" #'doom/other-popup
|
||||
|
||||
|
||||
;; --- <leader> -------------------------------------
|
||||
(:leader
|
||||
:desc "Ex command" :nv ";" #'evil-ex
|
||||
:desc "M-x" :nv ":" #'execute-extended-command
|
||||
:desc "Pop up scratch buffer" :nv "x" #'doom/open-scratch-buffer
|
||||
:desc "Org Capture" :nv "X" #'+org-capture/open
|
||||
|
||||
;; Most commonly used
|
||||
:desc "Find file in project" :n "SPC" #'projectile-find-file
|
||||
:desc "Switch workspace buffer" :n "," #'persp-switch-to-buffer
|
||||
:desc "Switch buffer" :n "<" #'switch-to-buffer
|
||||
:desc "Browse files" :n "." #'find-file
|
||||
:desc "Toggle last popup" :n "~" #'doom/popup-toggle
|
||||
:desc "Eval expression" :n "`" #'eval-expression
|
||||
:desc "Blink cursor line" :n "DEL" #'+doom/blink-cursor
|
||||
:desc "Jump to bookmark" :n "RET" #'bookmark-jump
|
||||
|
||||
;; C-u is used by evil
|
||||
:desc "Universal argument" :n "u" #'universal-argument
|
||||
:desc "window" :n "w" evil-window-map
|
||||
|
||||
(:desc "previous..." :prefix "["
|
||||
:desc "Text size" :nv "[" #'text-scale-decrease
|
||||
:desc "Buffer" :nv "b" #'doom/previous-buffer
|
||||
:desc "Diff Hunk" :nv "d" #'git-gutter:previous-hunk
|
||||
:desc "Todo" :nv "t" #'hl-todo-previous
|
||||
:desc "Error" :nv "e" #'previous-error
|
||||
:desc "Workspace" :nv "w" #'+workspace/switch-left
|
||||
:desc "Smart jump" :nv "h" #'smart-backward
|
||||
:desc "Spelling error" :nv "s" #'evil-prev-flyspell-error
|
||||
:desc "Spelling correction" :n "S" #'flyspell-correct-previous-word-generic)
|
||||
|
||||
(:desc "next..." :prefix "]"
|
||||
:desc "Text size" :nv "]" #'text-scale-increase
|
||||
:desc "Buffer" :nv "b" #'doom/next-buffer
|
||||
:desc "Diff Hunk" :nv "d" #'git-gutter:next-hunk
|
||||
:desc "Todo" :nv "t" #'hl-todo-next
|
||||
:desc "Error" :nv "e" #'next-error
|
||||
:desc "Workspace" :nv "w" #'+workspace/switch-right
|
||||
:desc "Smart jump" :nv "l" #'smart-forward
|
||||
:desc "Spelling error" :nv "s" #'evil-next-flyspell-error
|
||||
:desc "Spelling correction" :n "S" #'flyspell-correct-word-generic)
|
||||
|
||||
(:desc "search" :prefix "/"
|
||||
:desc "Swiper" :nv "/" #'swiper
|
||||
:desc "Imenu" :nv "i" #'imenu
|
||||
:desc "Imenu across buffers" :nv "I" #'imenu-anywhere
|
||||
:desc "Online providers" :nv "o" #'+jump/online-select)
|
||||
|
||||
(:desc "workspace" :prefix "TAB"
|
||||
:desc "Display tab bar" :n "TAB" #'+workspace/display
|
||||
:desc "New workspace" :n "n" #'+workspace/new
|
||||
:desc "Load workspace from file" :n "l" #'+workspace/load
|
||||
:desc "Load last session" :n "L" (λ! (+workspace/load-session))
|
||||
:desc "Save workspace to file" :n "s" #'+workspace/save
|
||||
:desc "Autosave current session" :n "S" #'+workspace/save-session
|
||||
:desc "Switch workspace" :n "." #'+workspace/switch-to
|
||||
:desc "Kill all buffers" :n "x" #'doom/kill-all-buffers
|
||||
:desc "Delete session" :n "X" #'+workspace/kill-session
|
||||
:desc "Delete this workspace" :n "d" #'+workspace/delete
|
||||
:desc "Load session" :n "L" #'+workspace/load-session
|
||||
:desc "Next workspace" :n "]" #'+workspace/switch-right
|
||||
:desc "Previous workspace" :n "[" #'+workspace/switch-left
|
||||
:desc "Switch to 1st workspace" :n "1" (λ! (+workspace/switch-to 0))
|
||||
:desc "Switch to 2nd workspace" :n "2" (λ! (+workspace/switch-to 1))
|
||||
:desc "Switch to 3rd workspace" :n "3" (λ! (+workspace/switch-to 2))
|
||||
:desc "Switch to 4th workspace" :n "4" (λ! (+workspace/switch-to 3))
|
||||
:desc "Switch to 5th workspace" :n "5" (λ! (+workspace/switch-to 4))
|
||||
:desc "Switch to 6th workspace" :n "6" (λ! (+workspace/switch-to 5))
|
||||
:desc "Switch to 7th workspace" :n "7" (λ! (+workspace/switch-to 6))
|
||||
:desc "Switch to 8th workspace" :n "8" (λ! (+workspace/switch-to 7))
|
||||
:desc "Switch to 9th workspace" :n "9" (λ! (+workspace/switch-to 8))
|
||||
:desc "Switch to last workspace" :n "0" #'+workspace/switch-to-last)
|
||||
|
||||
(:desc "buffer" :prefix "b"
|
||||
:desc "New empty buffer" :n "n" #'evil-buffer-new
|
||||
:desc "Switch workspace buffer" :n "b" #'persp-switch-to-buffer
|
||||
:desc "Switch buffer" :n "B" #'switch-to-buffer
|
||||
:desc "Kill buffer" :n "k" #'doom/kill-this-buffer
|
||||
:desc "Kill other buffers" :n "o" #'doom/kill-other-buffers
|
||||
:desc "Save buffer" :n "s" #'save-buffer
|
||||
:desc "Pop scratch buffer" :n "x" #'doom/open-scratch-buffer
|
||||
:desc "Bury buffer" :n "z" #'bury-buffer
|
||||
:desc "Next buffer" :n "]" #'doom/next-buffer
|
||||
:desc "Previous buffer" :n "[" #'doom/previous-buffer
|
||||
:desc "Sudo edit this file" :n "S" #'doom/sudo-this-file)
|
||||
|
||||
(:desc "code" :prefix "c"
|
||||
:desc "List errors" :n "x" #'flycheck-list-errors
|
||||
:desc "Evaluate buffer/region" :n "e" #'+eval/buffer
|
||||
:v "e" #'+eval/region
|
||||
:desc "Evaluate & replace region" :nv "E" #'+eval:replace-region
|
||||
:desc "Build tasks" :nv "b" #'+eval/build
|
||||
:desc "Jump to definition" :n "d" #'+jump/definition
|
||||
:desc "Jump to references" :n "D" #'+jump/references
|
||||
:desc "Open REPL" :n "r" #'+eval/open-repl
|
||||
:v "r" #'+eval:repl)
|
||||
|
||||
(:desc "file" :prefix "f"
|
||||
:desc "Find file" :n "." #'find-file
|
||||
:desc "Sudo find file" :n ">" #'doom/sudo-find-file
|
||||
:desc "Find file in project" :n "/" #'projectile-find-file
|
||||
:desc "Find file from here" :n "?" #'counsel-file-jump
|
||||
:desc "Find other file" :n "a" #'projectile-find-other-file
|
||||
:desc "Open project editorconfig" :n "c" #'editorconfig-find-current-editorconfig
|
||||
:desc "Find file in dotfiles" :n "d" #'+default/find-in-dotfiles
|
||||
:desc "Browse dotfiles" :n "D" #'+default/browse-dotfiles
|
||||
:desc "Find file in emacs.d" :n "e" #'+default/find-in-emacsd
|
||||
:desc "Browse emacs.d" :n "E" #'+default/browse-emacsd
|
||||
:desc "Recent files" :n "r" #'recentf-open-files
|
||||
:desc "Recent project files" :n "R" #'projectile-recentf
|
||||
:desc "Yank filename" :n "y" #'+default/yank-buffer-filename)
|
||||
|
||||
(:desc "git" :prefix "g"
|
||||
:desc "Git status" :n "S" #'magit-status
|
||||
:desc "Git blame" :n "b" #'magit-blame
|
||||
:desc "Git time machine" :n "t" #'git-timemachine-toggle
|
||||
:desc "Git stage hunk" :n "s" #'git-gutter:stage-hunk
|
||||
:desc "Git revert hunk" :n "r" #'git-gutter:revert-hunk
|
||||
:desc "Git revert buffer" :n "R" #'vc-revert
|
||||
:desc "List gists" :n "g" #'+gist:list
|
||||
:desc "Next hunk" :nv "]" #'git-gutter:next-hunk
|
||||
:desc "Previous hunk" :nv "[" #'git-gutter:previous-hunk)
|
||||
|
||||
(:desc "help" :prefix "h"
|
||||
:n "h" help-map
|
||||
:desc "Apropos" :n "a" #'apropos
|
||||
:desc "Reload theme" :n "R" #'doom//reload-theme
|
||||
:desc "Find library" :n "l" #'find-library
|
||||
:desc "Toggle Emacs log" :n "m" #'doom/popup-toggle-messages
|
||||
:desc "Command log" :n "L" #'global-command-log-mode
|
||||
:desc "Describe function" :n "f" #'describe-function
|
||||
:desc "Describe key" :n "k" #'describe-key
|
||||
:desc "Describe char" :n "c" #'describe-char
|
||||
:desc "Describe mode" :n "M" #'describe-mode
|
||||
:desc "Describe variable" :n "v" #'describe-variable
|
||||
:desc "Describe face" :n "F" #'describe-face
|
||||
:desc "Describe DOOM setting" :n "s" #'doom/describe-setting
|
||||
:desc "Describe DOOM module" :n "d" #'doom/describe-module
|
||||
:desc "Find definition" :n "." #'+jump/definition
|
||||
:desc "Find references" :n "/" #'+jump/references
|
||||
:desc "Find documentation" :n "h" #'+jump/documentation
|
||||
:desc "What face" :n "'" #'doom/what-face
|
||||
:desc "What minor modes" :n ";" #'doom/what-minor-mode
|
||||
:desc "Info" :n "i" #'info
|
||||
:desc "Toggle profiler" :n "p" #'doom/toggle-profiler)
|
||||
|
||||
(:desc "insert" :prefix "i"
|
||||
:desc "From kill-ring" :nv "y" #'counsel-yank-pop
|
||||
:desc "From snippet" :nv "s" #'yas-insert-snippet)
|
||||
|
||||
(:desc "notes" :prefix "n"
|
||||
:desc "Find file in notes" :n "n" #'+default/find-in-notes
|
||||
:desc "Browse notes" :n "N" #'+default/browse-notes
|
||||
:desc "Org capture" :n "x" #'+org-capture/open
|
||||
:desc "Browse mode notes" :n "m" #'+org/browse-notes-for-major-mode
|
||||
:desc "Browse project notes" :n "p" #'+org/browse-notes-for-project)
|
||||
|
||||
(:desc "open" :prefix "o"
|
||||
:desc "Default browser" :n "b" #'browse-url-of-file
|
||||
:desc "Debugger" :n "d" #'+debug/open
|
||||
:desc "REPL" :n "r" #'+eval/open-repl
|
||||
:v "r" #'+eval:repl
|
||||
:desc "Neotree" :n "n" #'+neotree/toggle
|
||||
:desc "Terminal" :n "t" #'+term/open-popup
|
||||
:desc "Terminal in project" :n "T" #'+term/open-popup-in-project
|
||||
|
||||
;; applications
|
||||
:desc "APP: elfeed" :n "E" #'=rss
|
||||
:desc "APP: email" :n "M" #'=email
|
||||
:desc "APP: twitter" :n "T" #'=twitter
|
||||
:desc "APP: regex" :n "X" #'=regex
|
||||
|
||||
;; macos
|
||||
(:when IS-MAC
|
||||
:desc "Reveal in Finder" :n "o" #'+macos/reveal-in-finder
|
||||
:desc "Reveal project in Finder" :n "O" #'+macos/reveal-project-in-finder
|
||||
:desc "Send to Transmit" :n "u" #'+macos/send-to-transmit
|
||||
:desc "Send project to Transmit" :n "U" #'+macos/send-project-to-transmit
|
||||
:desc "Send to Launchbar" :n "l" #'+macos/send-to-launchbar
|
||||
:desc "Send project to Launchbar" :n "L" #'+macos/send-project-to-launchbar))
|
||||
|
||||
(:desc "project" :prefix "p"
|
||||
:desc "Browse project" :n "." #'+default/browse-project
|
||||
:desc "Find file in project" :n "/" #'projectile-find-file
|
||||
:desc "Run cmd in project root" :nv "!" #'projectile-run-shell-command-in-root
|
||||
:desc "Switch project" :n "p" #'projectile-switch-project
|
||||
:desc "Recent project files" :n "r" #'projectile-recentf
|
||||
:desc "List project tasks" :n "t" #'+ivy/tasks
|
||||
:desc "Pop term in project" :n "o" #'+term/open-popup-in-project
|
||||
:desc "Invalidate cache" :n "x" #'projectile-invalidate-cache)
|
||||
|
||||
(:desc "quit" :prefix "q"
|
||||
:desc "Quit" :n "q" #'evil-save-and-quit
|
||||
:desc "Quit (forget session)" :n "Q" #'+workspace/kill-session-and-quit)
|
||||
|
||||
(:desc "remote" :prefix "r"
|
||||
:desc "Upload local" :n "u" #'+upload/local
|
||||
:desc "Upload local (force)" :n "U" (λ! (+upload/local t))
|
||||
:desc "Download remote" :n "d" #'+upload/remote-download
|
||||
:desc "Diff local & remote" :n "D" #'+upload/diff
|
||||
:desc "Browse remote files" :n "." #'+upload/browse
|
||||
:desc "Detect remote changes" :n ">" #'+upload/check-remote)
|
||||
|
||||
(:desc "snippets" :prefix "s"
|
||||
:desc "New snippet" :n "n" #'yas-new-snippet
|
||||
:desc "Insert snippet" :nv "i" #'yas-insert-snippet
|
||||
:desc "Find snippet for mode" :n "s" #'yas-visit-snippet-file
|
||||
:desc "Find snippet" :n "S" #'+default/find-in-snippets)
|
||||
|
||||
(:desc "toggle" :prefix "t"
|
||||
:desc "Flyspell" :n "s" #'flyspell-mode
|
||||
:desc "Flycheck" :n "f" #'flycheck-mode
|
||||
:desc "Line numbers" :n "l" #'doom/toggle-line-numbers
|
||||
:desc "Fullscreen" :n "f" #'doom/toggle-fullscreen
|
||||
:desc "Indent guides" :n "i" #'highlight-indentation-mode
|
||||
:desc "Indent guides (column)" :n "I" #'highlight-indentation-current-column-mode
|
||||
:desc "Impatient mode" :n "h" #'+impatient-mode/toggle
|
||||
:desc "Big mode" :n "b" #'doom-big-font-mode
|
||||
:desc "Evil goggles" :n "g" #'+evil-goggles/toggle))
|
||||
|
||||
|
||||
;; --- Personal vim-esque bindings ------------------
|
||||
:n "zx" #'doom/kill-this-buffer
|
||||
:n "ZX" #'bury-buffer
|
||||
:n "]b" #'doom/next-buffer
|
||||
:n "[b" #'doom/previous-buffer
|
||||
:n "]w" #'+workspace/switch-right
|
||||
:n "[w" #'+workspace/switch-left
|
||||
:m "gt" #'+workspace/switch-right
|
||||
:m "gT" #'+workspace/switch-left
|
||||
:m "gd" #'+jump/definition
|
||||
:m "gD" #'+jump/references
|
||||
:m "gh" #'+jump/documentation
|
||||
:n "gp" #'+evil/reselect-paste
|
||||
:n "gr" #'+eval:region
|
||||
:n "gR" #'+eval/buffer
|
||||
:v "gR" #'+eval:replace-region
|
||||
:v "@" #'+evil:macro-on-all-lines
|
||||
:n "g@" #'+evil:macro-on-all-lines
|
||||
;; repeat in visual mode (FIXME buggy)
|
||||
:v "." #'evil-repeat
|
||||
;; don't leave visual mode after shifting
|
||||
:v "<" #'+evil/visual-dedent ; vnoremap < <gv
|
||||
:v ">" #'+evil/visual-indent ; vnoremap > >gv
|
||||
;; paste from recent yank register (which isn't overwritten)
|
||||
:v "C-p" "\"0p"
|
||||
|
||||
(:map evil-window-map ; prefix "C-w"
|
||||
;; Navigation
|
||||
"C-h" #'evil-window-left
|
||||
"C-j" #'evil-window-down
|
||||
"C-k" #'evil-window-up
|
||||
"C-l" #'evil-window-right
|
||||
"C-w" #'ace-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
|
||||
;; Delete window
|
||||
"c" #'+workspace/close-window-or-workspace
|
||||
"C-C" #'ace-delete-window)
|
||||
|
||||
|
||||
;; --- Plugin bindings ------------------------------
|
||||
;; auto-yasnippet
|
||||
:i [C-tab] #'aya-expand
|
||||
:nv [C-tab] #'aya-create
|
||||
|
||||
;; company-mode (vim-like omnicompletion)
|
||||
:i "C-SPC" #'+company/complete
|
||||
(:prefix "C-x"
|
||||
:i "C-l" #'+company/whole-lines
|
||||
:i "C-k" #'+company/dict-or-keywords
|
||||
:i "C-f" #'company-files
|
||||
:i "C-]" #'company-etags
|
||||
:i "s" #'company-ispell
|
||||
:i "C-s" #'company-yasnippet
|
||||
:i "C-o" #'company-capf
|
||||
:i "C-n" #'company-dabbrev-code
|
||||
:i "C-p" #'+company/dabbrev-code-previous)
|
||||
(:after company
|
||||
(:map company-active-map
|
||||
;; Don't interfere with `evil-delete-backward-word' in insert mode
|
||||
"C-w" nil
|
||||
"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-s" #'company-search-candidates
|
||||
"C-s" #'company-filter-candidates
|
||||
"C-SPC" #'company-complete-common
|
||||
"C-h" #'company-quickhelp-manual-begin
|
||||
[tab] #'company-complete-common-or-cycle
|
||||
[backtab] #'company-select-previous
|
||||
[escape] (λ! (company-abort) (evil-normal-state 1)))
|
||||
;; Automatically applies to `company-filter-map'
|
||||
(:map company-search-map
|
||||
"C-n" #'company-search-repeat-forward
|
||||
"C-p" #'company-search-repeat-backward
|
||||
"C-s" (λ! (company-search-abort) (company-filter-candidates))
|
||||
[escape] #'company-search-abort))
|
||||
|
||||
;; counsel
|
||||
(: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)))
|
||||
|
||||
;; evil-commentary
|
||||
:n "gc" #'evil-commentary
|
||||
|
||||
;; evil-exchange
|
||||
:n "gx" #'evil-exchange
|
||||
|
||||
;; evil-matchit
|
||||
:nv [tab] #'+evil/matchit-or-toggle-fold
|
||||
|
||||
;; evil-magit
|
||||
(:after evil-magit
|
||||
:map (magit-status-mode-map magit-revision-mode-map)
|
||||
:n "C-j" nil
|
||||
:n "C-k" nil)
|
||||
|
||||
;; evil-mc
|
||||
(:prefix "gz"
|
||||
:nv "m" #'evil-mc-make-all-cursors
|
||||
:nv "u" #'evil-mc-undo-all-cursors
|
||||
:nv "z" #'+evil/mc-make-cursor-here
|
||||
:nv "t" #'+evil/mc-toggle-cursors
|
||||
:nv "n" #'evil-mc-make-and-goto-next-cursor
|
||||
:nv "p" #'evil-mc-make-and-goto-prev-cursor
|
||||
:nv "N" #'evil-mc-make-and-goto-last-cursor
|
||||
:nv "P" #'evil-mc-make-and-goto-first-cursor
|
||||
:nv "d" #'evil-mc-make-and-goto-next-match
|
||||
:nv "D" #'evil-mc-make-and-goto-prev-match)
|
||||
(:after evil-mc
|
||||
:map evil-mc-key-map
|
||||
:nv "C-n" #'evil-mc-make-and-goto-next-cursor
|
||||
:nv "C-N" #'evil-mc-make-and-goto-last-cursor
|
||||
:nv "C-p" #'evil-mc-make-and-goto-prev-cursor
|
||||
:nv "C-P" #'evil-mc-make-and-goto-first-cursor)
|
||||
|
||||
;; evil-multiedit
|
||||
:v "R" #'evil-multiedit-match-all
|
||||
:n "M-d" #'evil-multiedit-match-symbol-and-next
|
||||
:n "M-D" #'evil-multiedit-match-symbol-and-prev
|
||||
:v "M-d" #'evil-multiedit-match-and-next
|
||||
:v "M-D" #'evil-multiedit-match-and-prev
|
||||
: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)
|
||||
(:map (evil-multiedit-state-map evil-multiedit-insert-state-map)
|
||||
"C-n" #'evil-multiedit-next
|
||||
"C-p" #'evil-multiedit-prev))
|
||||
|
||||
;; evil-snipe
|
||||
(:after evil-snipe
|
||||
(:after evil-easymotion
|
||||
;; Binding to switch to evil-easymotion/avy after a 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
|
||||
|
||||
;; expand-region
|
||||
:v "v" #'er/expand-region
|
||||
:v "V" #'er/contract-region
|
||||
|
||||
;; flycheck
|
||||
:m "]e" #'next-error
|
||||
: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)
|
||||
|
||||
;; flyspell
|
||||
:m "]S" #'flyspell-correct-word-generic
|
||||
:m "[S" #'flyspell-correct-previous-word-generic
|
||||
|
||||
;; git-gutter
|
||||
:m "]d" #'git-gutter:next-hunk
|
||||
:m "[d" #'git-gutter:previous-hunk
|
||||
|
||||
;; git-timemachine
|
||||
(:after git-timemachine
|
||||
(:map git-timemachine-mode-map
|
||||
:n "C-p" #'git-timemachine-show-previous-revision
|
||||
:n "C-n" #'git-timemachine-show-next-revision
|
||||
:n "[[" #'git-timemachine-show-previous-revision
|
||||
:n "]]" #'git-timemachine-show-next-revision
|
||||
:n "q" #'git-timemachine-quit
|
||||
:n "gb" #'git-timemachine-blame))
|
||||
|
||||
;; gist
|
||||
(:after gist
|
||||
:map gist-list-menu-mode-map
|
||||
:n "RET" #'+gist/open-current
|
||||
:n "b" #'gist-browse-current-url
|
||||
:n "c" #'gist-add-buffer
|
||||
:n "d" #'gist-kill-current
|
||||
:n "f" #'gist-fork
|
||||
:n "q" #'quit-window
|
||||
:n "r" #'gist-list-reload
|
||||
:n "s" #'gist-star
|
||||
:n "S" #'gist-unstar
|
||||
:n "y" #'gist-print-current-url)
|
||||
|
||||
;; helm
|
||||
(:after helm
|
||||
(:map helm-map
|
||||
"ESC" nil
|
||||
"C-S-n" #'helm-next-source
|
||||
"C-S-p" #'helm-previous-source
|
||||
"C-u" #'helm-delete-minibuffer-contents
|
||||
"C-w" #'backward-kill-word
|
||||
"C-r" #'evil-paste-from-register ; Evil registers in helm! Glorious!
|
||||
"C-b" #'backward-word
|
||||
[left] #'backward-char
|
||||
[right] #'forward-char
|
||||
[escape] #'helm-keyboard-quit
|
||||
[tab] #'helm-execute-persistent-action)
|
||||
|
||||
(:after helm-files
|
||||
(:map helm-generic-files-map
|
||||
:e "ESC" #'helm-keyboard-quit)
|
||||
(:map helm-find-files-map
|
||||
"C-w" #'helm-find-files-up-one-level
|
||||
"TAB" #'helm-execute-persistent-action))
|
||||
|
||||
(:after helm-ag
|
||||
(:map helm-ag-map
|
||||
"<backtab>" #'helm-ag-edit)))
|
||||
|
||||
;; hl-todo
|
||||
:m "]t" #'hl-todo-next
|
||||
:m "[t" #'hl-todo-previous
|
||||
|
||||
;; ivy
|
||||
(:after ivy
|
||||
:map ivy-minibuffer-map
|
||||
[escape] #'keyboard-escape-quit
|
||||
"C-SPC" #'ivy-call-and-recenter
|
||||
"M-v" #'yank
|
||||
"M-z" #'undo
|
||||
"C-r" #'evil-paste-from-register
|
||||
"C-k" #'ivy-previous-line
|
||||
"C-j" #'ivy-next-line
|
||||
"C-l" #'ivy-alt-done
|
||||
"C-w" #'ivy-backward-kill-word
|
||||
"C-u" #'ivy-kill-line
|
||||
"C-b" #'backward-word
|
||||
"C-f" #'forward-word)
|
||||
|
||||
;; neotree
|
||||
(:after neotree
|
||||
:map neotree-mode-map
|
||||
:n "g" nil
|
||||
:n [tab] #'neotree-quick-look
|
||||
:n "RET" #'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)
|
||||
|
||||
;; realgud
|
||||
(:after realgud
|
||||
:map realgud:shortkey-mode-map
|
||||
:n "j" #'evil-next-line
|
||||
:n "k" #'evil-previous-line
|
||||
:n "h" #'evil-backward-char
|
||||
:n "l" #'evil-forward-char
|
||||
:m "n" #'realgud:cmd-next
|
||||
:m "b" #'realgud:cmd-break
|
||||
:m "B" #'realgud:cmd-clear
|
||||
:n "c" #'realgud:cmd-continue)
|
||||
|
||||
;; rotate-text
|
||||
:n "!" #'rotate-text
|
||||
|
||||
;; smart-forward
|
||||
:nv "K" #'smart-up
|
||||
:m "g]" #'smart-forward
|
||||
:m "g[" #'smart-backward
|
||||
|
||||
;; undo-tree -- undo/redo for visual regions
|
||||
:v "C-u" #'undo-tree-undo
|
||||
:v "C-r" #'undo-tree-redo
|
||||
|
||||
;; yasnippet
|
||||
(:after yasnippet
|
||||
(:map yas-keymap
|
||||
"C-e" #'+snippets/goto-end-of-field
|
||||
"C-a" #'+snippets/goto-start-of-field
|
||||
"<M-right>" #'+snippets/goto-end-of-field
|
||||
"<M-left>" #'+snippets/goto-start-of-field
|
||||
"<M-backspace>" #'+snippets/delete-to-start-of-field
|
||||
[escape] #'evil-normal-state
|
||||
[backspace] #'+snippets/delete-backward-char
|
||||
[delete] #'+snippets/delete-forward-char-or-field)
|
||||
(:map yas-minor-mode-map
|
||||
:i "<tab>" yas-maybe-expand
|
||||
:v "<tab>" #'+snippets/expand-on-region))
|
||||
|
||||
|
||||
;; --- Major mode bindings --------------------------
|
||||
(:after markdown-mode
|
||||
(:map markdown-mode-map
|
||||
;; fix conflicts with private bindings
|
||||
"<backspace>" nil
|
||||
"<M-left>" nil
|
||||
"<M-right>" nil))
|
||||
|
||||
|
||||
;; --- Custom evil text-objects ---------------------
|
||||
: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 "I" #'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
|
||||
|
||||
|
||||
;; --- Built-in plugins -----------------------------
|
||||
(:after comint
|
||||
;; TAB auto-completion in term buffers
|
||||
:map comint-mode-map [tab] #'company-complete)
|
||||
|
||||
(:after debug
|
||||
;; For elisp debugging
|
||||
:map debugger-mode-map
|
||||
:n "RET" #'debug-help-follow
|
||||
:n "e" #'debugger-eval-expression
|
||||
:n "n" #'debugger-step-through
|
||||
:n "c" #'debugger-continue)
|
||||
|
||||
(:map help-mode-map
|
||||
:n "[[" #'help-go-back
|
||||
:n "]]" #'help-go-forward
|
||||
:n "o" #'ace-link-help
|
||||
:n "q" #'quit-window
|
||||
:n "Q" #'+ivy-quit-and-resume)
|
||||
|
||||
(:after vc-annotate
|
||||
:map vc-annotate-mode-map
|
||||
:n "q" #'kill-this-buffer
|
||||
:n "d" #'vc-annotate-show-diff-revision-at-line
|
||||
:n "D" #'vc-annotate-show-changeset-diff-revision-at-line
|
||||
:n "SPC" #'vc-annotate-show-log-revision-at-line
|
||||
:n "]]" #'vc-annotate-next-revision
|
||||
:n "[[" #'vc-annotate-prev-revision
|
||||
:n "TAB" #'vc-annotate-toggle-annotation-visibility
|
||||
:n "RET" #'vc-annotate-find-revision-at-line))
|
||||
|
||||
|
||||
;;
|
||||
;; Keybinding fixes
|
||||
;;
|
||||
|
||||
;; This section is dedicated to "fixing" certain keys so that they behave
|
||||
;; properly, more like vim, or how I like it.
|
||||
|
||||
(map! (:map input-decode-map
|
||||
[S-iso-lefttab] [backtab]
|
||||
(:unless window-system "TAB" [tab])) ; Fix TAB in terminal
|
||||
|
||||
;; I want C-a and C-e to be a little smarter. 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 and trailing whitespace before
|
||||
;; jumping to eol.
|
||||
:i "C-a" #'doom/backward-to-bol-or-indent
|
||||
:i "C-e" #'doom/forward-to-last-non-comment-or-eol
|
||||
:i "C-u" #'doom/backward-kill-to-bol-and-indent
|
||||
|
||||
;; textmate-esque newline insertion
|
||||
:i [M-return] #'evil-open-below
|
||||
:i [S-M-return] #'evil-open-above
|
||||
;; textmate-esque deletion
|
||||
[M-backspace] #'doom/backward-kill-to-bol-and-indent
|
||||
:i [backspace] #'delete-backward-char
|
||||
:i [M-backspace] #'doom/backward-kill-to-bol-and-indent
|
||||
;; Emacsien motions for insert mode
|
||||
:i "C-b" #'backward-word
|
||||
:i "C-f" #'forward-word
|
||||
|
||||
;; Highjacks space/backspace to:
|
||||
;; a) balance spaces inside brackets/parentheses ( | ) -> (|)
|
||||
;; b) delete space-indented blocks intelligently
|
||||
;; c) do none of this when inside a string
|
||||
:i "SPC" #'doom/inflate-space-maybe
|
||||
:i [remap delete-backward-char] #'doom/deflate-space-maybe
|
||||
:i [remap newline] #'doom/newline-and-indent
|
||||
|
||||
(:after org
|
||||
(:map org-mode-map
|
||||
:i [remap doom/inflate-space-maybe] #'org-self-insert-command
|
||||
:i "C-e" #'org-end-of-line
|
||||
:i "C-a" #'org-beginning-of-line))
|
||||
|
||||
;; Restore common editing keys (and ESC) in minibuffer
|
||||
(:map (minibuffer-local-map
|
||||
minibuffer-local-ns-map
|
||||
minibuffer-local-completion-map
|
||||
minibuffer-local-must-match-map
|
||||
minibuffer-local-isearch-map
|
||||
evil-ex-completion-map
|
||||
evil-ex-search-keymap
|
||||
read-expression-map)
|
||||
[escape] #'abort-recursive-edit
|
||||
"C-r" #'evil-paste-from-register
|
||||
"C-a" #'move-beginning-of-line
|
||||
"C-w" #'doom/minibuffer-kill-word
|
||||
"C-u" #'doom/minibuffer-kill-line
|
||||
"C-b" #'backward-word
|
||||
"C-f" #'forward-word
|
||||
"M-z" #'doom/minibuffer-undo)
|
||||
|
||||
(:map messages-buffer-mode-map
|
||||
"M-;" #'eval-expression
|
||||
"A-;" #'eval-expression)
|
||||
|
||||
(:map tabulated-list-mode-map
|
||||
[remap evil-record-macro] #'doom/popup-close-maybe)
|
||||
|
||||
(:after view
|
||||
(:map view-mode-map "<escape>" #'View-quit-all)))
|
|
@ -1,12 +1,12 @@
|
|||
;;; private/hlissner/+commands.el -*- lexical-binding: t; -*-
|
||||
;;; private/default/+evil-commands.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defalias 'ex! 'evil-ex-define-cmd)
|
||||
|
||||
;;; Commands defined elsewhere
|
||||
;;; Commands defined elsewhere
|
||||
;;(ex! "al[ign]" #'+evil:align)
|
||||
;;(ex! "g[lobal]" #'+evil:global)
|
||||
|
||||
;;; Custom commands
|
||||
;;; Custom commands
|
||||
;; Editing
|
||||
(ex! "@" #'+evil:macro-on-all-lines) ; TODO Test me
|
||||
(ex! "al[ign]" #'+evil:align)
|
||||
|
@ -16,7 +16,6 @@
|
|||
(ex! "iedit" #'evil-multiedit-ex-match)
|
||||
(ex! "na[rrow]" #'+evil:narrow-buffer)
|
||||
(ex! "retab" #'+evil:retab)
|
||||
|
||||
;; External resources
|
||||
;; TODO (ex! "db" #'doom:db)
|
||||
;; TODO (ex! "dbu[se]" #'doom:db-select)
|
||||
|
@ -29,7 +28,6 @@
|
|||
(ex! "t[mux]" #'+tmux:run) ; send to tmux
|
||||
(ex! "tcd" #'+tmux:cd-here) ; cd to default-directory in tmux
|
||||
(ex! "x" #'doom/open-project-scratch-buffer)
|
||||
|
||||
;; GIT
|
||||
(ex! "gist" #'+gist:send) ; send current buffer/region to gist
|
||||
(ex! "gistl" #'+gist:list) ; list gists by user
|
||||
|
@ -40,20 +38,18 @@
|
|||
(ex! "gunstage" #'magit-unstage)
|
||||
(ex! "gblame" #'magit-blame)
|
||||
(ex! "grevert" #'git-gutter:revert-hunk)
|
||||
|
||||
;; Dealing with buffers
|
||||
(ex! "clean[up]" #'doom/cleanup-buffers)
|
||||
(ex! "clean[up]" #'doom/cleanup-session)
|
||||
(ex! "k[ill]" #'doom/kill-this-buffer)
|
||||
(ex! "k[ill]all" #'+hlissner:kill-all-buffers)
|
||||
(ex! "k[ill]m" #'+hlissner:kill-matching-buffers)
|
||||
(ex! "k[ill]all" #'+default:kill-all-buffers)
|
||||
(ex! "k[ill]m" #'+default:kill-matching-buffers)
|
||||
(ex! "k[ill]o" #'doom/kill-other-buffers)
|
||||
(ex! "l[ast]" #'doom/popup-restore)
|
||||
(ex! "m[sg]" #'view-echo-area-messages)
|
||||
(ex! "pop[up]" #'doom/popup-this-buffer)
|
||||
|
||||
;; Project navigation
|
||||
(ex! "a" #'projectile-find-other-file)
|
||||
(ex! "cd" #'+hlissner:cd)
|
||||
(ex! "cd" #'+default:cd)
|
||||
(cond ((featurep! :completion ivy)
|
||||
(ex! "ag" #'+ivy:ag)
|
||||
(ex! "agc[wd]" #'+ivy:ag-cwd)
|
||||
|
@ -68,17 +64,14 @@
|
|||
(ex! "rgc[wd]" #'+helm:rg-cwd)
|
||||
(ex! "sw[oop]" #'+helm:swoop)
|
||||
(ex! "todo" #'+helm:todo)))
|
||||
|
||||
;; Project tools
|
||||
(ex! "build" #'+eval/build)
|
||||
(ex! "debug" #'+debug/run)
|
||||
(ex! "er[rors]" #'flycheck-list-errors)
|
||||
|
||||
;; File operations
|
||||
(ex! "cp" #'+evil:copy-this-file)
|
||||
(ex! "mv" #'+evil:move-this-file)
|
||||
(ex! "rm" #'+evil:delete-this-file)
|
||||
|
||||
;; Sessions/tabs
|
||||
(ex! "sclear" #'+workspace/kill-session)
|
||||
(ex! "sl[oad]" #'+workspace:load-session)
|
||||
|
@ -93,6 +86,6 @@
|
|||
(ex! "tabr[ename]" #'+workspace:rename)
|
||||
(ex! "tabs" #'+workspace/display)
|
||||
(ex! "tabsave" #'+workspace:save)
|
||||
|
||||
;; Org-mode
|
||||
(ex! "cap" #'+org-capture/dwim)
|
||||
|
47
modules/private/default/autoload/default.el
Normal file
47
modules/private/default/autoload/default.el
Normal file
|
@ -0,0 +1,47 @@
|
|||
;; private/default/autoload/default.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun +default/yank-buffer-filename ()
|
||||
"Copy the current buffer's path to the kill ring."
|
||||
(interactive)
|
||||
(if-let* ((filename (or buffer-file-name (bound-and-true-p list-buffers-directory))))
|
||||
(message (kill-new (abbreviate-file-name filename)))
|
||||
(error "Couldn't find filename in current buffer")))
|
||||
|
||||
;;;###autoload
|
||||
(defmacro +default--def-browse-in! (name dir)
|
||||
(let ((prefix (cdr (doom-module-from-path (or load-file-name byte-compile-current-file)))))
|
||||
`(defun ,(intern (format "%s/browse-%s" prefix name)) ()
|
||||
(interactive)
|
||||
(doom-project-browse ,dir))))
|
||||
|
||||
;;;###autoload
|
||||
(defmacro +default--def-find-in! (name dir)
|
||||
(let ((prefix (cdr (doom-module-from-path (or load-file-name byte-compile-current-file)))))
|
||||
`(defun ,(intern (format "+%s/find-in-%s" prefix name)) ()
|
||||
(interactive)
|
||||
(doom-project-find-file ,dir))))
|
||||
|
||||
|
||||
;;;###autoload (autoload '+default/browse-project "private/default/autoload/default" nil t)
|
||||
(+default--def-browse-in! project (doom-project-root))
|
||||
|
||||
;;;###autoload (autoload '+default/find-in-templates "private/default/autoload/default" nil t)
|
||||
(+default--def-find-in! templates +file-templates-dir)
|
||||
;;;###autoload (autoload '+default/browse-templates "private/default/autoload/default" nil t)
|
||||
(+default--def-browse-in! templates +file-templates-dir)
|
||||
|
||||
;;;###autoload (autoload '+default/find-in-emacsd "private/default/autoload/default" nil t)
|
||||
(+default--def-find-in! emacsd doom-emacs-dir)
|
||||
;;;###autoload (autoload '+default/browse-emacsd "private/default/autoload/default" nil t)
|
||||
(+default--def-browse-in! emacsd doom-emacs-dir)
|
||||
|
||||
;;;###autoload (autoload '+default/find-in-notes "private/default/autoload/default" nil t)
|
||||
(+default--def-find-in! notes +org-dir)
|
||||
;;;###autoload (autoload '+default/browse-notes "private/default/autoload/default" nil t)
|
||||
(+default--def-browse-in! notes +org-dir)
|
||||
|
||||
;;;###autoload (autoload '+default/find-in-snippets "private/default/autoload/default" nil t)
|
||||
(+default--def-find-in! snippets +default-snippets-dir)
|
||||
;; NOTE No need for a browse-snippets variant, use `yas-visit-snippet-file'
|
||||
|
38
modules/private/default/autoload/evil.el
Normal file
38
modules/private/default/autoload/evil.el
Normal file
|
@ -0,0 +1,38 @@
|
|||
;; private/default/autoload/evil.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! :feature evil)
|
||||
|
||||
;;;###autoload (autoload '+default:multi-next-line "private/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))))
|
||||
(evil-line-move (* 6 (or count 1)))))
|
||||
|
||||
;;;###autoload (autoload '+default:multi-previous-line "private/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))))
|
||||
(evil-line-move (- (* 6 (or count 1))))))
|
||||
|
||||
;;;###autoload (autoload '+default:cd "private/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 "private/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 "private/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))
|
||||
|
80
modules/private/default/config.el
Normal file
80
modules/private/default/config.el
Normal file
|
@ -0,0 +1,80 @@
|
|||
;;; private/default/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(load! +bindings)
|
||||
|
||||
|
||||
;;
|
||||
;; Plugins
|
||||
;;
|
||||
|
||||
(def-package! emacs-snippets :after yasnippet)
|
||||
|
||||
|
||||
;;
|
||||
;; Config
|
||||
;;
|
||||
|
||||
(after! epa
|
||||
(setq epa-file-encrypt-to (or epa-file-encrypt-to user-mail-address)
|
||||
;; With GPG 2.1, this forces gpg-agent to use the Emacs minibuffer to
|
||||
;; prompt for the key passphrase.
|
||||
epa-pinentry-mode 'loopback))
|
||||
|
||||
|
||||
(when (featurep 'evil)
|
||||
(load! +evil-commands)
|
||||
|
||||
;; Makes ; and , the universal repeat-keys in evil-mode
|
||||
(defmacro do-repeat! (command next-func prev-func)
|
||||
"Repeat motions with ;/,"
|
||||
(let ((fn-sym (intern (format "+evil*repeat-%s" command))))
|
||||
`(progn
|
||||
(defun ,fn-sym (&rest _)
|
||||
(define-key evil-motion-state-map (kbd ";") ',next-func)
|
||||
(define-key evil-motion-state-map (kbd ",") ',prev-func))
|
||||
(advice-add #',command :before #',fn-sym))))
|
||||
|
||||
;; n/N
|
||||
(do-repeat! evil-ex-search-next evil-ex-search-next evil-ex-search-previous)
|
||||
(do-repeat! evil-ex-search-previous evil-ex-search-next evil-ex-search-previous)
|
||||
(do-repeat! evil-ex-search-forward evil-ex-search-next evil-ex-search-previous)
|
||||
(do-repeat! evil-ex-search-backward evil-ex-search-next evil-ex-search-previous)
|
||||
|
||||
;; f/F/t/T/s/S
|
||||
(after! evil-snipe
|
||||
(setq evil-snipe-repeat-keys nil
|
||||
evil-snipe-override-evil-repeat-keys nil) ; causes problems with remapped ;
|
||||
|
||||
(do-repeat! evil-snipe-f evil-snipe-repeat evil-snipe-repeat-reverse)
|
||||
(do-repeat! evil-snipe-F evil-snipe-repeat evil-snipe-repeat-reverse)
|
||||
(do-repeat! evil-snipe-t evil-snipe-repeat evil-snipe-repeat-reverse)
|
||||
(do-repeat! evil-snipe-T evil-snipe-repeat evil-snipe-repeat-reverse)
|
||||
(do-repeat! evil-snipe-s evil-snipe-repeat evil-snipe-repeat-reverse)
|
||||
(do-repeat! evil-snipe-S evil-snipe-repeat evil-snipe-repeat-reverse)
|
||||
(do-repeat! evil-snipe-x evil-snipe-repeat evil-snipe-repeat-reverse)
|
||||
(do-repeat! evil-snipe-X evil-snipe-repeat evil-snipe-repeat-reverse))
|
||||
|
||||
;; */#
|
||||
(after! evil-visualstar
|
||||
(do-repeat! evil-visualstar/begin-search-forward
|
||||
evil-ex-search-next evil-ex-search-previous)
|
||||
(do-repeat! evil-visualstar/begin-search-backward
|
||||
evil-ex-search-previous evil-ex-search-next))
|
||||
|
||||
(after! evil-easymotion
|
||||
(let ((prefix (concat doom-leader-key " /")))
|
||||
;; NOTE `evilem-default-keybinds' unsets all other keys on the prefix (in
|
||||
;; motion state)
|
||||
(evilem-default-keybindings prefix)
|
||||
(evilem-define (kbd (concat prefix " n")) #'evil-ex-search-next)
|
||||
(evilem-define (kbd (concat prefix " N")) #'evil-ex-search-previous)
|
||||
(evilem-define (kbd (concat prefix " s")) #'evil-snipe-repeat
|
||||
:pre-hook (save-excursion (call-interactively #'evil-snipe-s))
|
||||
:bind ((evil-snipe-scope 'buffer)
|
||||
(evil-snipe-enable-highlight)
|
||||
(evil-snipe-enable-incremental-highlight)))
|
||||
(evilem-define (kbd (concat prefix " S")) #'evil-snipe-repeat-reverse
|
||||
:pre-hook (save-excursion (call-interactively #'evil-snipe-s))
|
||||
:bind ((evil-snipe-scope 'buffer)
|
||||
(evil-snipe-enable-highlight)
|
||||
(evil-snipe-enable-incremental-highlight))))))
|
7
modules/private/default/packages.el
Normal file
7
modules/private/default/packages.el
Normal file
|
@ -0,0 +1,7 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; private/default/packages.el
|
||||
|
||||
(package! emacs-snippets
|
||||
:recipe (:fetcher github
|
||||
:repo "hlissner/emacs-snippets"
|
||||
:files ("*")))
|
|
@ -1,795 +0,0 @@
|
|||
;;; private/hlissner/+bindings.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defmacro find-file-in! (path &optional project-p)
|
||||
"Returns an interactive function for searching files."
|
||||
`(lambda () (interactive)
|
||||
(let ((default-directory ,path))
|
||||
(call-interactively
|
||||
',(command-remapping
|
||||
(if project-p
|
||||
#'projectile-find-file
|
||||
#'find-file))))))
|
||||
|
||||
(map!
|
||||
[remap evil-jump-to-tag] #'projectile-find-tag
|
||||
[remap find-tag] #'projectile-find-tag
|
||||
;; ensure there are no conflicts
|
||||
:nmvo doom-leader-key nil
|
||||
:nmvo doom-localleader-key nil)
|
||||
|
||||
(map!
|
||||
;; --- Global keybindings ---------------------------
|
||||
;; Make M-x available everywhere
|
||||
:gnvime "M-x" #'execute-extended-command
|
||||
:gnvime "A-x" #'execute-extended-command
|
||||
;; Emacs debug utilities
|
||||
:gnvime "M-;" #'eval-expression
|
||||
:gnvime "M-:" #'doom/open-scratch-buffer
|
||||
;; Text-scaling
|
||||
"M-+" (λ! (text-scale-set 0))
|
||||
"M-=" #'text-scale-increase
|
||||
"M--" #'text-scale-decrease
|
||||
;; Simple window navigation/manipulation
|
||||
"C-`" #'doom/popup-toggle
|
||||
"C-~" #'doom/popup-raise
|
||||
"M-t" #'+workspace/new
|
||||
"M-T" #'+workspace/display
|
||||
"M-w" #'delete-window
|
||||
"M-W" #'+workspace/close-workspace-or-frame
|
||||
"M-n" #'evil-buffer-new
|
||||
"M-N" #'make-frame
|
||||
"M-1" (λ! (+workspace/switch-to 0))
|
||||
"M-2" (λ! (+workspace/switch-to 1))
|
||||
"M-3" (λ! (+workspace/switch-to 2))
|
||||
"M-4" (λ! (+workspace/switch-to 3))
|
||||
"M-5" (λ! (+workspace/switch-to 4))
|
||||
"M-6" (λ! (+workspace/switch-to 5))
|
||||
"M-7" (λ! (+workspace/switch-to 6))
|
||||
"M-8" (λ! (+workspace/switch-to 7))
|
||||
"M-9" (λ! (+workspace/switch-to 8))
|
||||
"M-0" #'+workspace/switch-to-last
|
||||
;; Other sensible, textmate-esque global bindings
|
||||
:ne "M-r" #'+eval/buffer
|
||||
:ne "M-R" #'+eval/region-and-replace
|
||||
:ne "M-b" #'+eval/build
|
||||
:ne "M-a" #'mark-whole-buffer
|
||||
:ne "M-c" #'evil-yank
|
||||
:ne "M-q" (if (daemonp) #'delete-frame #'save-buffers-kill-emacs)
|
||||
:ne "M-f" #'swiper
|
||||
:ne "C-M-f" #'doom/toggle-fullscreen
|
||||
:n "M-s" #'save-buffer
|
||||
:m "A-j" #'+hlissner:multi-next-line
|
||||
:m "A-k" #'+hlissner:multi-previous-line
|
||||
:nv "C-SPC" #'+evil:fold-toggle
|
||||
:gnvimer "M-v" #'clipboard-yank
|
||||
;; Easier window navigation
|
||||
:en "C-h" #'evil-window-left
|
||||
:en "C-j" #'evil-window-down
|
||||
:en "C-k" #'evil-window-up
|
||||
:en "C-l" #'evil-window-right
|
||||
|
||||
"C-x p" #'doom/other-popup
|
||||
|
||||
|
||||
;; --- <leader> -------------------------------------
|
||||
(:leader
|
||||
:desc "Ex command" :nv ";" #'evil-ex
|
||||
:desc "M-x" :nv ":" #'execute-extended-command
|
||||
:desc "Pop up scratch buffer" :nv "x" #'doom/open-scratch-buffer
|
||||
:desc "Org Capture" :nv "X" #'+org-capture/open
|
||||
|
||||
;; Most commonly used
|
||||
:desc "Find file in project" :n "SPC" #'projectile-find-file
|
||||
:desc "Switch workspace buffer" :n "," #'persp-switch-to-buffer
|
||||
:desc "Switch buffer" :n "<" #'switch-to-buffer
|
||||
:desc "Browse files" :n "." #'find-file
|
||||
:desc "Toggle last popup" :n "~" #'doom/popup-toggle
|
||||
:desc "Eval expression" :n "`" #'eval-expression
|
||||
:desc "Blink cursor line" :n "DEL" #'+doom/blink-cursor
|
||||
:desc "Jump to bookmark" :n "RET" #'bookmark-jump
|
||||
|
||||
;; C-u is used by evil
|
||||
:desc "Universal argument" :n "u" #'universal-argument
|
||||
:desc "window" :n "w" evil-window-map
|
||||
|
||||
(:desc "previous..." :prefix "["
|
||||
:desc "Text size" :nv "[" #'text-scale-decrease
|
||||
:desc "Buffer" :nv "b" #'doom/previous-buffer
|
||||
:desc "Diff Hunk" :nv "d" #'git-gutter:previous-hunk
|
||||
:desc "Todo" :nv "t" #'hl-todo-previous
|
||||
:desc "Error" :nv "e" #'previous-error
|
||||
:desc "Workspace" :nv "w" #'+workspace/switch-left
|
||||
:desc "Smart jump" :nv "h" #'smart-backward
|
||||
:desc "Spelling error" :nv "s" #'evil-prev-flyspell-error
|
||||
:desc "Spelling correction" :n "S" #'flyspell-correct-previous-word-generic)
|
||||
|
||||
(:desc "next..." :prefix "]"
|
||||
:desc "Text size" :nv "]" #'text-scale-increase
|
||||
:desc "Buffer" :nv "b" #'doom/next-buffer
|
||||
:desc "Diff Hunk" :nv "d" #'git-gutter:next-hunk
|
||||
:desc "Todo" :nv "t" #'hl-todo-next
|
||||
:desc "Error" :nv "e" #'next-error
|
||||
:desc "Workspace" :nv "w" #'+workspace/switch-right
|
||||
:desc "Smart jump" :nv "l" #'smart-forward
|
||||
:desc "Spelling error" :nv "s" #'evil-next-flyspell-error
|
||||
:desc "Spelling correction" :n "S" #'flyspell-correct-word-generic)
|
||||
|
||||
(:desc "search" :prefix "/"
|
||||
:desc "Swiper" :nv "/" #'swiper
|
||||
:desc "Imenu" :nv "i" #'imenu
|
||||
:desc "Imenu across buffers" :nv "I" #'imenu-anywhere
|
||||
:desc "Online providers" :nv "o" #'+jump/online-select)
|
||||
|
||||
(:desc "workspace" :prefix "TAB"
|
||||
:desc "Display tab bar" :n "TAB" #'+workspace/display
|
||||
:desc "New workspace" :n "n" #'+workspace/new
|
||||
:desc "Load workspace from file" :n "l" #'+workspace/load
|
||||
:desc "Load last session" :n "L" (λ! (+workspace/load-session))
|
||||
:desc "Save workspace to file" :n "s" #'+workspace/save
|
||||
:desc "Autosave current session" :n "S" #'+workspace/save-session
|
||||
:desc "Switch workspace" :n "." #'+workspace/switch-to
|
||||
:desc "Kill all buffers" :n "x" #'doom/kill-all-buffers
|
||||
:desc "Delete session" :n "X" #'+workspace/kill-session
|
||||
:desc "Delete this workspace" :n "d" #'+workspace/delete
|
||||
:desc "Load session" :n "L" #'+workspace/load-session
|
||||
:desc "Next workspace" :n "]" #'+workspace/switch-right
|
||||
:desc "Previous workspace" :n "[" #'+workspace/switch-left
|
||||
:desc "Switch to 1st workspace" :n "1" (λ! (+workspace/switch-to 0))
|
||||
:desc "Switch to 2nd workspace" :n "2" (λ! (+workspace/switch-to 1))
|
||||
:desc "Switch to 3rd workspace" :n "3" (λ! (+workspace/switch-to 2))
|
||||
:desc "Switch to 4th workspace" :n "4" (λ! (+workspace/switch-to 3))
|
||||
:desc "Switch to 5th workspace" :n "5" (λ! (+workspace/switch-to 4))
|
||||
:desc "Switch to 6th workspace" :n "6" (λ! (+workspace/switch-to 5))
|
||||
:desc "Switch to 7th workspace" :n "7" (λ! (+workspace/switch-to 6))
|
||||
:desc "Switch to 8th workspace" :n "8" (λ! (+workspace/switch-to 7))
|
||||
:desc "Switch to 9th workspace" :n "9" (λ! (+workspace/switch-to 8))
|
||||
:desc "Switch to last workspace" :n "0" #'+workspace/switch-to-last)
|
||||
|
||||
(:desc "buffer" :prefix "b"
|
||||
:desc "New empty buffer" :n "n" #'evil-buffer-new
|
||||
:desc "Switch workspace buffer" :n "b" #'persp-switch-to-buffer
|
||||
:desc "Switch buffer" :n "B" #'switch-to-buffer
|
||||
:desc "Kill buffer" :n "k" #'doom/kill-this-buffer
|
||||
:desc "Kill other buffers" :n "o" #'doom/kill-other-buffers
|
||||
:desc "Save buffer" :n "s" #'save-buffer
|
||||
:desc "Pop scratch buffer" :n "x" #'doom/open-scratch-buffer
|
||||
:desc "Bury buffer" :n "z" #'bury-buffer
|
||||
:desc "Next buffer" :n "]" #'doom/next-buffer
|
||||
:desc "Previous buffer" :n "[" #'doom/previous-buffer
|
||||
:desc "Sudo edit this file" :n "S" #'doom/sudo-this-file)
|
||||
|
||||
(:desc "code" :prefix "c"
|
||||
:desc "List errors" :n "x" #'flycheck-list-errors
|
||||
:desc "Evaluate buffer/region" :n "e" #'+eval/buffer
|
||||
:v "e" #'+eval/region
|
||||
:desc "Evaluate & replace region" :nv "E" #'+eval:replace-region
|
||||
:desc "Build tasks" :nv "b" #'+eval/build
|
||||
:desc "Jump to definition" :n "d" #'+jump/definition
|
||||
:desc "Jump to references" :n "D" #'+jump/references
|
||||
:desc "Open REPL" :n "r" #'+eval/open-repl
|
||||
:v "r" #'+eval:repl)
|
||||
|
||||
(:desc "file" :prefix "f"
|
||||
:desc "Find file" :n "." #'find-file
|
||||
:desc "Sudo find file" :n ">" #'doom/sudo-find-file
|
||||
:desc "Find file in project" :n "/" #'projectile-find-file
|
||||
:desc "Find file from here" :n "?" #'counsel-file-jump
|
||||
:desc "Find other file" :n "a" #'projectile-find-other-file
|
||||
:desc "Open project editorconfig" :n "c" #'editorconfig-find-current-editorconfig
|
||||
:desc "Find file in dotfiles" :n "d" #'+hlissner/find-in-dotfiles
|
||||
:desc "Browse dotfiles" :n "D" #'+hlissner/browse-dotfiles
|
||||
:desc "Find file in emacs.d" :n "e" #'+hlissner/find-in-emacsd
|
||||
:desc "Browse emacs.d" :n "E" #'+hlissner/browse-emacsd
|
||||
:desc "Recent files" :n "r" #'recentf-open-files
|
||||
:desc "Recent project files" :n "R" #'projectile-recentf
|
||||
:desc "Yank filename" :n "y" #'+hlissner/yank-buffer-filename)
|
||||
|
||||
(:desc "git" :prefix "g"
|
||||
:desc "Git status" :n "S" #'magit-status
|
||||
:desc "Git blame" :n "b" #'magit-blame
|
||||
:desc "Git time machine" :n "t" #'git-timemachine-toggle
|
||||
:desc "Git stage hunk" :n "s" #'git-gutter:stage-hunk
|
||||
:desc "Git revert hunk" :n "r" #'git-gutter:revert-hunk
|
||||
:desc "Git revert buffer" :n "R" #'vc-revert
|
||||
:desc "List gists" :n "g" #'+gist:list
|
||||
:desc "Next hunk" :nv "]" #'git-gutter:next-hunk
|
||||
:desc "Previous hunk" :nv "[" #'git-gutter:previous-hunk)
|
||||
|
||||
(:desc "help" :prefix "h"
|
||||
:n "h" help-map
|
||||
:desc "Apropos" :n "a" #'apropos
|
||||
:desc "Reload theme" :n "R" #'doom//reload-theme
|
||||
:desc "Find library" :n "l" #'find-library
|
||||
:desc "Toggle Emacs log" :n "m" #'doom/popup-toggle-messages
|
||||
:desc "Command log" :n "L" #'global-command-log-mode
|
||||
:desc "Describe function" :n "f" #'describe-function
|
||||
:desc "Describe key" :n "k" #'describe-key
|
||||
:desc "Describe char" :n "c" #'describe-char
|
||||
:desc "Describe mode" :n "M" #'describe-mode
|
||||
:desc "Describe variable" :n "v" #'describe-variable
|
||||
:desc "Describe face" :n "F" #'describe-face
|
||||
:desc "Describe DOOM setting" :n "s" #'doom/describe-setting
|
||||
:desc "Describe DOOM module" :n "d" #'doom/describe-module
|
||||
:desc "Find definition" :n "." #'+jump/definition
|
||||
:desc "Find references" :n "/" #'+jump/references
|
||||
:desc "Find documentation" :n "h" #'+jump/documentation
|
||||
:desc "What face" :n "'" #'doom/what-face
|
||||
:desc "What minor modes" :n ";" #'doom/what-minor-mode
|
||||
:desc "Info" :n "i" #'info
|
||||
:desc "Toggle profiler" :n "p" #'doom/toggle-profiler)
|
||||
|
||||
(:desc "insert" :prefix "i"
|
||||
:desc "From kill-ring" :nv "y" #'counsel-yank-pop
|
||||
:desc "From snippet" :nv "s" #'yas-insert-snippet)
|
||||
|
||||
(:desc "notes" :prefix "n"
|
||||
:desc "Find file in notes" :n "n" #'+hlissner/find-in-notes
|
||||
:desc "Browse notes" :n "N" #'+hlissner/browse-notes
|
||||
:desc "Org capture" :n "x" #'+org-capture/open
|
||||
:desc "Browse mode notes" :n "m" #'+org/browse-notes-for-major-mode
|
||||
:desc "Browse project notes" :n "p" #'+org/browse-notes-for-project)
|
||||
|
||||
(:desc "open" :prefix "o"
|
||||
:desc "Default browser" :n "b" #'browse-url-of-file
|
||||
:desc "Debugger" :n "d" #'+debug/open
|
||||
:desc "REPL" :n "r" #'+eval/open-repl
|
||||
:v "r" #'+eval:repl
|
||||
:desc "Neotree" :n "n" #'+neotree/toggle
|
||||
:desc "Terminal" :n "t" #'+term/open-popup
|
||||
:desc "Terminal in project" :n "T" #'+term/open-popup-in-project
|
||||
|
||||
;; applications
|
||||
:desc "APP: elfeed" :n "E" #'=rss
|
||||
:desc "APP: email" :n "M" #'=email
|
||||
:desc "APP: twitter" :n "T" #'=twitter
|
||||
:desc "APP: regex" :n "X" #'=regex
|
||||
|
||||
;; macos
|
||||
(:when IS-MAC
|
||||
:desc "Reveal in Finder" :n "o" #'+macos/reveal-in-finder
|
||||
:desc "Reveal project in Finder" :n "O" #'+macos/reveal-project-in-finder
|
||||
:desc "Send to Transmit" :n "u" #'+macos/send-to-transmit
|
||||
:desc "Send project to Transmit" :n "U" #'+macos/send-project-to-transmit
|
||||
:desc "Send to Launchbar" :n "l" #'+macos/send-to-launchbar
|
||||
:desc "Send project to Launchbar" :n "L" #'+macos/send-project-to-launchbar))
|
||||
|
||||
(:desc "project" :prefix "p"
|
||||
:desc "Browse project" :n "." (find-file-in! (doom-project-root))
|
||||
:desc "Find file in project" :n "/" #'projectile-find-file
|
||||
:desc "Run cmd in project root" :nv "!" #'projectile-run-shell-command-in-root
|
||||
:desc "Switch project" :n "p" #'projectile-switch-project
|
||||
:desc "Recent project files" :n "r" #'projectile-recentf
|
||||
:desc "List project tasks" :n "t" #'+ivy/tasks
|
||||
:desc "Pop term in project" :n "o" #'+term/open-popup-in-project
|
||||
:desc "Invalidate cache" :n "x" #'projectile-invalidate-cache)
|
||||
|
||||
(:desc "quit" :prefix "q"
|
||||
:desc "Quit" :n "q" #'evil-save-and-quit
|
||||
:desc "Quit (forget session)" :n "Q" #'+workspace/kill-session-and-quit)
|
||||
|
||||
(:desc "remote" :prefix "r"
|
||||
:desc "Upload local" :n "u" #'+upload/local
|
||||
:desc "Upload local (force)" :n "U" (λ! (+upload/local t))
|
||||
:desc "Download remote" :n "d" #'+upload/remote-download
|
||||
:desc "Diff local & remote" :n "D" #'+upload/diff
|
||||
:desc "Browse remote files" :n "." #'+upload/browse
|
||||
:desc "Detect remote changes" :n ">" #'+upload/check-remote)
|
||||
|
||||
(:desc "snippets" :prefix "s"
|
||||
:desc "New snippet" :n "n" #'yas-new-snippet
|
||||
:desc "Insert snippet" :nv "i" #'yas-insert-snippet
|
||||
:desc "Find snippet for mode" :n "s" #'yas-visit-snippet-file
|
||||
:desc "Find snippet" :n "S" #'+hlissner/find-in-snippets)
|
||||
|
||||
(:desc "toggle" :prefix "t"
|
||||
:desc "Flyspell" :n "s" #'flyspell-mode
|
||||
:desc "Flycheck" :n "f" #'flycheck-mode
|
||||
:desc "Line numbers" :n "l" #'doom/toggle-line-numbers
|
||||
:desc "Fullscreen" :n "f" #'doom/toggle-fullscreen
|
||||
:desc "Indent guides" :n "i" #'highlight-indentation-mode
|
||||
:desc "Indent guides (column)" :n "I" #'highlight-indentation-current-column-mode
|
||||
:desc "Impatient mode" :n "h" #'+impatient-mode/toggle
|
||||
:desc "Big mode" :n "b" #'doom-big-font-mode
|
||||
:desc "Evil goggles" :n "g" #'+evil-goggles/toggle))
|
||||
|
||||
|
||||
;; --- Personal vim-esque bindings ------------------
|
||||
:n "zx" #'doom/kill-this-buffer
|
||||
:n "ZX" #'bury-buffer
|
||||
:n "]b" #'doom/next-buffer
|
||||
:n "[b" #'doom/previous-buffer
|
||||
:n "]w" #'+workspace/switch-right
|
||||
:n "[w" #'+workspace/switch-left
|
||||
:m "gt" #'+workspace/switch-right
|
||||
:m "gT" #'+workspace/switch-left
|
||||
:m "gd" #'+jump/definition
|
||||
:m "gD" #'+jump/references
|
||||
:m "gh" #'+jump/documentation
|
||||
:n "gp" #'+evil/reselect-paste
|
||||
:n "gr" #'+eval:region
|
||||
:n "gR" #'+eval/buffer
|
||||
:v "gR" #'+eval:replace-region
|
||||
:v "@" #'+evil:macro-on-all-lines
|
||||
:n "g@" #'+evil:macro-on-all-lines
|
||||
;; repeat in visual mode (FIXME buggy)
|
||||
:v "." #'evil-repeat
|
||||
;; don't leave visual mode after shifting
|
||||
:v "<" #'+evil/visual-dedent ; vnoremap < <gv
|
||||
:v ">" #'+evil/visual-indent ; vnoremap > >gv
|
||||
;; paste from recent yank register (which isn't overwritten)
|
||||
:v "C-p" "\"0p"
|
||||
|
||||
(:map evil-window-map ; prefix "C-w"
|
||||
;; Navigation
|
||||
"C-h" #'evil-window-left
|
||||
"C-j" #'evil-window-down
|
||||
"C-k" #'evil-window-up
|
||||
"C-l" #'evil-window-right
|
||||
"C-w" #'ace-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
|
||||
;; Delete window
|
||||
"c" #'+workspace/close-window-or-workspace
|
||||
"C-C" #'ace-delete-window)
|
||||
|
||||
|
||||
;; --- Plugin bindings ------------------------------
|
||||
;; auto-yasnippet
|
||||
:i [C-tab] #'aya-expand
|
||||
:nv [C-tab] #'aya-create
|
||||
|
||||
;; company-mode (vim-like omnicompletion)
|
||||
:i "C-SPC" #'+company/complete
|
||||
(:prefix "C-x"
|
||||
:i "C-l" #'+company/whole-lines
|
||||
:i "C-k" #'+company/dict-or-keywords
|
||||
:i "C-f" #'company-files
|
||||
:i "C-]" #'company-etags
|
||||
:i "s" #'company-ispell
|
||||
:i "C-s" #'company-yasnippet
|
||||
:i "C-o" #'company-capf
|
||||
:i "C-n" #'company-dabbrev-code
|
||||
:i "C-p" #'+company/dabbrev-code-previous)
|
||||
(:after company
|
||||
(:map company-active-map
|
||||
;; Don't interfere with `evil-delete-backward-word' in insert mode
|
||||
"C-w" nil
|
||||
"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-s" #'company-search-candidates
|
||||
"C-s" #'company-filter-candidates
|
||||
"C-SPC" #'company-complete-common
|
||||
"C-h" #'company-quickhelp-manual-begin
|
||||
[tab] #'company-complete-common-or-cycle
|
||||
[backtab] #'company-select-previous
|
||||
[escape] (λ! (company-abort) (evil-normal-state 1)))
|
||||
;; Automatically applies to `company-filter-map'
|
||||
(:map company-search-map
|
||||
"C-n" #'company-search-repeat-forward
|
||||
"C-p" #'company-search-repeat-backward
|
||||
"C-s" (λ! (company-search-abort) (company-filter-candidates))
|
||||
[escape] #'company-search-abort))
|
||||
|
||||
;; counsel
|
||||
(: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)))
|
||||
|
||||
;; evil-commentary
|
||||
:n "gc" #'evil-commentary
|
||||
|
||||
;; evil-exchange
|
||||
:n "gx" #'evil-exchange
|
||||
|
||||
;; evil-matchit
|
||||
:nv [tab] #'+evil/matchit-or-toggle-fold
|
||||
|
||||
;; evil-magit
|
||||
(:after evil-magit
|
||||
:map (magit-status-mode-map magit-revision-mode-map)
|
||||
:n "C-j" nil
|
||||
:n "C-k" nil)
|
||||
|
||||
;; evil-mc
|
||||
(:prefix "gz"
|
||||
:nv "m" #'evil-mc-make-all-cursors
|
||||
:nv "u" #'evil-mc-undo-all-cursors
|
||||
:nv "z" #'+evil/mc-make-cursor-here
|
||||
:nv "t" #'+evil/mc-toggle-cursors
|
||||
:nv "n" #'evil-mc-make-and-goto-next-cursor
|
||||
:nv "p" #'evil-mc-make-and-goto-prev-cursor
|
||||
:nv "N" #'evil-mc-make-and-goto-last-cursor
|
||||
:nv "P" #'evil-mc-make-and-goto-first-cursor
|
||||
:nv "d" #'evil-mc-make-and-goto-next-match
|
||||
:nv "D" #'evil-mc-make-and-goto-prev-match)
|
||||
(:after evil-mc
|
||||
:map evil-mc-key-map
|
||||
:nv "C-n" #'evil-mc-make-and-goto-next-cursor
|
||||
:nv "C-N" #'evil-mc-make-and-goto-last-cursor
|
||||
:nv "C-p" #'evil-mc-make-and-goto-prev-cursor
|
||||
:nv "C-P" #'evil-mc-make-and-goto-first-cursor)
|
||||
|
||||
;; evil-multiedit
|
||||
:v "R" #'evil-multiedit-match-all
|
||||
:n "M-d" #'evil-multiedit-match-symbol-and-next
|
||||
:n "M-D" #'evil-multiedit-match-symbol-and-prev
|
||||
:v "M-d" #'evil-multiedit-match-and-next
|
||||
:v "M-D" #'evil-multiedit-match-and-prev
|
||||
: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)
|
||||
(:map (evil-multiedit-state-map evil-multiedit-insert-state-map)
|
||||
"C-n" #'evil-multiedit-next
|
||||
"C-p" #'evil-multiedit-prev))
|
||||
|
||||
;; evil-snipe
|
||||
(:after evil-snipe
|
||||
;; Binding to switch to evil-easymotion/avy after a 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
|
||||
|
||||
;; expand-region
|
||||
:v "v" #'er/expand-region
|
||||
:v "V" #'er/contract-region
|
||||
|
||||
;; flycheck
|
||||
:m "]e" #'next-error
|
||||
: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)
|
||||
|
||||
;; flyspell
|
||||
:m "]S" #'flyspell-correct-word-generic
|
||||
:m "[S" #'flyspell-correct-previous-word-generic
|
||||
|
||||
;; git-gutter
|
||||
:m "]d" #'git-gutter:next-hunk
|
||||
:m "[d" #'git-gutter:previous-hunk
|
||||
|
||||
;; git-timemachine
|
||||
(:after git-timemachine
|
||||
(:map git-timemachine-mode-map
|
||||
:n "C-p" #'git-timemachine-show-previous-revision
|
||||
:n "C-n" #'git-timemachine-show-next-revision
|
||||
:n "[[" #'git-timemachine-show-previous-revision
|
||||
:n "]]" #'git-timemachine-show-next-revision
|
||||
:n "q" #'git-timemachine-quit
|
||||
:n "gb" #'git-timemachine-blame))
|
||||
|
||||
;; gist
|
||||
(:after gist
|
||||
:map gist-list-menu-mode-map
|
||||
:n "RET" #'+gist/open-current
|
||||
:n "b" #'gist-browse-current-url
|
||||
:n "c" #'gist-add-buffer
|
||||
:n "d" #'gist-kill-current
|
||||
:n "f" #'gist-fork
|
||||
:n "q" #'quit-window
|
||||
:n "r" #'gist-list-reload
|
||||
:n "s" #'gist-star
|
||||
:n "S" #'gist-unstar
|
||||
:n "y" #'gist-print-current-url)
|
||||
|
||||
;; helm
|
||||
(:after helm
|
||||
(:map helm-map
|
||||
"ESC" nil
|
||||
"C-S-n" #'helm-next-source
|
||||
"C-S-p" #'helm-previous-source
|
||||
"C-u" #'helm-delete-minibuffer-contents
|
||||
"C-w" #'backward-kill-word
|
||||
"C-r" #'evil-paste-from-register ; Evil registers in helm! Glorious!
|
||||
"C-b" #'backward-word
|
||||
[left] #'backward-char
|
||||
[right] #'forward-char
|
||||
[escape] #'helm-keyboard-quit
|
||||
[tab] #'helm-execute-persistent-action)
|
||||
|
||||
(:after helm-files
|
||||
(:map helm-generic-files-map
|
||||
:e "ESC" #'helm-keyboard-quit)
|
||||
(:map helm-find-files-map
|
||||
"C-w" #'helm-find-files-up-one-level
|
||||
"TAB" #'helm-execute-persistent-action))
|
||||
|
||||
(:after helm-ag
|
||||
(:map helm-ag-map
|
||||
"<backtab>" #'helm-ag-edit)))
|
||||
|
||||
;; hl-todo
|
||||
:m "]t" #'hl-todo-next
|
||||
:m "[t" #'hl-todo-previous
|
||||
|
||||
;; ivy
|
||||
(:after ivy
|
||||
:map ivy-minibuffer-map
|
||||
[escape] #'keyboard-escape-quit
|
||||
"C-SPC" #'ivy-call-and-recenter
|
||||
"TAB" #'ivy-partial
|
||||
"M-v" #'yank
|
||||
"M-z" #'undo
|
||||
"C-r" #'evil-paste-from-register
|
||||
"C-k" #'ivy-previous-line
|
||||
"C-j" #'ivy-next-line
|
||||
"C-l" #'ivy-alt-done
|
||||
"C-w" #'ivy-backward-kill-word
|
||||
"C-u" #'ivy-kill-line
|
||||
"C-b" #'backward-word
|
||||
"C-f" #'forward-word)
|
||||
|
||||
;; neotree
|
||||
(:after neotree
|
||||
:map neotree-mode-map
|
||||
:n "g" nil
|
||||
:n [tab] #'neotree-quick-look
|
||||
:n "RET" #'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)
|
||||
|
||||
;; realgud
|
||||
(:after realgud
|
||||
:map realgud:shortkey-mode-map
|
||||
:n "j" #'evil-next-line
|
||||
:n "k" #'evil-previous-line
|
||||
:n "h" #'evil-backward-char
|
||||
:n "l" #'evil-forward-char
|
||||
:m "n" #'realgud:cmd-next
|
||||
:m "b" #'realgud:cmd-break
|
||||
:m "B" #'realgud:cmd-clear
|
||||
:n "c" #'realgud:cmd-continue)
|
||||
|
||||
;; rotate-text
|
||||
:n "!" #'rotate-text
|
||||
|
||||
;; smart-forward
|
||||
:nv "K" #'smart-up
|
||||
:m "g]" #'smart-forward
|
||||
:m "g[" #'smart-backward
|
||||
|
||||
;; undo-tree -- undo/redo for visual regions
|
||||
:v "C-u" #'undo-tree-undo
|
||||
:v "C-r" #'undo-tree-redo
|
||||
|
||||
;; yasnippet
|
||||
(:after yasnippet
|
||||
(:map yas-keymap
|
||||
"C-e" #'+snippets/goto-end-of-field
|
||||
"C-a" #'+snippets/goto-start-of-field
|
||||
"<M-right>" #'+snippets/goto-end-of-field
|
||||
"<M-left>" #'+snippets/goto-start-of-field
|
||||
"<M-backspace>" #'+snippets/delete-to-start-of-field
|
||||
[escape] #'evil-normal-state
|
||||
[backspace] #'+snippets/delete-backward-char
|
||||
[delete] #'+snippets/delete-forward-char-or-field)
|
||||
(:map yas-minor-mode-map
|
||||
:i "<tab>" yas-maybe-expand
|
||||
:v "<tab>" #'+snippets/expand-on-region))
|
||||
|
||||
|
||||
;; --- Major mode bindings --------------------------
|
||||
(:after markdown-mode
|
||||
(:map markdown-mode-map
|
||||
;; fix conflicts with private bindings
|
||||
"<backspace>" nil
|
||||
"<M-left>" nil
|
||||
"<M-right>" nil))
|
||||
|
||||
|
||||
;; --- Custom evil text-objects ---------------------
|
||||
: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 "I" #'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
|
||||
|
||||
|
||||
;; --- Built-in plugins -----------------------------
|
||||
(:after comint
|
||||
;; TAB auto-completion in term buffers
|
||||
:map comint-mode-map [tab] #'company-complete)
|
||||
|
||||
(:after debug
|
||||
;; For elisp debugging
|
||||
:map debugger-mode-map
|
||||
:n "RET" #'debug-help-follow
|
||||
:n "e" #'debugger-eval-expression
|
||||
:n "n" #'debugger-step-through
|
||||
:n "c" #'debugger-continue)
|
||||
|
||||
(:map help-mode-map
|
||||
:n "[[" #'help-go-back
|
||||
:n "]]" #'help-go-forward
|
||||
:n "o" #'ace-link-help
|
||||
:n "q" #'quit-window
|
||||
:n "Q" #'+ivy-quit-and-resume)
|
||||
|
||||
(:after vc-annotate
|
||||
:map vc-annotate-mode-map
|
||||
:n "q" #'kill-this-buffer
|
||||
:n "d" #'vc-annotate-show-diff-revision-at-line
|
||||
:n "D" #'vc-annotate-show-changeset-diff-revision-at-line
|
||||
:n "SPC" #'vc-annotate-show-log-revision-at-line
|
||||
:n "]]" #'vc-annotate-next-revision
|
||||
:n "[[" #'vc-annotate-prev-revision
|
||||
:n "TAB" #'vc-annotate-toggle-annotation-visibility
|
||||
:n "RET" #'vc-annotate-find-revision-at-line))
|
||||
|
||||
|
||||
;; --- Custom key functionality ---------------------
|
||||
(defmacro do-repeat! (command next-func prev-func)
|
||||
"Repeat motions with ;/,"
|
||||
(let ((fn-sym (intern (format "+evil*repeat-%s" command))))
|
||||
`(progn
|
||||
(defun ,fn-sym (&rest _)
|
||||
(define-key evil-motion-state-map (kbd ";") ',next-func)
|
||||
(define-key evil-motion-state-map (kbd ",") ',prev-func))
|
||||
(advice-add #',command :before #',fn-sym))))
|
||||
|
||||
;; n/N
|
||||
(do-repeat! evil-ex-search-next evil-ex-search-next evil-ex-search-previous)
|
||||
(do-repeat! evil-ex-search-previous evil-ex-search-next evil-ex-search-previous)
|
||||
(do-repeat! evil-ex-search-forward evil-ex-search-next evil-ex-search-previous)
|
||||
(do-repeat! evil-ex-search-backward evil-ex-search-next evil-ex-search-previous)
|
||||
|
||||
;; f/F/t/T/s/S
|
||||
(after! evil-snipe
|
||||
(setq evil-snipe-repeat-keys nil
|
||||
evil-snipe-override-evil-repeat-keys nil) ; causes problems with remapped ;
|
||||
|
||||
(do-repeat! evil-snipe-f evil-snipe-repeat evil-snipe-repeat-reverse)
|
||||
(do-repeat! evil-snipe-F evil-snipe-repeat evil-snipe-repeat-reverse)
|
||||
(do-repeat! evil-snipe-t evil-snipe-repeat evil-snipe-repeat-reverse)
|
||||
(do-repeat! evil-snipe-T evil-snipe-repeat evil-snipe-repeat-reverse)
|
||||
(do-repeat! evil-snipe-s evil-snipe-repeat evil-snipe-repeat-reverse)
|
||||
(do-repeat! evil-snipe-S evil-snipe-repeat evil-snipe-repeat-reverse)
|
||||
(do-repeat! evil-snipe-x evil-snipe-repeat evil-snipe-repeat-reverse)
|
||||
(do-repeat! evil-snipe-X evil-snipe-repeat evil-snipe-repeat-reverse))
|
||||
|
||||
;; */#
|
||||
(after! evil-visualstar
|
||||
(do-repeat! evil-visualstar/begin-search-forward
|
||||
evil-ex-search-next evil-ex-search-previous)
|
||||
(do-repeat! evil-visualstar/begin-search-backward
|
||||
evil-ex-search-previous evil-ex-search-next))
|
||||
|
||||
;; evil-easymotion
|
||||
(after! evil-easymotion
|
||||
(let ((prefix (concat doom-leader-key " /")))
|
||||
;; NOTE `evilem-default-keybinds' unsets all other keys on the prefix (in
|
||||
;; motion state)
|
||||
(evilem-default-keybindings prefix)
|
||||
(evilem-define (kbd (concat prefix " n")) #'evil-ex-search-next)
|
||||
(evilem-define (kbd (concat prefix " N")) #'evil-ex-search-previous)
|
||||
(evilem-define (kbd (concat prefix " s")) #'evil-snipe-repeat
|
||||
:pre-hook (save-excursion (call-interactively #'evil-snipe-s))
|
||||
:bind ((evil-snipe-scope 'buffer)
|
||||
(evil-snipe-enable-highlight)
|
||||
(evil-snipe-enable-incremental-highlight)))
|
||||
(evilem-define (kbd (concat prefix " S")) #'evil-snipe-repeat-reverse
|
||||
:pre-hook (save-excursion (call-interactively #'evil-snipe-s))
|
||||
:bind ((evil-snipe-scope 'buffer)
|
||||
(evil-snipe-enable-highlight)
|
||||
(evil-snipe-enable-incremental-highlight)))))
|
||||
|
||||
|
||||
;;
|
||||
;; Keybinding fixes
|
||||
;;
|
||||
|
||||
;; This section is dedicated to "fixing" certain keys so that they behave
|
||||
;; properly, more like vim, or how I like it.
|
||||
|
||||
(map! (:map input-decode-map
|
||||
[S-iso-lefttab] [backtab]
|
||||
(:unless window-system "TAB" [tab])) ; Fix TAB in terminal
|
||||
|
||||
;; I want C-a and C-e to be a little smarter. 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 and trailing whitespace before
|
||||
;; jumping to eol.
|
||||
:i "C-a" #'doom/backward-to-bol-or-indent
|
||||
:i "C-e" #'doom/forward-to-last-non-comment-or-eol
|
||||
:i "C-u" #'doom/backward-kill-to-bol-and-indent
|
||||
|
||||
;; textmate-esque newline insertion
|
||||
:i [M-return] #'evil-open-below
|
||||
:i [S-M-return] #'evil-open-above
|
||||
;; textmate-esque deletion
|
||||
[M-backspace] #'doom/backward-kill-to-bol-and-indent
|
||||
:i [backspace] #'delete-backward-char
|
||||
:i [M-backspace] #'doom/backward-kill-to-bol-and-indent
|
||||
;; Emacsien motions for insert mode
|
||||
:i "C-b" #'backward-word
|
||||
:i "C-f" #'forward-word
|
||||
|
||||
;; Highjacks space/backspace to:
|
||||
;; a) balance spaces inside brackets/parentheses ( | ) -> (|)
|
||||
;; b) delete space-indented blocks intelligently
|
||||
;; c) do none of this when inside a string
|
||||
:i "SPC" #'doom/inflate-space-maybe
|
||||
:i [remap delete-backward-char] #'doom/deflate-space-maybe
|
||||
:i [remap newline] #'doom/newline-and-indent
|
||||
|
||||
(:after org
|
||||
(:map org-mode-map
|
||||
:i [remap doom/inflate-space-maybe] #'org-self-insert-command
|
||||
:i "C-e" #'org-end-of-line
|
||||
:i "C-a" #'org-beginning-of-line))
|
||||
|
||||
;; Restore common editing keys (and ESC) in minibuffer
|
||||
(:map (minibuffer-local-map
|
||||
minibuffer-local-ns-map
|
||||
minibuffer-local-completion-map
|
||||
minibuffer-local-must-match-map
|
||||
minibuffer-local-isearch-map
|
||||
evil-ex-completion-map
|
||||
evil-ex-search-keymap
|
||||
read-expression-map)
|
||||
[escape] #'abort-recursive-edit
|
||||
"C-r" #'evil-paste-from-register
|
||||
"C-a" #'move-beginning-of-line
|
||||
"C-w" #'doom/minibuffer-kill-word
|
||||
"C-u" #'doom/minibuffer-kill-line
|
||||
"C-b" #'backward-word
|
||||
"C-f" #'forward-word
|
||||
"M-z" #'doom/minibuffer-undo)
|
||||
|
||||
(:map messages-buffer-mode-map
|
||||
"M-;" #'eval-expression
|
||||
"A-;" #'eval-expression)
|
||||
|
||||
(:map tabulated-list-mode-map
|
||||
[remap evil-record-macro] #'doom/popup-close-maybe)
|
||||
|
||||
(:after view
|
||||
(:map view-mode-map "<escape>" #'View-quit-all)))
|
2
modules/private/hlissner/.gitignore
vendored
2
modules/private/hlissner/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
|||
snippets
|
||||
.authinfo.gpg
|
|
@ -1,37 +0,0 @@
|
|||
;;; private/hlissner/autoload/evil.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! :feature evil)
|
||||
|
||||
;;;###autoload (autoload '+hlissner:multi-next-line "private/hlissner/autoload/evil" nil t)
|
||||
(evil-define-motion +hlissner:multi-next-line (count)
|
||||
"Move down 6 lines."
|
||||
:type line
|
||||
(let ((line-move-visual (or visual-line-mode (derived-mode-p 'text-mode))))
|
||||
(evil-line-move (* 6 (or count 1)))))
|
||||
|
||||
;;;###autoload (autoload '+hlissner:multi-previous-line "private/hlissner/autoload/evil" nil t)
|
||||
(evil-define-motion +hlissner:multi-previous-line (count)
|
||||
"Move up 6 lines."
|
||||
:type line
|
||||
(let ((line-move-visual (or visual-line-mode (derived-mode-p 'text-mode))))
|
||||
(evil-line-move (- (* 6 (or count 1))))))
|
||||
|
||||
;;;###autoload (autoload '+hlissner:cd "private/hlissner/autoload/evil" nil t)
|
||||
(evil-define-command +hlissner:cd ()
|
||||
"Change `default-directory' with `cd'."
|
||||
(interactive "<f>")
|
||||
(cd input))
|
||||
|
||||
;;;###autoload (autoload '+hlissner:kill-all-buffers "private/hlissner/autoload/evil" nil t)
|
||||
(evil-define-command +hlissner: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 '+hlissner:kill-matching-buffers "private/hlissner/autoload/evil" nil t)
|
||||
(evil-define-command +hlissner: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))
|
|
@ -1,53 +0,0 @@
|
|||
;;; private/hlissner/autoload/hlissner.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun +hlissner/install-snippets ()
|
||||
"Install my snippets from https://github.com/hlissner/emacs-snippets into
|
||||
private/hlissner/snippets."
|
||||
(interactive)
|
||||
(doom-fetch :github "hlissner/emacs-snippets"
|
||||
(expand-file-name "snippets" (doom-module-path :private 'hlissner))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +hlissner/yank-buffer-filename ()
|
||||
"Copy the current buffer's path to the kill ring."
|
||||
(interactive)
|
||||
(if-let* ((filename (or buffer-file-name (bound-and-true-p list-buffers-directory))))
|
||||
(message (kill-new (abbreviate-file-name filename)))
|
||||
(error "Couldn't find filename in current buffer")))
|
||||
|
||||
(defmacro +hlissner-def-finder! (name dir)
|
||||
"Define a pair of find-file and browse functions."
|
||||
`(progn
|
||||
(defun ,(intern (format "+hlissner/find-in-%s" name)) ()
|
||||
(interactive)
|
||||
(let ((default-directory ,dir)
|
||||
projectile-project-name
|
||||
projectile-require-project-root
|
||||
projectile-cached-buffer-file-name
|
||||
projectile-cached-project-root)
|
||||
(call-interactively (command-remapping #'projectile-find-file))))
|
||||
(defun ,(intern (format "+hlissner/browse-%s" name)) ()
|
||||
(interactive)
|
||||
(let ((default-directory ,dir))
|
||||
(call-interactively (command-remapping #'find-file))))))
|
||||
|
||||
;;;###autoload (autoload '+hlissner/find-in-templates "private/hlissner/autoload/hlissner" nil t)
|
||||
;;;###autoload (autoload '+hlissner/browse-templates "private/hlissner/autoload/hlissner" nil t)
|
||||
(+hlissner-def-finder! templates +file-templates-dir)
|
||||
|
||||
;;;###autoload (autoload '+hlissner/find-in-snippets "private/hlissner/autoload/hlissner" nil t)
|
||||
;;;###autoload (autoload '+hlissner/browse-snippets "private/hlissner/autoload/hlissner" nil t)
|
||||
(+hlissner-def-finder! snippets +hlissner-snippets-dir)
|
||||
|
||||
;;;###autoload (autoload '+hlissner/find-in-dotfiles "private/hlissner/autoload/hlissner" nil t)
|
||||
;;;###autoload (autoload '+hlissner/browse-dotfiles "private/hlissner/autoload/hlissner" nil t)
|
||||
(+hlissner-def-finder! dotfiles (expand-file-name ".dotfiles" "~"))
|
||||
|
||||
;;;###autoload (autoload '+hlissner/find-in-emacsd "private/hlissner/autoload/hlissner" nil t)
|
||||
;;;###autoload (autoload '+hlissner/browse-emacsd "private/hlissner/autoload/hlissner" nil t)
|
||||
(+hlissner-def-finder! emacsd doom-emacs-dir)
|
||||
|
||||
;;;###autoload (autoload '+hlissner/find-in-notes "private/hlissner/autoload/hlissner" nil t)
|
||||
;;;###autoload (autoload '+hlissner/browse-notes "private/hlissner/autoload/hlissner" nil t)
|
||||
(+hlissner-def-finder! notes +org-dir)
|
|
@ -1,108 +0,0 @@
|
|||
;;; private/hlissner/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +hlissner-dir (file-name-directory load-file-name))
|
||||
(defvar +hlissner-snippets-dir (expand-file-name "snippets/" +hlissner-dir))
|
||||
|
||||
;;
|
||||
(when (featurep! :feature evil)
|
||||
(load! +bindings) ; my key bindings
|
||||
(load! +commands)) ; my custom ex commands
|
||||
|
||||
|
||||
;;
|
||||
;; Global config
|
||||
;;
|
||||
|
||||
(setq epa-file-encrypt-to user-mail-address
|
||||
auth-sources (list (expand-file-name ".authinfo.gpg" +hlissner-dir))
|
||||
+doom-modeline-buffer-file-name-style 'relative-from-project)
|
||||
|
||||
(defun +hlissner*no-authinfo-for-tramp (orig-fn &rest args)
|
||||
"Don't look into .authinfo for local sudo TRAMP buffers."
|
||||
(let ((auth-sources (if (equal tramp-current-method "sudo") nil auth-sources)))
|
||||
(apply orig-fn args)))
|
||||
(advice-add #'tramp-read-passwd :around #'+hlissner*no-authinfo-for-tramp)
|
||||
|
||||
|
||||
;;
|
||||
;; Modules
|
||||
;;
|
||||
|
||||
(after! smartparens
|
||||
;; Auto-close more conservatively and expand braces on RET
|
||||
(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))
|
||||
(sp-pair "{" nil :post-handlers '(("||\n[i]" "RET") ("| " " "))
|
||||
:unless '(sp-point-before-word-p sp-point-before-same-p))
|
||||
(sp-pair "(" nil :post-handlers '(("||\n[i]" "RET") ("| " " "))
|
||||
:unless '(sp-point-before-word-p sp-point-before-same-p))
|
||||
(sp-pair "[" nil :post-handlers '(("| " " "))
|
||||
:unless '(sp-point-before-word-p sp-point-before-same-p)))
|
||||
|
||||
;; feature/evil
|
||||
(after! evil-mc
|
||||
;; Make evil-mc resume its cursors when I switch to insert mode
|
||||
(add-hook! 'evil-mc-before-cursors-created
|
||||
(add-hook 'evil-insert-state-entry-hook #'evil-mc-resume-cursors nil t))
|
||||
(add-hook! 'evil-mc-after-cursors-deleted
|
||||
(remove-hook 'evil-insert-state-entry-hook #'evil-mc-resume-cursors t)))
|
||||
|
||||
;; feature/snippets
|
||||
(after! yasnippet
|
||||
;; Don't use default snippets, use mine.
|
||||
(setq yas-snippet-dirs
|
||||
(append (list '+hlissner-snippets-dir)
|
||||
(delq 'yas-installed-snippets-dir yas-snippet-dirs))))
|
||||
|
||||
;; completion/helm
|
||||
(after! helm
|
||||
;; Hide header lines in helm. I don't like them
|
||||
(set-face-attribute 'helm-source-header nil :height 0.1))
|
||||
|
||||
;; lang/org
|
||||
(after! org-bullets
|
||||
;; The standard unicode characters are usually misaligned depending on the
|
||||
;; font. This bugs me. Personally, markdown #-marks for headlines are more
|
||||
;; elegant, so we use those.
|
||||
(setq org-bullets-bullet-list '("#")))
|
||||
|
||||
;; app/irc
|
||||
(after! circe
|
||||
(setq +irc-notifications-watch-strings '("v0" "vnought" "hlissner"))
|
||||
|
||||
(set! :irc "irc.snoonet.org"
|
||||
`(:tls t
|
||||
:nick "v0"
|
||||
:port 6697
|
||||
:sasl-username ,(+pass-get-user "irc/snoonet.org")
|
||||
:sasl-password ,(+pass-get-secret "irc/snoonet.org")
|
||||
:channels (:after-auth "#ynought"))))
|
||||
|
||||
;; app/email
|
||||
(after! mu4e
|
||||
(setq smtpmail-stream-type 'starttls
|
||||
smtpmail-default-smtp-server "smtp.gmail.com"
|
||||
smtpmail-smtp-server "smtp.gmail.com"
|
||||
smtpmail-smtp-service 587)
|
||||
|
||||
(set! :email "gmail.com"
|
||||
'((mu4e-sent-folder . "/gmail.com/Sent Mail")
|
||||
(mu4e-drafts-folder . "/gmail.com/Drafts")
|
||||
(mu4e-trash-folder . "/gmail.com/Trash")
|
||||
(mu4e-refile-folder . "/gmail.com/All Mail")
|
||||
(smtpmail-smtp-user . "hlissner")
|
||||
(user-mail-address . "hlissner@gmail.com")
|
||||
(mu4e-compose-signature . "---\nHenrik")))
|
||||
|
||||
(set! :email "lissner.net"
|
||||
'((mu4e-sent-folder . "/lissner.net/Sent Mail")
|
||||
(mu4e-drafts-folder . "/lissner.net/Drafts")
|
||||
(mu4e-trash-folder . "/lissner.net/Trash")
|
||||
(mu4e-refile-folder . "/lissner.net/All Mail")
|
||||
(smtpmail-smtp-user . "henrik@lissner.net")
|
||||
(user-mail-address . "henrik@lissner.net")
|
||||
(mu4e-compose-signature . "---\nHenrik Lissner"))
|
||||
t))
|
|
@ -1,52 +0,0 @@
|
|||
;;; private/hlissner/init.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; An extra measure to prevent the flash of unstyled mode-line while Emacs is
|
||||
;; booting up (when Doom is byte-compiled).
|
||||
(setq-default mode-line-format nil)
|
||||
|
||||
;; I've swapped these keys on my keyboard
|
||||
(setq x-super-keysym 'alt
|
||||
x-alt-keysym 'meta)
|
||||
|
||||
(setq user-mail-address "henrik@lissner.net"
|
||||
user-full-name "Henrik Lissner")
|
||||
|
||||
(setq doom-big-font (font-spec :family "Fira Mono" :size 19))
|
||||
|
||||
(pcase (system-name)
|
||||
("proteus"
|
||||
;; My 13" laptop has very little screen estate, so we use a bitmap font
|
||||
;; there. For Doom, that means we need to take up less space!
|
||||
(setq-default line-spacing 1)
|
||||
|
||||
(setq doom-font (font-spec :family "kakwa kakwafont" :size 12)
|
||||
doom-variable-pitch-font (font-spec :family "kakwa kakwafont")
|
||||
doom-unicode-font (font-spec :family "UT Ttyp0")
|
||||
;; ui/doom-modeline
|
||||
+doom-modeline-height 23
|
||||
;; `doom-themes'
|
||||
doom-neotree-enable-variable-pitch nil
|
||||
doom-neotree-project-size 1.2
|
||||
doom-neotree-line-spacing 0
|
||||
doom-neotree-folder-size 1.0
|
||||
doom-neotree-chevron-size 0.6)
|
||||
(add-hook! doom-big-font-mode
|
||||
(setq +doom-modeline-height (if doom-big-font-mode 37 23)))
|
||||
|
||||
;; No highlighted bar in the mode-line
|
||||
(setq +doom-modeline-bar-width 1)
|
||||
(custom-set-faces '(doom-modeline-bar ((t (:background nil))))))
|
||||
|
||||
(_
|
||||
;; Everywhere else, I have big displays and plenty of space, so use it!
|
||||
(setq doom-font (font-spec :family "Fira Mono" :size 12)
|
||||
doom-variable-pitch-font (font-spec :family "Fira Sans")
|
||||
doom-unicode-font (font-spec :family "DejaVu Sans Mono")
|
||||
org-ellipsis " ")
|
||||
|
||||
;; Fira Mono doesn't have italics, so we highlight it instead.
|
||||
(add-hook! doom-post-init
|
||||
(set-face-attribute 'italic nil :weight 'ultra-light :foreground "#ffffff"))
|
||||
|
||||
(add-hook! doom-big-font-mode
|
||||
(setq +doom-modeline-height (if doom-big-font-mode 37 29)))))
|
|
@ -1,7 +1,9 @@
|
|||
#+TITLE: :evil neotree
|
||||
|
||||
This module brings a side panel for browsing project files, inspired by vim's NERDTree.
|
||||
This module brings a side panel for browsing project files, inspired by vim's
|
||||
NERDTree.
|
||||
|
||||
#+begin_quote
|
||||
Sure, there's dired and projectile, but sometimes I'd like a bird's eye view of a project.
|
||||
Sure, there's dired and projectile, but sometimes I'd like a bird's eye view of
|
||||
a project.
|
||||
#+end_quote
|
||||
|
|
|
@ -9,13 +9,15 @@
|
|||
(require 'neotree)
|
||||
(cond ((and (neo-global--window-exists-p)
|
||||
(get-buffer-window neo-buffer-name t))
|
||||
(neotree-find path project-root))
|
||||
(neotree-find path project-root)
|
||||
(neotree-refresh))
|
||||
((not (and (neo-global--window-exists-p)
|
||||
(equal (file-truename (neo-global--with-buffer neo-buffer--start-node))
|
||||
(file-truename project-root))))
|
||||
(neotree-dir project-root)
|
||||
(neotree-find path project-root))
|
||||
(t (neotree-find path project-root)))))
|
||||
(t
|
||||
(neotree-find path project-root)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +neotree/collapse-or-up ()
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
(and (or (string-match-p "https?://" url)
|
||||
(error "Field for %s doesn't look like an url" item))
|
||||
(browse-url url))
|
||||
(error "Username not found.")))
|
||||
(error "url not found.")))
|
||||
|
||||
(defun +pass-ivy-action--get-field (item)
|
||||
(let* ((data (+pass--get-entry item))
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
(load! ../autoload)
|
||||
|
||||
(defmacro -with-passwords! (buffer-args &rest body)
|
||||
(defmacro with-passwords!! (buffer-args &rest body)
|
||||
(declare (indent defun))
|
||||
`(cl-letf
|
||||
(((symbol-function '+pass--get-entry)
|
||||
|
@ -18,7 +18,7 @@
|
|||
|
||||
;;
|
||||
(def-test! get-field
|
||||
(-with-passwords!
|
||||
(with-passwords!!
|
||||
(should (equal (+pass-get-field "fake/source" "login")
|
||||
"HL2532-GANDI"))
|
||||
(should (equal (+pass-get-field "fake/source" "email")
|
||||
|
@ -29,14 +29,14 @@
|
|||
"henrik@lissner.net"))))
|
||||
|
||||
(def-test! missing-fields-return-nil
|
||||
(-with-passwords!
|
||||
(with-passwords!!
|
||||
(should-not (+pass-get-field "fake/source" '("x" "y" "z")))))
|
||||
|
||||
(def-test! missing-entries-throw-error
|
||||
(-with-passwords!
|
||||
(with-passwords!!
|
||||
(should-error (+pass-get-field "nonexistent/source" "login"))))
|
||||
|
||||
(def-test! get-login
|
||||
(-with-passwords!
|
||||
(with-passwords!!
|
||||
(should (equal (+pass-get-user "fake/source") "HL2532-GANDI"))
|
||||
(should (equal (+pass-get-secret "fake/source") "defuse-account-gad"))))
|
||||
|
|
|
@ -3,20 +3,38 @@
|
|||
(defvar +doom-dashboard-name " *doom*"
|
||||
"The name to use for the dashboard buffer.")
|
||||
|
||||
(defvar +doom-dashboard-inhibit-refresh nil
|
||||
"If non-nil, the doom buffer won't be refreshed.")
|
||||
|
||||
(defvar +doom-dashboard-widgets '(banner shortmenu loaded)
|
||||
"List of widgets to display in a blank scratch buffer.")
|
||||
|
||||
(defvar +doom-dashboard-inhibit-refresh nil
|
||||
"If non-nil, the doom buffer won't be refreshed.")
|
||||
|
||||
(defvar +doom-dashboard-inhibit-functions ()
|
||||
"A list of functions that determine whether to inhibit the dashboard the
|
||||
"A list of functions that determine whether to inhibit the dashboard from
|
||||
loading.")
|
||||
|
||||
(defvar +doom-dashboard-pwd-policy 'last-project
|
||||
"The policy to use when setting the `default-directory' in the dashboard.
|
||||
|
||||
Possible values:
|
||||
|
||||
'last-project the `doom-project-root' of the last open buffer
|
||||
'last the `default-directory' of the last open buffer
|
||||
a FUNCTION a function run with the `default-directory' of the last
|
||||
open buffer, that returns a directory path
|
||||
a STRING a fixed path
|
||||
nil `default-directory' will never change")
|
||||
|
||||
;;
|
||||
(defvar +doom-dashboard--last-cwd nil)
|
||||
(defvar +doom-dashboard--width 80)
|
||||
(defvar +doom-dashboard--height 0)
|
||||
(defvar +doom-dashboard--old-fringe-indicator fringe-indicator-alist)
|
||||
|
||||
(defvar all-the-icons-scale-factor)
|
||||
(defvar all-the-icons-default-adjust)
|
||||
|
||||
;;
|
||||
(setq doom-fallback-buffer +doom-dashboard-name)
|
||||
|
||||
|
||||
|
@ -25,6 +43,8 @@ loading.")
|
|||
"Major mode for the DOOM dashboard buffer."
|
||||
(read-only-mode +1)
|
||||
(setq truncate-lines t)
|
||||
(setq-local whitespace-style nil)
|
||||
(setq-local show-trailing-whitespace nil)
|
||||
(cl-loop for (car . _cdr) in fringe-indicator-alist
|
||||
collect (cons car nil) into alist
|
||||
finally do (setq fringe-indicator-alist alist)))
|
||||
|
@ -51,15 +71,25 @@ loading.")
|
|||
if in a GUI/non-daemon session."
|
||||
(add-hook 'window-configuration-change-hook #'+doom-dashboard-reload)
|
||||
(add-hook 'focus-in-hook #'+doom-dashboard-reload)
|
||||
(add-hook 'kill-buffer-query-functions #'+doom-dashboard|kill-buffer-query-fn)
|
||||
(add-hook 'kill-buffer-query-functions #'+doom-dashboard|reload-on-kill)
|
||||
(when (and (display-graphic-p) (not (daemonp)))
|
||||
(let ((default-directory doom-emacs-dir))
|
||||
(+doom-dashboard/open (selected-frame)))))
|
||||
|
||||
(defun +doom-dashboard|kill-buffer-query-fn ()
|
||||
(or (not (+doom-dashboard-p))
|
||||
(ignore (let (+doom-dashboard-inhibit-refresh)
|
||||
(ignore-errors (+doom-dashboard-reload))))))
|
||||
(defun +doom-dashboard|reload-on-kill ()
|
||||
"If this isn't a dashboard buffer, move along, but record its
|
||||
`default-directory' if the buffer is real. See `doom-real-buffer-p' for an
|
||||
explanation for what 'real' means.
|
||||
|
||||
If this is the dashboard buffer, reload the dashboard."
|
||||
(or (unless (+doom-dashboard-p)
|
||||
(when (doom-real-buffer-p)
|
||||
(setq +doom-dashboard--last-cwd default-directory)
|
||||
(+doom-dashboard-update-pwd))
|
||||
t)
|
||||
(ignore
|
||||
(let (+doom-dashboard-inhibit-refresh)
|
||||
(ignore-errors (+doom-dashboard-reload))))))
|
||||
|
||||
(defun +doom-dashboard|make-frame (frame)
|
||||
"Reload the dashboard after a brief pause. This is necessary for new frames,
|
||||
|
@ -85,55 +115,87 @@ whose dimensions may not be fully initialized by the time this is run."
|
|||
(+doom-dashboard-reload)))
|
||||
(setq +doom-dashboard-inhibit-refresh nil)))
|
||||
|
||||
;
|
||||
(defun +doom-dashboard-p (&optional buffer)
|
||||
"Returns t if BUFFER is the dashboard buffer."
|
||||
(let ((buffer (or buffer (current-buffer))))
|
||||
(and (buffer-live-p buffer)
|
||||
(eq buffer (doom-fallback-buffer)))))
|
||||
(eq (or buffer (current-buffer))
|
||||
(doom-fallback-buffer)))
|
||||
|
||||
(defun +doom-dashboard-center (len s)
|
||||
(concat (make-string (ceiling (max 0 (- len (length s))) 2) ? )
|
||||
s))
|
||||
(defun +doom-dashboard-update-pwd ()
|
||||
"TODO"
|
||||
(with-current-buffer (doom-fallback-buffer)
|
||||
(cd (or (+doom-dashboard--get-pwd)
|
||||
default-directory))))
|
||||
|
||||
(defun +doom-dashboard-reload (&optional dir)
|
||||
(defun +doom-dashboard-reload (&optional force)
|
||||
"Update the DOOM scratch buffer (or create it, if it doesn't exist)."
|
||||
(when (get-buffer-window (doom-fallback-buffer))
|
||||
(unless (or +doom-dashboard-inhibit-refresh
|
||||
(window-minibuffer-p (frame-selected-window)))
|
||||
(let ((old-pwd (or dir default-directory))
|
||||
(fallback-buffer (doom-fallback-buffer)))
|
||||
(with-current-buffer fallback-buffer
|
||||
(with-silent-modifications
|
||||
(unless (eq major-mode '+doom-dashboard-mode)
|
||||
(+doom-dashboard-mode))
|
||||
(erase-buffer)
|
||||
(setq default-directory old-pwd)
|
||||
(let ((+doom-dashboard--height (window-height (get-buffer-window fallback-buffer)))
|
||||
(lines 1)
|
||||
content)
|
||||
(with-temp-buffer
|
||||
(dolist (widget-name +doom-dashboard-widgets)
|
||||
(funcall (intern (format "doom-dashboard-widget--%s" widget-name)))
|
||||
(insert "\n"))
|
||||
(setq content (buffer-string)
|
||||
lines (count-lines (point-min) (point-max))))
|
||||
(insert (make-string (max 0 (- (/ +doom-dashboard--height 2)
|
||||
(/ lines 2)))
|
||||
?\n)
|
||||
content))
|
||||
(unless (button-at (point))
|
||||
(goto-char (next-button (point-min))))))))
|
||||
(let ((fallback-buffer (doom-fallback-buffer)))
|
||||
(when (or (and after-init-time
|
||||
(not +doom-dashboard-inhibit-refresh)
|
||||
(get-buffer-window fallback-buffer)
|
||||
(not (window-minibuffer-p (frame-selected-window))))
|
||||
force)
|
||||
(with-current-buffer fallback-buffer
|
||||
(+doom-dashboard-update-pwd)
|
||||
(with-silent-modifications
|
||||
(unless (eq major-mode '+doom-dashboard-mode)
|
||||
(+doom-dashboard-mode))
|
||||
(erase-buffer)
|
||||
(let ((+doom-dashboard--height
|
||||
(window-height (get-buffer-window fallback-buffer)))
|
||||
(lines 1)
|
||||
content)
|
||||
(with-temp-buffer
|
||||
(dolist (widget-name +doom-dashboard-widgets)
|
||||
(funcall (intern (format "doom-dashboard-widget--%s" widget-name)))
|
||||
(insert "\n"))
|
||||
(setq content (buffer-string)
|
||||
lines (count-lines (point-min) (point-max))))
|
||||
(insert (make-string (max 0 (- (/ +doom-dashboard--height 2)
|
||||
(/ lines 2)))
|
||||
?\n)
|
||||
content))
|
||||
(unless (button-at (point))
|
||||
(goto-char (next-button (point-min)))))))
|
||||
;; Update all dashboard windows
|
||||
(dolist (win (get-buffer-window-list (doom-fallback-buffer) nil t))
|
||||
(dolist (win (get-buffer-window-list fallback-buffer nil t))
|
||||
(set-window-fringes win 0 0)
|
||||
(set-window-margins
|
||||
win (max 0 (/ (- (window-total-width win) +doom-dashboard--width) 2)))))
|
||||
t)
|
||||
|
||||
;; helpers
|
||||
(defun +doom-dashboard--center (len s)
|
||||
(concat (make-string (ceiling (max 0 (- len (length s))) 2) ? )
|
||||
s))
|
||||
|
||||
(defun +doom-dashboard--get-pwd ()
|
||||
(let ((lastcwd +doom-dashboard--last-cwd)
|
||||
(policy +doom-dashboard-pwd-policy))
|
||||
(cond ((null policy)
|
||||
default-directory)
|
||||
((stringp policy)
|
||||
(expand-file-name policy lastcwd))
|
||||
((functionp policy)
|
||||
(funcall policy lastcwd))
|
||||
((null lastcwd)
|
||||
default-directory)
|
||||
((eq policy 'last-project)
|
||||
(let ((cwd default-directory)
|
||||
(default-directory lastcwd))
|
||||
(if (doom-project-p)
|
||||
(doom-project-root)
|
||||
cwd)))
|
||||
((eq policy 'last)
|
||||
lastcwd)
|
||||
(t
|
||||
(warn "`+doom-dashboard-pwd-policy' has an invalid value of '%s'"
|
||||
policy)))))
|
||||
|
||||
;; widgets
|
||||
(defun doom-dashboard-widget--banner ()
|
||||
(mapc (lambda (line)
|
||||
(insert (propertize (+doom-dashboard-center +doom-dashboard--width line)
|
||||
(insert (propertize (+doom-dashboard--center +doom-dashboard--width line)
|
||||
'face 'font-lock-comment-face) " ")
|
||||
(insert "\n"))
|
||||
'("================= =============== =============== ======== ========"
|
||||
|
@ -160,17 +222,15 @@ whose dimensions may not be fully initialized by the time this is run."
|
|||
(insert
|
||||
"\n"
|
||||
(propertize
|
||||
(+doom-dashboard-center
|
||||
(+doom-dashboard--center
|
||||
+doom-dashboard--width
|
||||
(format "Loaded %d packages in %d modules in %.02fs"
|
||||
(- (length load-path) (length doom--base-load-path))
|
||||
(length doom--package-load-path)
|
||||
(hash-table-size doom-modules)
|
||||
(if (floatp doom-init-time) doom-init-time 0.0)))
|
||||
'face 'font-lock-comment-face)
|
||||
"\n"))
|
||||
|
||||
(defvar all-the-icons-scale-factor)
|
||||
(defvar all-the-icons-default-adjust)
|
||||
(defun doom-dashboard-widget--shortmenu ()
|
||||
(let ((all-the-icons-scale-factor 1.45)
|
||||
(all-the-icons-default-adjust -0.02))
|
||||
|
@ -184,7 +244,7 @@ whose dimensions may not be fully initialized by the time this is run."
|
|||
(propertize (concat " " label) 'face 'font-lock-keyword-face))
|
||||
'action `(lambda (_) ,fn)
|
||||
'follow-link t)
|
||||
(+doom-dashboard-center (- +doom-dashboard--width 2) (buffer-string)))
|
||||
(+doom-dashboard--center (- +doom-dashboard--width 2) (buffer-string)))
|
||||
"\n\n"))))
|
||||
`(("Homepage" "mark-github"
|
||||
(browse-url "https://github.com/hlissner/doom-emacs"))
|
||||
|
|
51
modules/ui/doom-dashboard/test/doom-dashboard.el
Normal file
51
modules/ui/doom-dashboard/test/doom-dashboard.el
Normal file
|
@ -0,0 +1,51 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; ui/doom-dashboard/test/doom-dashboard.el
|
||||
|
||||
(require! :ui doom-dashboard)
|
||||
(+doom-dashboard|init)
|
||||
|
||||
(defun -dashboard-test-pwd (spec file)
|
||||
(let ((kill-buffer-query-functions '(+doom-dashboard|reload-on-kill))
|
||||
(+doom-dashboard-pwd-policy (car spec))
|
||||
(fallback-buffer (doom-fallback-buffer))
|
||||
+doom-dashboard--last-cwd
|
||||
projectile-enable-caching)
|
||||
(with-temp-buffer
|
||||
(setq buffer-file-name file
|
||||
default-directory (file-name-directory file)
|
||||
doom-real-buffer-p t))
|
||||
(should +doom-dashboard--last-cwd)
|
||||
(+doom-dashboard-update-pwd)
|
||||
(should (equal (buffer-local-value 'default-directory fallback-buffer)
|
||||
(cdr spec)))))
|
||||
|
||||
;;
|
||||
(def-test! dashboard-p
|
||||
(let ((fallback-buffer (doom-fallback-buffer)))
|
||||
(should (equal (buffer-name fallback-buffer) +doom-dashboard-name))
|
||||
(should (+doom-dashboard-p fallback-buffer))
|
||||
(with-current-buffer fallback-buffer
|
||||
(should (+doom-dashboard-p)))))
|
||||
|
||||
(def-test! get-pwd
|
||||
(let ((default-directory doom-core-dir)
|
||||
(+doom-dashboard--last-cwd doom-core-dir)
|
||||
projectile-enable-caching)
|
||||
(dolist (spec (list (cons 'last-project doom-emacs-dir)
|
||||
(cons 'last doom-core-dir)
|
||||
(cons (lambda (x) "x") "x")
|
||||
(cons "~" (expand-file-name "~"))
|
||||
(cons nil default-directory)))
|
||||
(let ((+doom-dashboard-pwd-policy (car spec)))
|
||||
(should (equal (+doom-dashboard--get-pwd) (cdr spec)))))))
|
||||
|
||||
(def-test! pwd-policy
|
||||
(dolist (spec (list (cons 'last-project doom-emacs-dir)
|
||||
(cons 'last doom-core-dir)
|
||||
(cons "~" (expand-file-name "~/"))
|
||||
(cons (lambda (x) "/tmp") "/tmp/")))
|
||||
(-dashboard-test-pwd spec (expand-file-name "core.el" doom-core-dir))))
|
||||
|
||||
;;
|
||||
(def-test! inhibit-refresh :skip t)
|
||||
(def-test! inhibit-functions :skip t)
|
Loading…
Add table
Add a link
Reference in a new issue