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/
|
.cask/
|
||||||
var/
|
var/
|
||||||
/init.el
|
/init.el
|
||||||
|
modules/private/
|
||||||
|
|
||||||
# emacs tempfiles that shouldn't be there
|
# emacs tempfiles that shouldn't be there
|
||||||
.mc-lists.el
|
.mc-lists.el
|
||||||
|
|
|
@ -12,6 +12,91 @@
|
||||||
- [[#200-jan-17-2017][2.0.0 (Jan 17, 2017)]]
|
- [[#200-jan-17-2017][2.0.0 (Jan 17, 2017)]]
|
||||||
|
|
||||||
* Unreleased (develop)
|
* 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)
|
* 2.0.8 (Dec 09, 2017)
|
||||||
+ *Module changes:*
|
+ *Module changes:*
|
||||||
|
|
138
bin/doom-doctor
138
bin/doom-doctor
|
@ -8,6 +8,7 @@
|
||||||
;; In case it isn't defined (in really old versions of Emacs, like the one that
|
;; In case it isn't defined (in really old versions of Emacs, like the one that
|
||||||
;; ships with MacOS).
|
;; ships with MacOS).
|
||||||
(defvar user-emacs-directory (expand-file-name "~/.emacs.d/"))
|
(defvar user-emacs-directory (expand-file-name "~/.emacs.d/"))
|
||||||
|
(defvar doom-debug-mode (getenv "DEBUG"))
|
||||||
|
|
||||||
(unless (equal (expand-file-name user-emacs-directory)
|
(unless (equal (expand-file-name user-emacs-directory)
|
||||||
(expand-file-name "~/.emacs.d/"))
|
(expand-file-name "~/.emacs.d/"))
|
||||||
|
@ -15,14 +16,20 @@
|
||||||
|
|
||||||
(require 'pp)
|
(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-init-p nil)
|
||||||
(defvar doom-errors 0)
|
(defvar doom-errors 0)
|
||||||
(defmacro check! (cond &rest body)
|
(defmacro check! (cond &rest body)
|
||||||
(declare (indent defun))
|
(declare (indent defun))
|
||||||
`(when ,cond
|
`(let ((it ,cond))
|
||||||
|
(when it
|
||||||
,@body
|
,@body
|
||||||
(setq doom-errors (1+ doom-errors))))
|
(setq doom-errors (1+ doom-errors)))))
|
||||||
|
|
||||||
(defun indented (spc msg)
|
(defun indented (spc msg)
|
||||||
(declare (indent defun))
|
(declare (indent defun))
|
||||||
|
@ -57,26 +64,18 @@
|
||||||
"\n")))
|
"\n")))
|
||||||
(buffer-string)))
|
(buffer-string)))
|
||||||
|
|
||||||
(defmacro wait-for! (var if-body &optional else-body)
|
(defun sh (cmd)
|
||||||
(declare (indent defun))
|
(string-trim-right (shell-command-to-string cmd)))
|
||||||
`(let ((i 0))
|
|
||||||
(while (and (not ,var)
|
|
||||||
(< i 5))
|
|
||||||
(sleep-for 1)
|
|
||||||
(setq i (1+ i)))
|
|
||||||
(if ,var
|
|
||||||
,if-body
|
|
||||||
,else-body)))
|
|
||||||
|
|
||||||
(defun color (code msg &rest args)
|
(defun color (code msg &rest args)
|
||||||
(format "\e[%dm%s\e[%dm" code (apply #'format msg args) 0))
|
(format "\e[%dm%s\e[%dm" code (apply #'format msg args) 0))
|
||||||
|
|
||||||
(defalias 'msg! #'message)
|
(defalias 'msg! #'message)
|
||||||
(defmacro error! (&rest args) `(message (color 1 (color 31 ,@args))))
|
(defmacro error! (&rest args) `(msg! (color 1 (color 31 ,@args))))
|
||||||
(defmacro warn! (&rest args) `(message (color 1 (color 33 ,@args))))
|
(defmacro warn! (&rest args) `(msg! (color 1 (color 33 ,@args))))
|
||||||
(defmacro success! (&rest args) `(message (color 1 (color 32 ,@args))))
|
(defmacro success! (&rest args) `(msg! (color 1 (color 32 ,@args))))
|
||||||
(defmacro log! (&rest args) `(if doom-debug-mode (message (color 34 ,@args))))
|
(defmacro section! (&rest args) `(msg! (color 34 ,@args)))
|
||||||
(defmacro explain! (&rest args) `(message (indented 2 (autofill ,@args))))
|
(defmacro explain! (&rest args) `(msg! (indented 2 (autofill ,@args))))
|
||||||
|
|
||||||
;;; Polyfills
|
;;; Polyfills
|
||||||
;; early versions of emacs won't have this
|
;; early versions of emacs won't have this
|
||||||
|
@ -88,15 +87,21 @@
|
||||||
|
|
||||||
;; --- start a'doctorin' --------------------------------------
|
;; --- 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 "DOOM Doctor")
|
||||||
(color 1 emacs-version)
|
(color 1 emacs-version)
|
||||||
(if (executable-find "git")
|
(if (executable-find "git")
|
||||||
(shell-command-to-string "git rev-parse HEAD")
|
(sh "git rev-parse HEAD")
|
||||||
"n/a"))
|
"n/a"))
|
||||||
|
|
||||||
|
(msg! "shell: %s%s"
|
||||||
|
(getenv "SHELL")
|
||||||
|
(if (equal (getenv "SHELL") (sh "echo $SHELL"))
|
||||||
|
""
|
||||||
|
(color 31 " (mismatch)")))
|
||||||
(when (boundp 'system-configuration-features)
|
(when (boundp 'system-configuration-features)
|
||||||
(msg! "Compiled with:\n%s" (indented 2 (autofill 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)
|
(let (doom-core-packages doom-debug-mode)
|
||||||
(condition-case ex
|
(condition-case ex
|
||||||
|
@ -108,11 +113,10 @@
|
||||||
(doom|finalize)
|
(doom|finalize)
|
||||||
(success! "Attempt to load DOOM: success! Loaded v%s" doom-version)
|
(success! "Attempt to load DOOM: success! Loaded v%s" doom-version)
|
||||||
(when (executable-find "git")
|
(when (executable-find "git")
|
||||||
(msg! "Revision %s"
|
(msg! "Revision %s\n"
|
||||||
(or (ignore-errors
|
(ignore-errors
|
||||||
(let ((default-directory user-emacs-directory))
|
(let ((default-directory user-emacs-directory))
|
||||||
(shell-command-to-string "git rev-parse HEAD")))
|
(sh "git rev-parse HEAD"))))))
|
||||||
"\n"))))
|
|
||||||
('error (warn! "Attempt to load DOOM: failed\n %s\n"
|
('error (warn! "Attempt to load DOOM: failed\n %s\n"
|
||||||
(or (cdr-safe ex) (car ex))))))
|
(or (cdr-safe ex) (car ex))))))
|
||||||
|
|
||||||
|
@ -120,7 +124,7 @@
|
||||||
|
|
||||||
;; --- is emacs set up properly? ------------------------------
|
;; --- is emacs set up properly? ------------------------------
|
||||||
|
|
||||||
(log! "test-emacs")
|
(section! "test-emacs")
|
||||||
(check! (version< emacs-version "25.1")
|
(check! (version< emacs-version "25.1")
|
||||||
(error! "Important: Emacs %s detected [%s]" emacs-version (executable-find "emacs"))
|
(error! "Important: Emacs %s detected [%s]" emacs-version (executable-find "emacs"))
|
||||||
(explain!
|
(explain!
|
||||||
|
@ -133,13 +137,13 @@
|
||||||
;; --- is the environment set up properly? --------------------
|
;; --- is the environment set up properly? --------------------
|
||||||
|
|
||||||
;; windows? windows
|
;; windows? windows
|
||||||
(log! "test-windows")
|
(section! "test-windows")
|
||||||
(check! (memq system-type '(windows-nt ms-dos cygwin))
|
(check! (memq system-type '(windows-nt ms-dos cygwin))
|
||||||
(warn! "Warning: Windows detected")
|
(warn! "Warning: Windows detected")
|
||||||
(explain! "DOOM was designed for MacOS and Linux. Expect a bumpy ride!"))
|
(explain! "DOOM was designed for MacOS and Linux. Expect a bumpy ride!"))
|
||||||
|
|
||||||
;; are all default fonts present
|
;; are all default fonts present
|
||||||
(log! "test-fonts")
|
(section! "test-fonts")
|
||||||
(if (not (fboundp 'find-font))
|
(if (not (fboundp 'find-font))
|
||||||
(progn
|
(progn
|
||||||
(warn! "Warning: unable to detect font")
|
(warn! "Warning: unable to detect font")
|
||||||
|
@ -162,19 +166,19 @@
|
||||||
"case, ignore this warning."))))))
|
"case, ignore this warning."))))))
|
||||||
|
|
||||||
;; gnutls-cli & openssl
|
;; gnutls-cli & openssl
|
||||||
(log! "test-gnutls")
|
(section! "test-gnutls")
|
||||||
(cond ((executable-find "gnutls-cli"))
|
(cond ((executable-find "gnutls-cli"))
|
||||||
((executable-find "openssl")
|
((executable-find "openssl")
|
||||||
(let* ((output (shell-command-to-string "openssl ciphers -v"))
|
(let* ((output (sh "openssl ciphers -v"))
|
||||||
(protocols
|
(protocols
|
||||||
(let (protos)
|
(let (protos)
|
||||||
(mapcar (lambda (row)
|
(mapcar (lambda (row)
|
||||||
(add-to-list 'protos (cadr (split-string row " " t))))
|
(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))))
|
(delq nil protos))))
|
||||||
(check! (not (or (member "TLSv1.1" protocols)
|
(check! (not (or (member "TLSv1.1" protocols)
|
||||||
(member "TLSv1.2" 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)
|
(warn! "Warning: couldn't find gnutls-cli, and OpenSSL is out-of-date (v%s)" version)
|
||||||
(explain!
|
(explain!
|
||||||
"This may not affect your Emacs experience, but there are security "
|
"This may not affect your Emacs experience, but there are security "
|
||||||
|
@ -198,7 +202,7 @@
|
||||||
"network, provider, government, neckbearded mother-in-laws, geeky roommates, "
|
"network, provider, government, neckbearded mother-in-laws, geeky roommates, "
|
||||||
"or just about anyone who knows more about computers than you do!"))))
|
"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))
|
(cond ((not (string-match-p "\\_<GNUTLS\\_>" system-configuration-features))
|
||||||
(warn! "Warning: You didn't install Emacs with gnutls support")
|
(warn! "Warning: You didn't install Emacs with gnutls support")
|
||||||
(explain!
|
(explain!
|
||||||
|
@ -211,53 +215,50 @@
|
||||||
" brew tap d12frosted/emacs-plus"
|
" brew tap d12frosted/emacs-plus"
|
||||||
" brew install 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")
|
((or (executable-find "gnutls-cli")
|
||||||
(executable-find "openssl"))
|
(executable-find "openssl"))
|
||||||
(let ((tls-checktrust t)
|
(let ((tls-checktrust t)
|
||||||
(gnutls-verify-error t))
|
(gnutls-verify-error t))
|
||||||
(dolist (url '("https://elpa.gnu.org"
|
(dolist (url '("https://elpa.gnu.org" "https://melpa.org"))
|
||||||
"https://melpa.org"))
|
(check! (condition-case-unless-debug e
|
||||||
(condition-case-unless-debug ex
|
(if (let ((inhibit-message t)) (url-retrieve-synchronously url))
|
||||||
(let (result)
|
(ignore (success! "Validated %s" url))
|
||||||
(let ((inhibit-message t))
|
'empty)
|
||||||
(url-retrieve url (lambda (status &rest _) (setq result status))))
|
('timed-out 'timeout)
|
||||||
(wait-for! result
|
('error e))
|
||||||
(when (getenv "DEBUG")
|
(pcase it
|
||||||
(success! "Verified %s" (nth 2 (split-string url "/"))))
|
(`empty (error! "Couldn't reach %s" url))
|
||||||
(signal 'timed-out url)))
|
(`timeout (error! "Timed out trying to contact %s" ex))
|
||||||
('timed-out
|
(_
|
||||||
(error! "Timed out trying to contact %s" ex))
|
(error! "Failed to validate %s" url)
|
||||||
('error
|
(when doom-debug-mode
|
||||||
(check! t
|
(explain! (pp-to-string it)))))))
|
||||||
(error! "Rejected %s" url)
|
|
||||||
(explain! (pp-to-string ex))))))
|
|
||||||
(dolist (url '("https://self-signed.badssl.com"
|
(dolist (url '("https://self-signed.badssl.com"
|
||||||
"https://wrong.host.badssl.com/"))
|
"https://wrong.host.badssl.com/"))
|
||||||
(condition-case-unless-debug ex
|
(check! (condition-case-unless-debug e
|
||||||
(let (result)
|
(if (let ((inhibit-message t)) (url-retrieve-synchronously url))
|
||||||
(let ((inhibit-message t))
|
t
|
||||||
(url-retrieve url (lambda (status &rest _) (setq result status))))
|
'empty)
|
||||||
(wait-for! result
|
('timed-out 'timeout)
|
||||||
(check! t
|
('error (ignore (success! "Successfully rejected %s" url))))
|
||||||
(warn! "Verified %s (this shouldn't happen!)" (nth 2 (split-string url "/")))
|
(pcase it
|
||||||
(explain! (pp-to-string result)))
|
(`empty (error! "Couldn't reach %s" url))
|
||||||
(signal 'timed-out url)))
|
(`timeout (error! "Timed out trying to contact %s" ex))
|
||||||
('timed-out
|
(_
|
||||||
(error! "Timed out trying to contact %s" ex))
|
(error! "Validated %s (this shouldn't happen!)" url)))))))
|
||||||
('error
|
|
||||||
(when (getenv "DEBUG")
|
|
||||||
(success! "Rejected %s (a good thing!)" url)
|
|
||||||
(explain! (pp-to-string ex))))))))
|
|
||||||
|
|
||||||
(t
|
(t
|
||||||
(error! "Nope!")))
|
(error! "Nope!")))
|
||||||
|
|
||||||
;; bsd vs gnu tar
|
;; bsd vs gnu tar
|
||||||
(log! "test-tar")
|
(section! "test-tar")
|
||||||
(let ((tar-bin (or (executable-find "gtar")
|
(let ((tar-bin (or (executable-find "gtar")
|
||||||
(executable-find "tar"))))
|
(executable-find "tar"))))
|
||||||
(if tar-bin
|
(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")
|
(warn! "Warning: BSD tar detected")
|
||||||
(explain!
|
(explain!
|
||||||
"QUELPA (through package-build) uses the system tar to build plugins, but it "
|
"QUELPA (through package-build) uses the system tar to build plugins, but it "
|
||||||
|
@ -275,7 +276,7 @@
|
||||||
|
|
||||||
;; --- report! ------------------------------------------------
|
;; --- report! ------------------------------------------------
|
||||||
|
|
||||||
(when (getenv "DEBUG")
|
(when doom-debug-mode
|
||||||
(msg! "\n====\nHave some debug information:\n")
|
(msg! "\n====\nHave some debug information:\n")
|
||||||
|
|
||||||
(when (bound-and-true-p doom-modules)
|
(when (bound-and-true-p doom-modules)
|
||||||
|
@ -290,11 +291,12 @@
|
||||||
(msg! " + enabled packages:\n%s"
|
(msg! " + enabled packages:\n%s"
|
||||||
(indented 4
|
(indented 4
|
||||||
(columns 2 35
|
(columns 2 35
|
||||||
|
(delq nil
|
||||||
(mapcar (lambda (pkg)
|
(mapcar (lambda (pkg)
|
||||||
(let ((desc (cadr (assq pkg package-alist))))
|
(let ((desc (cadr (assq pkg package-alist))))
|
||||||
(when desc
|
(when desc
|
||||||
(package-desc-full-name desc))))
|
(package-desc-full-name desc))))
|
||||||
(sort (mapcar #'car doom-packages) #'string-lessp))))))
|
(sort (mapcar #'car doom-packages) #'string-lessp)))))))
|
||||||
|
|
||||||
(msg! " + byte-compiled files:\n%s"
|
(msg! " + byte-compiled files:\n%s"
|
||||||
(indented 4
|
(indented 4
|
||||||
|
@ -318,7 +320,7 @@
|
||||||
(success! "Everything seems fine, happy Emacs'ing!")
|
(success! "Everything seems fine, happy Emacs'ing!")
|
||||||
(message "\n----")
|
(message "\n----")
|
||||||
(warn! "There were issues!")
|
(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! "\nHopefully these can help you find problems. If not, run this doctor again with DEBUG=1:")
|
||||||
(msg! "\n DEBUG=1 make doctor\n")
|
(msg! "\n DEBUG=1 make doctor\n")
|
||||||
(msg! "And file a bug report with its output at https://github.com/hlissner/.emacs.d/issues")))
|
(msg! "And file a bug report with its output at https://github.com/hlissner/.emacs.d/issues")))
|
||||||
|
|
|
@ -4,8 +4,12 @@
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defvar doom-real-buffer-functions '()
|
(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
|
(defvar-local doom-real-buffer-p nil
|
||||||
"If non-nil, this buffer should be considered real no matter what.")
|
"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
|
"The name of the buffer to fall back to if no other buffers exist (will create
|
||||||
it if it doesn't exist).")
|
it if it doesn't exist).")
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Functions
|
||||||
|
;;
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom-fallback-buffer ()
|
(defun doom-fallback-buffer ()
|
||||||
"Returns the fallback buffer, creating it if necessary. By default this is the
|
"Returns the fallback buffer, creating it if necessary. By default this is the
|
||||||
scratch buffer."
|
scratch buffer."
|
||||||
(get-buffer-create doom-fallback-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
|
;;;###autoload
|
||||||
(defalias 'doom-buffer-list #'buffer-list)
|
(defalias 'doom-buffer-list #'buffer-list)
|
||||||
|
|
||||||
|
@ -66,6 +51,28 @@ If no project is active, return all buffers."
|
||||||
if (doom-real-buffer-p buf)
|
if (doom-real-buffer-p buf)
|
||||||
collect 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
|
;;;###autoload
|
||||||
(defun doom-buffers-in-mode (modes &optional buffer-list derived-p)
|
(defun doom-buffers-in-mode (modes &optional buffer-list derived-p)
|
||||||
"Return a list of buffers whose `major-mode' is `eq' to MODE(S).
|
"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
|
"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
|
buffers. If there's nothing left, switch to `doom-fallback-buffer'. See
|
||||||
`doom-real-buffer-p' for what 'real' means."
|
`doom-real-buffer-p' for what 'real' means."
|
||||||
(let ((buffers (delq (current-buffer) (doom-real-buffer-list)))
|
(let ((buffers (delq (current-buffer) (doom-real-buffer-list))))
|
||||||
(project-dir (doom-project-root)))
|
|
||||||
(cond ((or (not buffers)
|
(cond ((or (not buffers)
|
||||||
(zerop (% n (1+ (length buffers)))))
|
(zerop (% n (1+ (length buffers)))))
|
||||||
(switch-to-buffer (doom-fallback-buffer) nil t))
|
(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
|
do
|
||||||
(dotimes (_i (abs n))
|
(dotimes (_i (abs n))
|
||||||
(funcall move-func)))))
|
(funcall move-func)))))
|
||||||
(when (eq (current-buffer) (doom-fallback-buffer))
|
(force-mode-line-update)
|
||||||
(cd project-dir))
|
|
||||||
(current-buffer)))
|
(current-buffer)))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom-real-buffer-p (&optional buffer-or-name)
|
(defun doom-set-buffer-real (buffer flag)
|
||||||
"Returns t if BUFFER-OR-NAME is a 'real' buffer. The complete criteria for a
|
"Forcibly mark BUFFER as FLAG (non-nil = real)."
|
||||||
real buffer is:
|
(with-current-buffer buffer
|
||||||
|
(setq doom-real-buffer-p flag)))
|
||||||
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))
|
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom-kill-buffer (&optional buffer dont-save)
|
(defun doom-kill-buffer (&optional buffer dont-save)
|
||||||
"Kill BUFFER (falls back to current buffer if omitted) then switch to a real
|
"Kill BUFFER (defaults to current buffer), but make sure we land on a real
|
||||||
buffer. If the buffer is present in another window, only bury it.
|
buffer. Bury the buffer if the buffer is present in another window.
|
||||||
|
|
||||||
Will prompt to save unsaved buffers when attempting to kill them, unless
|
Will prompt to save unsaved buffers when attempting to kill them, unless
|
||||||
DONT-SAVE is non-nil.
|
DONT-SAVE is non-nil.
|
||||||
|
|
||||||
See `doom-real-buffer-p' for what 'real' means."
|
See `doom-real-buffer-p' for what 'real' means."
|
||||||
(setq buffer (or buffer (current-buffer)))
|
(unless buffer
|
||||||
(when (and (bufferp buffer) (buffer-live-p buffer))
|
(setq buffer (current-buffer)))
|
||||||
(let ((buffer-win (get-buffer-window buffer))
|
(when (and (bufferp buffer)
|
||||||
(only-buffer-window-p (= 1 (length (get-buffer-window-list buffer nil t)))))
|
(buffer-live-p buffer))
|
||||||
;; deal with unsaved buffers
|
(let ((buffer-win (get-buffer-window buffer)))
|
||||||
(when (and only-buffer-window-p
|
;; deal with modified buffers
|
||||||
(buffer-file-name buffer)
|
(when (and (buffer-file-name buffer)
|
||||||
(buffer-modified-p buffer))
|
(buffer-modified-p buffer))
|
||||||
(with-current-buffer buffer
|
(with-current-buffer buffer
|
||||||
(if (and (not dont-save)
|
(if (and (not dont-save)
|
||||||
(yes-or-no-p "Buffer is unsaved, save it?"))
|
(yes-or-no-p "Buffer is unsaved, save it?"))
|
||||||
(save-buffer)
|
(save-buffer)
|
||||||
(set-buffer-modified-p nil))))
|
(set-buffer-modified-p nil))))
|
||||||
(if buffer-win
|
;; kill the buffer (or close dedicated window)
|
||||||
;; deal with dedicated windows
|
(cond ((not buffer-win)
|
||||||
(if (window-dedicated-p buffer-win)
|
(kill-buffer buffer))
|
||||||
|
((window-dedicated-p buffer-win)
|
||||||
(unless (window--delete buffer-win t t)
|
(unless (window--delete buffer-win t t)
|
||||||
(split-window buffer-win)
|
(split-window buffer-win)
|
||||||
(window--delete buffer-win t t))
|
(window--delete buffer-win t t)))
|
||||||
;; cycle to a real buffer
|
(t ; cycle to a real buffer
|
||||||
(with-selected-window buffer-win
|
(with-selected-window buffer-win
|
||||||
(doom--cycle-real-buffers -1)
|
(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)))))
|
(kill-buffer buffer)))))
|
||||||
|
(not (eq (current-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))))))
|
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom-kill-buffer-and-windows (buffer)
|
(defun doom-kill-buffer-and-windows (buffer)
|
||||||
|
@ -229,23 +188,6 @@ switched to a real buffer."
|
||||||
(delete-window window)))
|
(delete-window window)))
|
||||||
(kill-buffer buffer))
|
(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
|
;;;###autoload
|
||||||
(defun doom-kill-matching-buffers (pattern &optional buffer-list)
|
(defun doom-kill-matching-buffers (pattern &optional buffer-list)
|
||||||
"Kill all buffers (in current workspace OR in BUFFER-LIST) that match the
|
"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))
|
(dolist (buf buffers (length buffers))
|
||||||
(doom-kill-buffer buf t))))
|
(doom-kill-buffer buf t))))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Interactive commands
|
||||||
|
;;
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom/kill-this-buffer ()
|
(defun doom/kill-this-buffer (&optional interactive-p)
|
||||||
"Use `doom-kill-buffer' on the current buffer."
|
"Use `doom-kill-buffer' on the current buffer."
|
||||||
(interactive)
|
(interactive (list 'interactive))
|
||||||
(when (and (not (doom-kill-buffer)) (called-interactively-p 'interactive))
|
(when (and (not (doom-kill-buffer)) interactive-p)
|
||||||
(message "Nowhere left to go!")))
|
(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
|
;;;###autoload
|
||||||
(defun doom/kill-all-buffers (&optional project-p)
|
(defun doom/kill-all-buffers (&optional project-p)
|
||||||
"Kill all buffers and closes their windows.
|
"Kill all buffers and closes their windows.
|
||||||
|
@ -305,18 +267,46 @@ project."
|
||||||
(message "Killed %s buffers" n))))
|
(message "Killed %s buffers" n))))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom/cleanup-buffers (&optional all-p)
|
(defun doom/cleanup-session (&optional all-p)
|
||||||
"Clean up buried and inactive process buffers in the current workspace."
|
"Clean up buried buries and orphaned processes in the current workspace. If
|
||||||
|
ALL-P (universal argument), clean them up globally."
|
||||||
(interactive "P")
|
(interactive "P")
|
||||||
|
(run-hooks 'doom-cleanup-hook)
|
||||||
(let ((buffers (doom-buried-buffers (if all-p (buffer-list))))
|
(let ((buffers (doom-buried-buffers (if all-p (buffer-list))))
|
||||||
(n 0))
|
(n 0)
|
||||||
|
kill-buffer-query-functions)
|
||||||
(mapc #'kill-buffer buffers)
|
(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)
|
(when (called-interactively-p 'interactive)
|
||||||
(message "Cleaned up %s buffers" n))))
|
(message "Cleaned up %s buffers" n))))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom-set-buffer-real (buffer flag)
|
(defun doom/cleanup-processes ()
|
||||||
"Forcibly mark a buffer's real property, no matter what."
|
"Kill all processes that have no visible associated buffers. Return number of
|
||||||
(with-current-buffer buffer
|
processes killed."
|
||||||
(setq doom-real-buffer-p flag)))
|
(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/"
|
in '("https://wrong.host.badssl.com/"
|
||||||
"https://self-signed.badssl.com/")
|
"https://self-signed.badssl.com/")
|
||||||
if (condition-case _e
|
if (condition-case _e
|
||||||
(url-retrieve bad (lambda (_retrieved) t))
|
(url-retrieve-synchronously bad)
|
||||||
(error nil))
|
(error nil))
|
||||||
collect bad)))
|
collect bad)))
|
||||||
(error (format "tls seems to be misconfigured (it got %s)."
|
(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-report)
|
||||||
(profiler-stop))
|
(profiler-stop))
|
||||||
(setq doom--profiler (not doom--profiler)))
|
(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
|
;;;###autoload
|
||||||
(defun doom/sudo-find-file (file)
|
(defun doom/sudo-find-file (file)
|
||||||
"Open a file as root."
|
"Open FILE as root."
|
||||||
(interactive
|
(interactive
|
||||||
(list (read-file-name "Open as root: ")))
|
(list (read-file-name "Open as root: ")))
|
||||||
(find-file (if (file-writable-p file)
|
(find-file (if (file-writable-p file)
|
||||||
|
@ -218,8 +218,29 @@ consistent throughout a selected region, depending on `indent-tab-mode'."
|
||||||
(tabify beg end)
|
(tabify beg end)
|
||||||
(untabify 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
|
;;;###autoload
|
||||||
(defun doom|enable-delete-trailing-whitespace ()
|
(defun doom|enable-delete-trailing-whitespace ()
|
||||||
"Attaches `delete-trailing-whitespace' to a buffer-local `before-save-hook'."
|
"Attaches `delete-trailing-whitespace' to a buffer-local `before-save-hook'."
|
||||||
(add-hook 'before-save-hook #'delete-trailing-whitespace nil t))
|
(add-hook 'before-save-hook #'delete-trailing-whitespace nil t))
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
;;; core/autoload/packages.el -*- lexical-binding: t; -*-
|
;;; core/autoload/packages.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
(require 'use-package)
|
||||||
|
(require 'quelpa)
|
||||||
|
|
||||||
(defvar doom--last-refresh nil)
|
(defvar doom--last-refresh nil)
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom-refresh-packages (&optional force-p)
|
(defun doom-refresh-packages (&optional force-p)
|
||||||
"Refresh ELPA packages."
|
"Refresh ELPA packages."
|
||||||
(doom-initialize)
|
|
||||||
(when force-p
|
(when force-p
|
||||||
(doom-refresh-clear-cache))
|
(doom-refresh-clear-cache))
|
||||||
(unless (or (persistent-soft-fetch 'last-pkg-refresh "emacs")
|
(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
|
"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."
|
quelpa. Throws an error if NOERROR is nil and the package isn't installed."
|
||||||
(cl-assert (symbolp name) t)
|
(cl-assert (symbolp name) t)
|
||||||
(doom-initialize)
|
|
||||||
(cond ((and (or (quelpa-setup-p)
|
(cond ((and (or (quelpa-setup-p)
|
||||||
(error "Could not initialize quelpa"))
|
(error "Could not initialize quelpa"))
|
||||||
(assq name quelpa-cache))
|
(assq name quelpa-cache))
|
||||||
'quelpa)
|
'quelpa)
|
||||||
((assq name package-alist)
|
((assq name package-alist)
|
||||||
'elpa)
|
'elpa)
|
||||||
|
((package-built-in-p name)
|
||||||
|
'emacs)
|
||||||
((not noerror)
|
((not noerror)
|
||||||
(error "%s package is not installed" name))))
|
(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)
|
(doom-initialize-packages)
|
||||||
(and (package-installed-p name)
|
(and (package-installed-p name)
|
||||||
(let* ((plist (cdr (assq name doom-packages)))
|
(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)))
|
(new-backend (if (plist-get plist :recipe) 'quelpa 'elpa)))
|
||||||
(not (eq old-backend new-backend)))))
|
(not (eq old-backend new-backend)))))
|
||||||
|
|
||||||
|
@ -114,14 +117,12 @@ If INSTALLED-ONLY-P, only return packages that are installed."
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom-get-depending-on (name)
|
(defun doom-get-depending-on (name)
|
||||||
"Return a list of packages that depend on the package named NAME."
|
"Return a list of packages that depend on the package named NAME."
|
||||||
(doom-initialize)
|
|
||||||
(when-let* ((desc (cadr (assq name package-alist))))
|
(when-let* ((desc (cadr (assq name package-alist))))
|
||||||
(mapcar #'package-desc-name (package--used-elsewhere-p desc nil t))))
|
(mapcar #'package-desc-name (package--used-elsewhere-p desc nil t))))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom-get-dependencies-for (name &optional only)
|
(defun doom-get-dependencies-for (name &optional only)
|
||||||
"Return a list of dependencies for a package."
|
"Return a list of dependencies for a package."
|
||||||
(doom-initialize)
|
|
||||||
(package--get-deps name only))
|
(package--get-deps name only))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
|
@ -156,8 +157,9 @@ Used by `doom//packages-update'."
|
||||||
(load ,(expand-file-name "core.el" doom-core-dir)))
|
(load ,(expand-file-name "core.el" doom-core-dir)))
|
||||||
(doom-package-outdated-p ',pkg)))
|
(doom-package-outdated-p ',pkg)))
|
||||||
futures))
|
futures))
|
||||||
(append (delq nil (mapcar #'doom-package-outdated-p elpa-pkgs))
|
(delq nil
|
||||||
(delq nil (mapcar #'async-get (reverse futures)))))))
|
(append (mapcar #'doom-package-outdated-p elpa-pkgs)
|
||||||
|
(mapcar #'async-get (reverse futures)))))))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom-get-orphaned-packages ()
|
(defun doom-get-orphaned-packages ()
|
||||||
|
@ -170,7 +172,8 @@ Used by `doom//packages-autoremove'."
|
||||||
(append (mapcar #'car doom-packages) doom-core-packages)))
|
(append (mapcar #'car doom-packages) doom-core-packages)))
|
||||||
(append (package--removable-packages)
|
(append (package--removable-packages)
|
||||||
(cl-loop for pkg in package-selected-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))))
|
collect pkg))))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
|
@ -213,7 +216,6 @@ Used by `doom//packages-install'."
|
||||||
(symbol-name (car other))))
|
(symbol-name (car other))))
|
||||||
|
|
||||||
(defun doom--packages-choose (prompt)
|
(defun doom--packages-choose (prompt)
|
||||||
(doom-initialize)
|
|
||||||
(let ((table (cl-loop for pkg in package-alist
|
(let ((table (cl-loop for pkg in package-alist
|
||||||
unless (package-built-in-p (cdr pkg))
|
unless (package-built-in-p (cdr pkg))
|
||||||
collect (cons (package-desc-full-name (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)
|
(defun doom-update-package (name &optional force-p)
|
||||||
"Updates package NAME (a symbol) if it is out of date, using quelpa or
|
"Updates package NAME (a symbol) if it is out of date, using quelpa or
|
||||||
package.el as appropriate."
|
package.el as appropriate."
|
||||||
(doom-initialize)
|
|
||||||
(unless (package-installed-p name)
|
(unless (package-installed-p name)
|
||||||
(user-error "%s isn't installed" name))
|
(user-error "%s isn't installed" name))
|
||||||
(when (doom-package-different-backend-p name)
|
(when (doom-package-different-backend-p name)
|
||||||
|
@ -298,7 +299,6 @@ package.el as appropriate."
|
||||||
|
|
||||||
(defun doom-delete-package (name &optional force-p)
|
(defun doom-delete-package (name &optional force-p)
|
||||||
"Uninstalls package NAME if it exists, and clears it from `quelpa-cache'."
|
"Uninstalls package NAME if it exists, and clears it from `quelpa-cache'."
|
||||||
(doom-initialize)
|
|
||||||
(unless (package-installed-p name)
|
(unless (package-installed-p name)
|
||||||
(user-error "%s isn't installed" name))
|
(user-error "%s isn't installed" name))
|
||||||
(let ((inhibit-message (not doom-debug-mode))
|
(let ((inhibit-message (not doom-debug-mode))
|
||||||
|
@ -318,13 +318,14 @@ package.el as appropriate."
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Interactive commands
|
;; Batch/interactive commands
|
||||||
;;
|
;;
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom//packages-install ()
|
(defun doom//packages-install ()
|
||||||
"Interactive command for installing missing packages."
|
"Interactive command for installing missing packages."
|
||||||
(interactive)
|
(interactive)
|
||||||
|
(message! "Looking for packages to install...")
|
||||||
(let ((packages (doom-get-missing-packages)))
|
(let ((packages (doom-get-missing-packages)))
|
||||||
(cond ((not packages)
|
(cond ((not packages)
|
||||||
(message! (green "No packages to install!")))
|
(message! (green "No packages to install!")))
|
||||||
|
@ -354,20 +355,20 @@ package.el as appropriate."
|
||||||
(dolist (pkg packages)
|
(dolist (pkg packages)
|
||||||
(message! "Installing %s" (car pkg))
|
(message! "Installing %s" (car pkg))
|
||||||
(doom--condition-case!
|
(doom--condition-case!
|
||||||
(message! " %s%s"
|
(message! "%s%s"
|
||||||
(cond ((and (package-installed-p (car pkg))
|
(cond ((and (package-installed-p (car pkg))
|
||||||
(not (doom-package-different-backend-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))
|
((doom-install-package (car pkg) (cdr pkg))
|
||||||
(green "DONE"))
|
(green "✓ DONE"))
|
||||||
(t
|
(t
|
||||||
(red "FAILED")))
|
(red "✕ FAILED")))
|
||||||
(if (plist-member (cdr pkg) :pin)
|
(if (plist-member (cdr pkg) :pin)
|
||||||
(format " [pinned: %s]" (plist-get (cdr pkg) :pin))
|
(format " [pinned: %s]" (plist-get (cdr pkg) :pin))
|
||||||
"")))))
|
""))))
|
||||||
|
|
||||||
(message! (bold (green "Finished!")))
|
(message! (bold (green "Finished!")))
|
||||||
(doom//reload-load-path))))
|
(doom//reload-load-path)))))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom//packages-update ()
|
(defun doom//packages-update ()
|
||||||
|
@ -404,8 +405,7 @@ package.el as appropriate."
|
||||||
(message!
|
(message!
|
||||||
(let ((result (doom-update-package (car pkg) t)))
|
(let ((result (doom-update-package (car pkg) t)))
|
||||||
(color (if result 'green 'red)
|
(color (if result 'green 'red)
|
||||||
" %s"
|
(if result "✓ DONE" "✕ FAILED"))))))
|
||||||
(if result "DONE" "FAILED"))))))
|
|
||||||
|
|
||||||
(message! (bold (green "Finished!")))
|
(message! (bold (green "Finished!")))
|
||||||
(doom//reload-load-path)))))
|
(doom//reload-load-path)))))
|
||||||
|
@ -414,27 +414,26 @@ package.el as appropriate."
|
||||||
(defun doom//packages-autoremove ()
|
(defun doom//packages-autoremove ()
|
||||||
"Interactive command for auto-removing orphaned packages."
|
"Interactive command for auto-removing orphaned packages."
|
||||||
(interactive)
|
(interactive)
|
||||||
|
(message! "Looking for orphaned packages...")
|
||||||
(let ((packages (doom-get-orphaned-packages)))
|
(let ((packages (doom-get-orphaned-packages)))
|
||||||
(cond ((not packages)
|
(cond ((not packages)
|
||||||
(message! (green "No unused packages to remove")))
|
(message! (green "No unused packages to remove")))
|
||||||
|
|
||||||
((not (or (getenv "YES")
|
((not
|
||||||
|
(or (getenv "YES")
|
||||||
(y-or-n-p
|
(y-or-n-p
|
||||||
(format "%s packages will be deleted:\n\n%s\n\nProceed?"
|
(format
|
||||||
|
"%s packages will be deleted:\n\n%s\n\nProceed?"
|
||||||
(length packages)
|
(length packages)
|
||||||
(mapconcat
|
(mapconcat
|
||||||
(lambda (sym)
|
(lambda (sym)
|
||||||
(format
|
(format "+ %s (%s)" sym
|
||||||
"+ %s (%s)"
|
|
||||||
sym
|
|
||||||
(let ((backend (doom-package-backend sym)))
|
(let ((backend (doom-package-backend sym)))
|
||||||
(if (doom-package-different-backend-p sym)
|
(if (doom-package-different-backend-p sym)
|
||||||
(if (eq backend 'quelpa)
|
(if (eq backend 'quelpa)
|
||||||
"QUELPA->ELPA"
|
"QUELPA->ELPA"
|
||||||
"ELPA->QUELPA")
|
"ELPA->QUELPA")
|
||||||
(if (eq backend 'quelpa)
|
(upcase (symbol-name backend))))))
|
||||||
"QUELPA"
|
|
||||||
"ELPA")))))
|
|
||||||
(sort (cl-copy-list packages) #'string-lessp)
|
(sort (cl-copy-list packages) #'string-lessp)
|
||||||
"\n")))))
|
"\n")))))
|
||||||
(message! (yellow "Aborted!")))
|
(message! (yellow "Aborted!")))
|
||||||
|
@ -446,13 +445,17 @@ package.el as appropriate."
|
||||||
(let ((result (doom-delete-package pkg t)))
|
(let ((result (doom-delete-package pkg t)))
|
||||||
(color (if result 'green 'red)
|
(color (if result 'green 'red)
|
||||||
"%s %s"
|
"%s %s"
|
||||||
(if result "Removed" "Failed to remove")
|
(if result "✓ Removed" "✕ Failed to remove")
|
||||||
pkg)))))
|
pkg)))))
|
||||||
|
|
||||||
(message! (bold (green "Finished!")))
|
(message! (bold (green "Finished!")))
|
||||||
(doom//reload-load-path)))))
|
(doom//reload-load-path)))))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Interactive commands
|
||||||
|
;;
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defalias 'doom/install-package #'package-install)
|
(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 (package-installed-p package)
|
||||||
(if (y-or-n-p (format "%s will be deleted. Confirm?" package))
|
(if (y-or-n-p (format "%s will be deleted. Confirm?" package))
|
||||||
(message "%s %s"
|
(message "%s %s"
|
||||||
(if (doom-delete-package package t) "Deleted" "Failed to delete")
|
(if (doom-delete-package package t)
|
||||||
|
"Deleted"
|
||||||
|
"Failed to delete")
|
||||||
package)
|
package)
|
||||||
(message "Aborted"))
|
(message "Aborted"))
|
||||||
(message "%s isn't installed" package))))
|
(message "%s isn't installed" package))))
|
||||||
|
|
|
@ -239,7 +239,7 @@ without leaving any trace behind (muahaha)."
|
||||||
(if (featurep 'evil)
|
(if (featurep 'evil)
|
||||||
#'evil-force-normal-state
|
#'evil-force-normal-state
|
||||||
#'keyboard-quit))
|
#'keyboard-quit))
|
||||||
(delete-window)))
|
(quit-restore-window nil 'kill)))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom/popup-this-buffer ()
|
(defun doom/popup-this-buffer ()
|
||||||
|
@ -413,12 +413,4 @@ properties."
|
||||||
(when (doom-popup-p window)
|
(when (doom-popup-p window)
|
||||||
(setq doom-popup-windows (delq window doom-popup-windows))
|
(setq doom-popup-windows (delq window doom-popup-windows))
|
||||||
(when doom-popup-remember-history
|
(when doom-popup-remember-history
|
||||||
(setq doom-popup-history (list (doom--popup-data window))))
|
(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)))))))
|
|
||||||
|
|
|
@ -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,
|
Requires the corresponding client, e.g. git for git repos, hg for mercurial,
|
||||||
etc."
|
etc."
|
||||||
(let* ((command (pcase fetcher
|
(let* ((command (pcase fetcher
|
||||||
(:github "git clone --depth 1 --recursive https://github.com/%s.git")
|
(:github "git clone --recursive https://github.com/%s.git")
|
||||||
(:git "git clone --depth 1 --recursive %s")
|
(:git "git clone --recursive %s")
|
||||||
(:gist "git clone https://gist.github.com/%s.git")
|
(:gist "git clone https://gist.github.com/%s.git")
|
||||||
;; TODO Add hg
|
;; TODO Add hg
|
||||||
(_ (error "%s is not a valid fetcher" fetcher))))
|
(_ (error "%s is not a valid fetcher" fetcher))))
|
||||||
|
@ -61,8 +61,8 @@ etc."
|
||||||
(error "%s couldn't be found" command))
|
(error "%s couldn't be found" command))
|
||||||
(unless (file-directory-p dest)
|
(unless (file-directory-p dest)
|
||||||
(funcall (if noninteractive
|
(funcall (if noninteractive
|
||||||
(lambda (&rest args) (princ (shell-command-to-string args)))
|
(lambda (c) (princ (shell-command-to-string c)))
|
||||||
#'async-shell-command)
|
#'async-shell-command)
|
||||||
(format "%s %s %s" bin args (shell-quote-argument dest)))
|
(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)
|
(defmacro def-test! (name &rest body)
|
||||||
"Define a namespaced ERT test."
|
"Define a namespaced ERT test."
|
||||||
(declare (indent defun) (doc-string 2))
|
(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
|
`(ert-deftest
|
||||||
,(cl-loop with path = (file-relative-name (file-name-sans-extension load-file-name)
|
,(cl-loop with path = (file-relative-name (file-name-sans-extension load-file-name)
|
||||||
doom-emacs-dir)
|
doom-emacs-dir)
|
||||||
for (rep . with) in '(("/test/" . "/") ("/" . ":"))
|
for (rep . with) in '(("/test/" . "/") ("/" . ":"))
|
||||||
do (setq path (replace-regexp-in-string rep with path t t))
|
do (setq path (replace-regexp-in-string rep with path t t))
|
||||||
finally return (intern (format "%s::%s" path name))) ()
|
finally return (intern (format "%s::%s" path name)))
|
||||||
()
|
()
|
||||||
,@body)))
|
(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.
|
"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
|
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)
|
(lambda (m1 m2) (< (marker-position m1)
|
||||||
(marker-position m2))))
|
(marker-position m2))))
|
||||||
(when (equal (caar marker-list) "0")
|
(when (equal (caar marker-list) "0")
|
||||||
(goto-char! 0)))
|
(goto-char!! 0)))
|
||||||
,@body
|
,@body
|
||||||
(let ((result-text (buffer-substring-no-properties (point-min) (point-max)))
|
(let ((result-text (buffer-substring-no-properties (point-min) (point-max)))
|
||||||
(point (point))
|
(point (point))
|
||||||
|
@ -130,15 +145,22 @@ against."
|
||||||
(should (equal expected-text result-text))
|
(should (equal expected-text result-text))
|
||||||
(should same-point)))))))
|
(should same-point)))))))
|
||||||
|
|
||||||
(defmacro goto-char! (index)
|
(defmacro goto-char!! (index)
|
||||||
"Meant to be used with `should-buffer!'. Will move the cursor to one of the
|
"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)."
|
cursor markers. e.g. Go to marker {2} with (goto-char!! 2)."
|
||||||
`(goto-char (point! ,index)))
|
`(goto-char (point!! ,index)))
|
||||||
|
|
||||||
(defmacro point! (index)
|
(defmacro point!! (index)
|
||||||
"Meant to be used with `should-buffer!'. Returns the position of a cursor
|
"Meant to be used with `should-buffer!!'. Returns the position of a cursor
|
||||||
marker. e.g. {2} can be retrieved with (point! 2)."
|
marker. e.g. {2} can be retrieved with (point!! 2)."
|
||||||
`(cdr (assoc ,(cond ((numberp index) (number-to-string index))
|
`(cdr (assoc ,(cond ((numberp index) (number-to-string index))
|
||||||
((symbolp index) (symbol-name index))
|
((symbolp index) (symbol-name index))
|
||||||
((stringp index) index))
|
((stringp index) index))
|
||||||
marker-list)))
|
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))))
|
(ignore (bury-buffer))))
|
||||||
(add-hook 'kill-buffer-query-functions #'doom|dont-kill-scratch-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 ()
|
(defun doom|check-large-file ()
|
||||||
"Check if the buffer's file is large (see `doom-large-file-size'). If so, ask
|
"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
|
for confirmation to open it literally (read-only, disabled undo and in
|
||||||
|
@ -75,43 +81,6 @@ fundamental-mode) for performance sake."
|
||||||
(fundamental-mode))))
|
(fundamental-mode))))
|
||||||
(add-hook 'find-file-hook #'doom|check-large-file)
|
(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)
|
(push '("/LICENSE$" . text-mode) auto-mode-alist)
|
||||||
|
|
||||||
|
|
||||||
|
@ -138,16 +107,15 @@ with functions that require it (like modeline segments)."
|
||||||
(def-package! recentf
|
(def-package! recentf
|
||||||
:hook (doom-init . recentf-mode)
|
:hook (doom-init . recentf-mode)
|
||||||
:config
|
: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-menu-items 0
|
||||||
recentf-max-saved-items 300
|
recentf-max-saved-items 300
|
||||||
|
recentf-filename-handlers '(file-truename)
|
||||||
recentf-exclude
|
recentf-exclude
|
||||||
(list "^/tmp/" "^/ssh:" "\\.?ido\\.last$" "\\.revive$" "/TAGS$"
|
(list "^/tmp/" "^/ssh:" "\\.?ido\\.last$" "\\.revive$" "/TAGS$"
|
||||||
"^/var/folders/.+$"
|
"^/var/folders/.+$"
|
||||||
;; ignore private DOOM temp files (but not all of them)
|
;; ignore private DOOM temp files (but not all of them)
|
||||||
(concat "^" (replace-regexp-in-string
|
(concat "^" (file-truename doom-local-dir)))))
|
||||||
(concat "@" (regexp-quote (system-name)))
|
|
||||||
"@" (abbreviate-file-name doom-host-dir))))))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
@ -206,8 +174,8 @@ extension, try to guess one."
|
||||||
|
|
||||||
;; Auto-close delimiters and blocks as you type
|
;; Auto-close delimiters and blocks as you type
|
||||||
(def-package! smartparens
|
(def-package! smartparens
|
||||||
|
:hook (doom-init . smartparens-global-mode)
|
||||||
:config
|
:config
|
||||||
(add-hook 'doom-init-hook #'smartparens-global-mode)
|
|
||||||
(require 'smartparens-config)
|
(require 'smartparens-config)
|
||||||
|
|
||||||
(setq sp-autowrap-region nil ; let evil-surround handle this
|
(setq sp-autowrap-region nil ; let evil-surround handle this
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
;;; core-lib.el -*- lexical-binding: t; -*-
|
;;; core-lib.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
(require 'cl-lib)
|
|
||||||
(require 'subr-x)
|
(require 'subr-x)
|
||||||
(load "async-autoloads" nil t)
|
(load "async-autoloads" nil t)
|
||||||
(load "persistent-soft-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
|
"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.")
|
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
|
(defvar doom-init-time nil
|
||||||
"The time it took, in seconds, for DOOM Emacs to initialize.")
|
"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.")
|
"The load path of built in Emacs libraries.")
|
||||||
|
|
||||||
(defvar doom--package-load-path ()
|
(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
|
(defvar doom--base-load-path
|
||||||
(append (list doom-core-dir doom-modules-dir)
|
(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
|
If you byte-compile core/core.el, this function will be avoided to speed up
|
||||||
startup."
|
startup."
|
||||||
;; Called early during initialization; only use native functions!
|
;; Called early during initialization; only use native (and cl-lib) functions!
|
||||||
(when (or (not doom-package-init-p) force-p)
|
(when (or force-p (not doom-init-p))
|
||||||
(setq load-path doom--base-load-path
|
;; Speed things up with a `load-path' for only the bare essentials
|
||||||
package-activated-list nil)
|
(let ((load-path doom--base-load-path))
|
||||||
;; Ensure core folders exist
|
;; Ensure core folders exist, otherwise we get errors
|
||||||
(dolist (dir (list doom-local-dir doom-etc-dir doom-cache-dir package-user-dir))
|
(dolist (dir (list doom-local-dir doom-etc-dir doom-cache-dir doom-packages-dir))
|
||||||
(unless (file-directory-p dir)
|
(unless (file-directory-p dir)
|
||||||
(make-directory dir t)))
|
(make-directory dir t)))
|
||||||
|
;; Ensure package.el is initialized; we use its state
|
||||||
|
(setq package-activated-list nil)
|
||||||
(condition-case _ (package-initialize t)
|
(condition-case _ (package-initialize t)
|
||||||
('error
|
('error (package-refresh-contents)
|
||||||
(package-refresh-contents)
|
|
||||||
(setq doom--refreshed-p t)
|
(setq doom--refreshed-p t)
|
||||||
(package-initialize 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
|
;; We could let `package-initialize' fill `load-path', but it does more than
|
||||||
;; that alone (like load autoload files). If you want something prematurely
|
;; that alone (like load autoload files). If you want something prematurely
|
||||||
;; optimizated right, ya gotta do it yourself.
|
;; optimizated right, ya gotta do it yourself.
|
||||||
|
@ -155,23 +168,7 @@ startup."
|
||||||
;; Also, in some edge cases involving package initialization during a
|
;; Also, in some edge cases involving package initialization during a
|
||||||
;; non-interactive session, `package-initialize' fails to fill `load-path'.
|
;; non-interactive session, `package-initialize' fails to fill `load-path'.
|
||||||
(setq doom--package-load-path (directory-files package-user-dir t "^[^.]" t)
|
(setq doom--package-load-path (directory-files package-user-dir t "^[^.]" t)
|
||||||
load-path (append load-path doom--package-load-path))
|
load-path (append doom--base-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"))))
|
|
||||||
|
|
||||||
(defun doom-initialize-autoloads ()
|
(defun doom-initialize-autoloads ()
|
||||||
"Ensures that `doom-autoload-file' exists and is loaded. Otherwise run
|
"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.
|
If FORCE-P is non-nil, do it even if they are.
|
||||||
|
|
||||||
This aggressively reloads core autoload files."
|
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
|
(with-temp-buffer ; prevent buffer-local settings from propagating
|
||||||
(let ((noninteractive t)
|
(cl-flet
|
||||||
(load-prefer-newer t)
|
((_load
|
||||||
(load-fn
|
(file &optional noerror interactive)
|
||||||
(lambda (file &optional noerror)
|
|
||||||
(condition-case-unless-debug ex
|
(condition-case-unless-debug ex
|
||||||
(load file noerror :nomessage :nosuffix)
|
(let ((load-prefer-newer t)
|
||||||
|
(noninteractive (not interactive)))
|
||||||
|
(load file noerror :nomessage :nosuffix))
|
||||||
('error
|
('error
|
||||||
(error (format "(doom-initialize-packages) %s in %s: %s"
|
(lwarn 'doom-initialize-packages :warning
|
||||||
|
"%s in %s: %s"
|
||||||
(car ex)
|
(car ex)
|
||||||
(file-relative-name file doom-emacs-dir)
|
(file-relative-name file doom-emacs-dir)
|
||||||
(error-message-string ex))
|
(error-message-string ex))))))
|
||||||
:error))))))
|
|
||||||
(when (or force-p (not doom-modules))
|
(when (or force-p (not doom-modules))
|
||||||
(setq doom-modules nil)
|
(setq doom-modules nil
|
||||||
(let (noninteractive)
|
doom-packages nil)
|
||||||
(load (concat doom-core-dir "core.el") nil t))
|
(_load (concat doom-core-dir "core.el") nil 'interactive)
|
||||||
(funcall load-fn (expand-file-name "init.el" doom-emacs-dir))
|
(_load (expand-file-name "init.el" doom-emacs-dir))
|
||||||
(when load-p
|
(when load-p
|
||||||
(let (noninteractive)
|
(mapc #'_load (file-expand-wildcards (expand-file-name "autoload/*.el" doom-core-dir)))
|
||||||
(funcall load-fn (doom-module-path :private user-login-name "init.el") t))
|
(_load (expand-file-name "init.el" doom-emacs-dir) nil 'interactive)))
|
||||||
(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))))
|
|
||||||
(when (or force-p (not doom-packages))
|
(when (or force-p (not doom-packages))
|
||||||
(setq doom-packages nil)
|
(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)
|
(cl-loop for (module . submodule) in (doom-module-pairs)
|
||||||
for path = (doom-module-path module submodule "packages.el")
|
for path = (doom-module-path module submodule "packages.el")
|
||||||
do (funcall load-fn path t)))))
|
do (_load path 'noerror))))))
|
||||||
(doom|finalize))
|
|
||||||
|
|
||||||
(defun doom-initialize-modules (modules)
|
(defun doom-initialize-modules (modules)
|
||||||
"Adds MODULES to `doom-modules'. MODULES must be in mplist format.
|
"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
|
;; Certainly imprecise, especially where custom additions to
|
||||||
;; load-path are concerned, but I don't mind a [small] margin of
|
;; load-path are concerned, but I don't mind a [small] margin of
|
||||||
;; error in the plugin count in exchange for faster startup.
|
;; 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)
|
(hash-table-size doom-modules)
|
||||||
(setq doom-init-time (float-time (time-subtract after-init-time before-init-time)))))
|
(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)
|
(doom-initialize-modules modules)
|
||||||
`(let (file-name-handler-alist)
|
`(let (file-name-handler-alist)
|
||||||
(setq doom-modules ',doom-modules)
|
(setq doom-modules ',doom-modules)
|
||||||
|
|
||||||
(unless noninteractive
|
(unless noninteractive
|
||||||
|
(message "Doom initialized")
|
||||||
,@(cl-loop for (module . submodule) in (doom-module-pairs)
|
,@(cl-loop for (module . submodule) in (doom-module-pairs)
|
||||||
for module-path = (doom-module-path module submodule)
|
for module-path = (doom-module-path module submodule)
|
||||||
collect `(load! init ,module-path t) into inits
|
collect `(load! init ,module-path t) into inits
|
||||||
collect `(load! config ,module-path t) into configs
|
collect `(load! config ,module-path t) into configs
|
||||||
finally return (append inits configs))
|
finally return (append inits configs))
|
||||||
|
|
||||||
(when (display-graphic-p)
|
(when (display-graphic-p)
|
||||||
(require 'server)
|
(require 'server)
|
||||||
(unless (server-running-p)
|
(unless (server-running-p)
|
||||||
(server-start)))
|
(server-start)))
|
||||||
|
|
||||||
(add-hook 'doom-init-hook #'doom-packages--display-benchmark t)
|
(add-hook 'doom-init-hook #'doom-packages--display-benchmark t)
|
||||||
(message "Doom modules initialized"))))
|
(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'
|
;; Ignore package if NAME is in `doom-disabled-packages'
|
||||||
(when (and (memq name doom-disabled-packages)
|
(when (and (memq name doom-disabled-packages)
|
||||||
(not (memq :disabled plist)))
|
(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.
|
;; If byte-compiling, ignore this package if it doesn't meet the condition.
|
||||||
;; This avoids false-positive load errors.
|
;; This avoids false-positive load errors.
|
||||||
(unless (and (bound-and-true-p byte-compile-current-file)
|
(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').
|
"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
|
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
|
where to look for the file (a string representing a directory path). If omitted,
|
||||||
it is relative to `load-file-name', `byte-compile-current-file' or
|
the lookup is relative to `load-file-name', `byte-compile-current-file' or
|
||||||
`buffer-file-name' (in that order).
|
`buffer-file-name' (in that order).
|
||||||
|
|
||||||
If NOERROR is non-nil, don't throw an error if the file doesn't exist."
|
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))
|
(cl-assert (symbolp filesym) t)
|
||||||
(and (stringp path) path)
|
(let ((path (or path
|
||||||
(and (listp path) (eval path))))
|
|
||||||
(and load-file-name (file-name-directory load-file-name))
|
(and load-file-name (file-name-directory load-file-name))
|
||||||
(and (bound-and-true-p byte-compile-current-file)
|
(and (bound-and-true-p byte-compile-current-file)
|
||||||
(file-name-directory byte-compile-current-file))
|
(file-name-directory byte-compile-current-file))
|
||||||
(and buffer-file-name
|
(and buffer-file-name
|
||||||
(file-name-directory buffer-file-name))))
|
(file-name-directory buffer-file-name))
|
||||||
(filename (cond ((stringp filesym) filesym)
|
(error "Could not detect path to look for '%s' in" filesym)))
|
||||||
((symbolp filesym) (symbol-name filesym))
|
(filename (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))
|
|
||||||
(let ((file (expand-file-name (concat filename ".el") path)))
|
(let ((file (expand-file-name (concat filename ".el") path)))
|
||||||
(if (file-exists-p file)
|
(if (file-exists-p file)
|
||||||
`(load ,(file-name-sans-extension file) ,noerror
|
`(load ,(file-name-sans-extension file) ,noerror
|
||||||
,(not doom-debug-mode))
|
,(not doom-debug-mode))
|
||||||
(unless noerror
|
(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)
|
(defmacro require! (module submodule &optional flags reload-p)
|
||||||
"Loads the module specified by MODULE (a property) and SUBMODULE (a symbol).
|
"Loads the module specified by MODULE (a property) and SUBMODULE (a symbol).
|
||||||
|
@ -507,7 +493,8 @@ loads MODULE SUBMODULE's packages.el file."
|
||||||
t)))
|
t)))
|
||||||
|
|
||||||
(defun doom-packages--async-run (fn)
|
(defun doom-packages--async-run (fn)
|
||||||
(let ((compilation-filter-hook
|
(let* ((default-directory doom-emacs-dir)
|
||||||
|
(compilation-filter-hook
|
||||||
(list (lambda () (ansi-color-apply-on-region compilation-filter-start (point))))))
|
(list (lambda () (ansi-color-apply-on-region compilation-filter-start (point))))))
|
||||||
(compile (format "%s --quick --batch -l core/core.el -f %s"
|
(compile (format "%s --quick --batch -l core/core.el -f %s"
|
||||||
(executable-find "emacs")
|
(executable-find "emacs")
|
||||||
|
@ -527,15 +514,14 @@ call `doom/reload-load-path' remotely (through emacsclient)."
|
||||||
(interactive)
|
(interactive)
|
||||||
(byte-recompile-file (expand-file-name "core.el" doom-core-dir) t)
|
(byte-recompile-file (expand-file-name "core.el" doom-core-dir) t)
|
||||||
(cond (noninteractive
|
(cond (noninteractive
|
||||||
(message "Reloading...")
|
|
||||||
(require 'server)
|
(require 'server)
|
||||||
(when (server-running-p)
|
(when (server-running-p)
|
||||||
|
(message "Reloading active Emacs session...")
|
||||||
(server-eval-at server-name '(doom//reload-load-path))))
|
(server-eval-at server-name '(doom//reload-load-path))))
|
||||||
(t
|
((let ((noninteractive t))
|
||||||
(doom-initialize t)
|
(doom-initialize-load-path t)
|
||||||
(message "Reloaded %d packages" (length doom--package-load-path))
|
(message "%d packages reloaded" (length doom--package-load-path))
|
||||||
(run-with-timer 1 nil #'redraw-display)
|
(run-hooks 'doom-reload-hook)))))
|
||||||
(run-hooks 'doom-reload-hook))))
|
|
||||||
|
|
||||||
(defun doom//reload-autoloads ()
|
(defun doom//reload-autoloads ()
|
||||||
"Refreshes the autoloads.el file, specified by `doom-autoload-file'.
|
"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.
|
;; state. `doom-initialize-packages' will have side effects otherwise.
|
||||||
(and (doom-packages--async-run 'doom//reload-autoloads)
|
(and (doom-packages--async-run 'doom//reload-autoloads)
|
||||||
(load doom-autoload-file))
|
(load doom-autoload-file))
|
||||||
(doom-initialize-packages)
|
(doom-initialize-packages t)
|
||||||
(let ((targets
|
(let ((targets
|
||||||
(file-expand-wildcards
|
(file-expand-wildcards
|
||||||
(expand-file-name "autoload/*.el" doom-core-dir))))
|
(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)
|
(delete-file doom-autoload-file)
|
||||||
(message "Deleted old autoloads.el"))
|
(message "Deleted old autoloads.el"))
|
||||||
(dolist (file (reverse targets))
|
(dolist (file (reverse targets))
|
||||||
(message (cond ((not (doom-packages--read-if-cookies file))
|
(message
|
||||||
"Ignoring %s")
|
(cond ((not (doom-packages--read-if-cookies file))
|
||||||
|
"⚠ Ignoring %s")
|
||||||
((update-file-autoloads file nil doom-autoload-file)
|
((update-file-autoloads file nil doom-autoload-file)
|
||||||
"Nothing in %s")
|
"✕ Nothing in %s")
|
||||||
(t
|
(t
|
||||||
"Scanned %s"))
|
"✓ Scanned %s"))
|
||||||
(file-relative-name file doom-emacs-dir)))
|
(file-relative-name file doom-emacs-dir)))
|
||||||
|
(make-directory (file-name-directory doom-autoload-file) t)
|
||||||
(let ((buf (get-file-buffer doom-autoload-file))
|
(let ((buf (get-file-buffer doom-autoload-file))
|
||||||
current-sexp)
|
current-sexp)
|
||||||
(unwind-protect
|
(unwind-protect
|
||||||
|
@ -646,6 +634,8 @@ If RECOMPILE-P is non-nil, only recompile out-of-date files."
|
||||||
(error "No targets to compile"))
|
(error "No targets to compile"))
|
||||||
(let ((use-package-expand-minimally t))
|
(let ((use-package-expand-minimally t))
|
||||||
(push (expand-file-name "init.el" doom-emacs-dir) compile-targets)
|
(push (expand-file-name "init.el" doom-emacs-dir) compile-targets)
|
||||||
|
(condition-case ex
|
||||||
|
(progn
|
||||||
(dolist (target compile-targets)
|
(dolist (target compile-targets)
|
||||||
(when (or (not recompile-p)
|
(when (or (not recompile-p)
|
||||||
(let ((elc-file (byte-compile-dest-file target)))
|
(let ((elc-file (byte-compile-dest-file target)))
|
||||||
|
@ -657,13 +647,13 @@ If RECOMPILE-P is non-nil, only recompile out-of-date files."
|
||||||
(short-name (file-relative-name target doom-emacs-dir)))
|
(short-name (file-relative-name target doom-emacs-dir)))
|
||||||
(cl-incf
|
(cl-incf
|
||||||
(cond ((eq result 'no-byte-compile)
|
(cond ((eq result 'no-byte-compile)
|
||||||
(message! (dark (white "Ignored %s" short-name)))
|
(message! (dark (white "⚠ Ignored %s" short-name)))
|
||||||
total-noop)
|
total-noop)
|
||||||
((null result)
|
((null result)
|
||||||
(message! (red "Failed to compile %s" short-name))
|
(message! (red "✕ Failed to compile %s" short-name))
|
||||||
total-fail)
|
total-fail)
|
||||||
(t
|
(t
|
||||||
(message! (green "Compiled %s" short-name))
|
(message! (green "✓ Compiled %s" short-name))
|
||||||
(quiet! (load target t t))
|
(quiet! (load target t t))
|
||||||
total-ok))))))
|
total-ok))))))
|
||||||
(message!
|
(message!
|
||||||
|
@ -672,7 +662,14 @@ If RECOMPILE-P is non-nil, only recompile out-of-date files."
|
||||||
"%s %s file(s) %s"
|
"%s %s file(s) %s"
|
||||||
(if recompile-p "Recompiled" "Compiled")
|
(if recompile-p "Recompiled" "Compiled")
|
||||||
(format "%d/%d" total-ok (- (length compile-targets) total-noop))
|
(format "%d/%d" total-ok (- (length compile-targets) total-noop))
|
||||||
(format "(%s ignored)" 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)
|
(defun doom//byte-compile-core (&optional recompile-p)
|
||||||
"Byte compile the core Doom files.
|
"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."
|
If RECOMPILE-P is non-nil, only recompile out-of-date core files."
|
||||||
(interactive "P")
|
(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 ()
|
(defun doom//byte-recompile-plugins ()
|
||||||
"Recompile all installed plugins. If you're getting odd errors after upgrading
|
"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))
|
(byte-recompile-directory package-user-dir 0 t))
|
||||||
|
|
||||||
(defun doom//clean-byte-compiled-files ()
|
(defun doom//clean-byte-compiled-files ()
|
||||||
"Delete all the compiled elc files in your Emacs configuration.
|
"Delete all the compiled elc files in your Emacs configuration. This excludes
|
||||||
|
compiled packages.'"
|
||||||
This excludes compiled packages in `doom-packages-dir'.'"
|
|
||||||
(interactive)
|
(interactive)
|
||||||
(let ((targets (append (list (expand-file-name "init.elc" doom-emacs-dir))
|
(let ((targets (append (list (expand-file-name "init.elc" doom-emacs-dir))
|
||||||
(directory-files-recursively doom-core-dir "\\.elc$")
|
(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
|
(unless (cl-loop for path in targets
|
||||||
if (file-exists-p path)
|
if (file-exists-p path)
|
||||||
collect path
|
collect path
|
||||||
and do (delete-file 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"))))
|
(message "Everything is clean"))))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -87,13 +87,13 @@ recognized by DOOM's popup system. They are:
|
||||||
;;
|
;;
|
||||||
;;
|
;;
|
||||||
|
|
||||||
(defvar doom-popup-parameters
|
;; (defvar doom-popup-parameters
|
||||||
'(:esc :modeline :transient :fit :align :size)
|
;; '(:esc :modeline :transient :fit :align :size)
|
||||||
"TODO")
|
;; "TODO")
|
||||||
|
|
||||||
(defvar doom-popup-whitelist
|
;; (defvar doom-popup-whitelist
|
||||||
'(("^ ?\\*" :size 15 :noselect t :autokill t :autoclose t))
|
;; '(("^ ?\\*" :size 15 :noselect t :autokill t :autoclose t))
|
||||||
"TODO")
|
;; "TODO")
|
||||||
|
|
||||||
(defvar doom-popup-blacklist
|
(defvar doom-popup-blacklist
|
||||||
'("^\\*magit")
|
'("^\\*magit")
|
||||||
|
@ -122,7 +122,7 @@ recognized by DOOM's popup system. They are:
|
||||||
("*Backtrace*" :size 20 :noselect t)
|
("*Backtrace*" :size 20 :noselect t)
|
||||||
("*Warnings*" :size 12 :noselect t :autofit t)
|
("*Warnings*" :size 12 :noselect t :autofit t)
|
||||||
("*Messages*" :size 12 :noselect 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)
|
("^\\*.*Shell Command.*\\*$" :regexp t :size 20 :noselect t :autokill t)
|
||||||
(apropos-mode :size 0.3 :autokill t :autoclose t)
|
(apropos-mode :size 0.3 :autokill t :autoclose t)
|
||||||
(Buffer-menu-mode :size 20 :autokill 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)
|
(defun doom-display-buffer-action (buffer alist)
|
||||||
(shackle-display-buffer buffer alist (shackle-match buffer)))
|
(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
|
(add-hook! doom-post-init
|
||||||
(setq display-buffer-alist
|
(setq display-buffer-alist
|
||||||
(cons '(doom-display-buffer-condition doom-display-buffer-action)
|
(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
|
;; no modeline in popups
|
||||||
(add-hook 'doom-popup-mode-hook #'doom|hide-modeline-in-popup)
|
(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 [escape] #'doom/popup-close-maybe)
|
||||||
(define-key map (kbd "ESC") #'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 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-right] #'ignore)
|
||||||
(define-key map [remap split-window-below] #'ignore)
|
(define-key map [remap split-window-below] #'ignore)
|
||||||
(define-key map [remap split-window-horizontally] #'ignore)
|
(define-key map [remap split-window-horizontally] #'ignore)
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
;;; core-projects.el -*- lexical-binding: t; -*-
|
;;; 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
|
(def-package! projectile
|
||||||
|
:hook (doom-init . projectile-mode)
|
||||||
:init
|
:init
|
||||||
(setq projectile-cache-file (concat doom-cache-dir "projectile.cache")
|
(setq projectile-cache-file (concat doom-cache-dir "projectile.cache")
|
||||||
projectile-enable-caching (not noninteractive)
|
projectile-enable-caching (not noninteractive)
|
||||||
|
@ -14,17 +11,23 @@ state are passed in.")
|
||||||
projectile-globally-ignored-files '(".DS_Store" "Icon
" "TAGS")
|
projectile-globally-ignored-files '(".DS_Store" "Icon
" "TAGS")
|
||||||
projectile-globally-ignored-file-suffixes '(".elc" ".pyc" ".o"))
|
projectile-globally-ignored-file-suffixes '(".elc" ".pyc" ".o"))
|
||||||
|
|
||||||
(add-hook 'doom-init-hook #'projectile-mode)
|
|
||||||
:config
|
: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
|
;; a more generic project root file
|
||||||
(push ".project" projectile-project-root-files-bottom-up)
|
(push ".project" projectile-project-root-files-bottom-up)
|
||||||
|
|
||||||
(nconc projectile-globally-ignored-directories (list (abbreviate-file-name doom-local-dir) ".sync"))
|
(setq projectile-globally-ignored-directories
|
||||||
(nconc projectile-other-file-alist '(("css" . ("scss" "sass" "less" "style"))
|
(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"))
|
("scss" . ("css"))
|
||||||
("sass" . ("css"))
|
("sass" . ("css"))
|
||||||
("less" . ("css"))
|
("less" . ("css"))
|
||||||
("styl" . ("css"))))
|
("styl" . ("css")))))
|
||||||
|
|
||||||
;; Projectile root-searching functions can cause an infinite loop on TRAMP
|
;; Projectile root-searching functions can cause an infinite loop on TRAMP
|
||||||
;; connections, so disable them.
|
;; 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."
|
they are absolute."
|
||||||
(doom--resolve-path-forms files (doom-project-root)))
|
(doom--resolve-path-forms files (doom-project-root)))
|
||||||
|
|
||||||
|
(defun doom-project-find-file (dir)
|
||||||
|
"Fuzzy-find a file under DIR."
|
||||||
|
(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
|
;; Projects
|
||||||
;;
|
;;
|
||||||
|
|
||||||
(defvar-local doom-project nil
|
(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 ()
|
(defun doom|autoload-project-mode ()
|
||||||
"Auto-enable projects listed in `doom-project', which is meant to be set from
|
"Auto-enable the project(s) listed in `doom-project'."
|
||||||
.dir-locals.el files."
|
(when doom-project
|
||||||
|
(if (symbolp doom-project)
|
||||||
|
(funcall doom-project)
|
||||||
(cl-loop for mode in doom-project
|
(cl-loop for mode in doom-project
|
||||||
unless (symbol-value mode)
|
unless (symbol-value mode)
|
||||||
do (funcall mode)))
|
do (funcall mode)))))
|
||||||
(add-hook 'after-change-major-mode-hook #'doom|autoload-project-mode)
|
|
||||||
|
|
||||||
(defmacro def-project-mode! (name &rest plist)
|
(defmacro def-project-mode! (name &rest plist)
|
||||||
"Define a project minor-mode named NAME (a symbol) and declare where and how
|
"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.
|
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
|
A project can be enabled through .dir-locals.el too, by setting `doom-project'.
|
||||||
the name (symbol) of the project mode(s) to enable.
|
|
||||||
|
|
||||||
PLIST may contain any of these properties, which are all checked to see if NAME
|
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.
|
should be activated. If they are *all* true, NAME is activated.
|
||||||
|
@ -151,7 +180,7 @@ Relevant: `doom-project-hook'."
|
||||||
:keymap (make-sparse-keymap)
|
:keymap (make-sparse-keymap)
|
||||||
(if (not ,name)
|
(if (not ,name)
|
||||||
,exit-form
|
,exit-form
|
||||||
(run-hook-with-args 'doom-project-hook ',name)
|
(run-hook-with-args 'doom-project-hook ',name ,name)
|
||||||
,(when load-form
|
,(when load-form
|
||||||
`(unless ,init-var
|
`(unless ,init-var
|
||||||
,load-form
|
,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
|
max-mini-window-height 0.3
|
||||||
mode-line-default-help-echo nil ; disable mode-line mouseovers
|
mode-line-default-help-echo nil ; disable mode-line mouseovers
|
||||||
mouse-yank-at-point t ; middle-click paste at point, not at click
|
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
|
resize-mini-windows 'grow-only ; Minibuffer resizing
|
||||||
show-help-function nil ; hide :help-echo text
|
show-help-function nil ; hide :help-echo text
|
||||||
split-width-threshold 160 ; favor horizontal splits
|
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)
|
(when (fontp doom-variable-pitch-font)
|
||||||
(set-face-attribute 'variable-pitch frame :font doom-variable-pitch-font)))
|
(set-face-attribute 'variable-pitch frame :font doom-variable-pitch-font)))
|
||||||
('error
|
('error
|
||||||
|
(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
|
(lwarn 'doom-ui :error
|
||||||
"Failed to set fonts because %s"
|
"Unexpected error while initializing fonts: %s"
|
||||||
(error-message-string ex))))
|
(error-message-string ex)))))
|
||||||
(run-hooks 'doom-init-ui-hook))
|
(run-hooks 'doom-init-ui-hook))
|
||||||
|
|
||||||
(defun doom|reload-ui-in-daemon (frame)
|
(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)
|
(add-hook! '(doom-post-init-hook minibuffer-setup-hook)
|
||||||
#'doom|no-fringes-in-minibuffer)
|
#'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
|
;; 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)
|
(defun doom*disable-all-the-icons-in-tty (orig-fn &rest args)
|
||||||
(when (display-graphic-p)
|
(when (display-graphic-p)
|
||||||
(apply orig-fn args)))
|
(apply orig-fn args)))
|
||||||
|
|
||||||
;; all-the-icons doesn't work in the terminal, so we "disable" it.
|
;; 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)
|
(dolist (fn '(all-the-icons-octicon all-the-icons-material
|
||||||
(advice-add #'all-the-icons-material :around #'doom*disable-all-the-icons-in-tty)
|
all-the-icons-faicon all-the-icons-fileicon
|
||||||
(advice-add #'all-the-icons-faicon :around #'doom*disable-all-the-icons-in-tty)
|
all-the-icons-wicon all-the-icons-alltheicon))
|
||||||
(advice-add #'all-the-icons-fileicon :around #'doom*disable-all-the-icons-in-tty)
|
(advice-add fn :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))
|
|
||||||
|
|
||||||
(def-package! fringe-helper
|
(def-package! fringe-helper
|
||||||
:commands (fringe-helper-define fringe-helper-convert)
|
: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
|
(def-package! hideshow ; built-in
|
||||||
:commands (hs-minor-mode hs-toggle-hiding hs-already-hidden-p)
|
:commands (hs-minor-mode hs-toggle-hiding hs-already-hidden-p)
|
||||||
:config
|
:config (setq hs-hide-comments-when-hiding-all nil))
|
||||||
(setq hs-hide-comments-when-hiding-all nil))
|
|
||||||
|
|
||||||
(def-package! highlight-indentation
|
(def-package! highlight-indentation
|
||||||
:commands (highlight-indentation-mode highlight-indentation-current-column-mode))
|
: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
|
;; Helps us distinguish stacked delimiter pairs. Especially in parentheses-drunk
|
||||||
;; languages like Lisp.
|
;; languages like Lisp.
|
||||||
(def-package! rainbow-delimiters
|
(def-package! rainbow-delimiters
|
||||||
:commands rainbow-delimiters-mode
|
:hook (lisp-mode . rainbow-delimiters-mode)
|
||||||
:config (setq rainbow-delimiters-max-face-count 3)
|
:config (setq rainbow-delimiters-max-face-count 3))
|
||||||
:init (add-hook 'lisp-mode-hook #'rainbow-delimiters-mode))
|
|
||||||
|
|
||||||
;; For a distractions-free-like UI, that dynamically resizes margets and can
|
;; For a distractions-free-like UI, that dynamically resizes margets and can
|
||||||
;; center a buffer.
|
;; center a buffer.
|
||||||
(def-package! visual-fill-column
|
(def-package! visual-fill-column
|
||||||
:commands visual-fill-column-mode
|
:commands visual-fill-column-mode
|
||||||
:config
|
:config
|
||||||
(setq-default visual-fill-column-center-text nil
|
(setq-default
|
||||||
visual-fill-column-width fill-column))
|
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)))
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
|
135
core/core.el
135
core/core.el
|
@ -18,14 +18,14 @@
|
||||||
;; Autoloaded functions are in core/autoload/*.el and modules/*/*/autoload.el or
|
;; Autoloaded functions are in core/autoload/*.el and modules/*/*/autoload.el or
|
||||||
;; modules/*/*/autoload/*.el.
|
;; modules/*/*/autoload/*.el.
|
||||||
|
|
||||||
(defvar doom-version "2.0.8"
|
(defvar doom-version "2.0.9"
|
||||||
"Current version of DOOM emacs.")
|
"Current version of DOOM emacs.")
|
||||||
|
|
||||||
(defvar doom-debug-mode (or (getenv "DEBUG") init-file-debug)
|
(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
|
"If non-nil, all doom functions will be verbose. Set DEBUG=1 in the command
|
||||||
line or use --debug-init to enable this.")
|
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.")
|
"The path to this emacs.d directory.")
|
||||||
|
|
||||||
(defvar doom-core-dir (concat doom-emacs-dir "core/")
|
(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/")
|
(defvar doom-modules-dir (concat doom-emacs-dir "modules/")
|
||||||
"Where configuration modules are stored.")
|
"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/")
|
(defvar doom-local-dir (concat doom-emacs-dir ".local/")
|
||||||
"Root directory for local Emacs files. Use this as permanent storage for files
|
"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
|
that are safe to share across systems (if this config is symlinked across
|
||||||
several computers).")
|
several computers).")
|
||||||
|
|
||||||
(defvar doom-host-dir (concat doom-local-dir "@" (system-name))
|
(defvar doom-etc-dir (concat doom-local-dir "etc/")
|
||||||
"Directory for hostname-specific file storage. Used by `doom-etc-dir' and
|
"Directory for non-volatile storage.
|
||||||
`doom-cache-dir'.")
|
|
||||||
|
|
||||||
(defvar doom-etc-dir (concat doom-host-dir "/etc/")
|
Use this for files that don't change much, like servers binaries, external
|
||||||
"Host-namespaced directory for non-volatile storage. These are not deleted or
|
dependencies or long-term shared data.")
|
||||||
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).")
|
|
||||||
|
|
||||||
(defvar doom-cache-dir (concat doom-host-dir "/cache/")
|
(defvar doom-cache-dir (concat doom-local-dir "cache/")
|
||||||
"Host-namespaced directory for volatile storage. Deleted when `doom/reset' is
|
"Directory for volatile storage.
|
||||||
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
|
Use this for files that change often, like cache files.")
|
||||||
problems.")
|
|
||||||
|
|
||||||
(defvar doom-packages-dir (concat doom-local-dir "packages/")
|
(defvar doom-packages-dir (concat doom-local-dir "packages/")
|
||||||
"Where package.el and quelpa plugins (and their caches) are stored.")
|
"Where package.el and quelpa plugins (and their caches) are stored.")
|
||||||
|
|
||||||
(defvar doom-autoload-file (concat doom-local-dir "autoloads.el")
|
(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
|
(defgroup doom nil
|
||||||
"DOOM Emacs, an Emacs configuration for a stubborn, shell-dwelling and
|
"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)
|
(load custom-file t t)
|
||||||
|
|
||||||
;; be quiet at startup; don't load or display anything unnecessary
|
;; be quiet at startup; don't load or display anything unnecessary
|
||||||
(advice-add #'display-startup-echo-area-message :override #'ignore)
|
(unless noninteractive
|
||||||
(setq inhibit-startup-message t
|
(advice-add #'display-startup-echo-area-message :override #'ignore)
|
||||||
|
(setq inhibit-startup-message t
|
||||||
inhibit-startup-echo-area-message user-login-name
|
inhibit-startup-echo-area-message user-login-name
|
||||||
inhibit-default-init t
|
inhibit-default-init t
|
||||||
initial-major-mode 'fundamental-mode
|
initial-major-mode 'fundamental-mode
|
||||||
initial-scratch-message nil
|
initial-scratch-message nil
|
||||||
mode-line-format nil)
|
mode-line-format nil))
|
||||||
|
|
||||||
;; Custom init hooks; clearer than `after-init-hook', `emacs-startup-hook', and
|
;; Custom init hooks; clearer than `after-init-hook', `emacs-startup-hook', and
|
||||||
;; `window-setup-hook'.
|
;; `window-setup-hook'.
|
||||||
|
@ -152,33 +142,23 @@ ability to invoke the debugger in debug mode."
|
||||||
(car ex) fn (error-message-string ex))))
|
(car ex) fn (error-message-string ex))))
|
||||||
nil)
|
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
|
;; Initialize
|
||||||
(eval-and-compile
|
(eval-and-compile
|
||||||
(defvar doom--file-name-handler-alist file-name-handler-alist)
|
(defvar doom--file-name-handler-alist file-name-handler-alist)
|
||||||
|
(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
|
(setq gc-cons-threshold 402653184
|
||||||
gc-cons-percentage 0.6
|
gc-cons-percentage 0.6
|
||||||
file-name-handler-alist nil)
|
file-name-handler-alist nil))
|
||||||
|
|
||||||
(require 'core-packages (concat doom-core-dir "core-packages"))
|
(require 'cl-lib)
|
||||||
(eval-when-compile
|
(load (concat doom-core-dir "core-packages") nil t)
|
||||||
(doom-initialize))
|
(setq load-path (eval-when-compile (doom-initialize t)
|
||||||
(setq load-path (eval-when-compile load-path)
|
(doom-initialize-load-path t))
|
||||||
doom--package-load-path (eval-when-compile doom--package-load-path))
|
doom--package-load-path (eval-when-compile doom--package-load-path))
|
||||||
|
|
||||||
(load! core-lib)
|
(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-popups) ; taming sudden yet inevitable windows
|
||||||
(load! core-editor) ; baseline configuration for text editing
|
(load! core-editor) ; baseline configuration for text editing
|
||||||
(load! core-projects) ; making Emacs project-aware
|
(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)
|
(defun doom|finalize ()
|
||||||
#'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)
|
(provide 'core)
|
||||||
;;; core.el ends here
|
;;; core.el ends here
|
||||||
|
|
|
@ -1,24 +1,23 @@
|
||||||
;; -*- no-byte-compile: t; -*-
|
;; -*- no-byte-compile: t; -*-
|
||||||
;;; core/test/autoload-buffers.el
|
;;; core/test/autoload-buffers.el
|
||||||
|
|
||||||
(defmacro -with-temp-buffers! (buffer-args &rest body)
|
(defmacro with-temp-buffers!! (buffer-args &rest body)
|
||||||
(declare (indent defun))
|
(declare (indent defun))
|
||||||
(let (buffers)
|
(let (buffers)
|
||||||
(dolist (bsym buffer-args)
|
(dolist (bsym buffer-args)
|
||||||
(push `(,bsym (get-buffer-create ,(symbol-name bsym)))
|
(push `(,bsym (get-buffer-create ,(symbol-name bsym)))
|
||||||
buffers))
|
buffers))
|
||||||
`(save-window-excursion
|
`(cl-flet ((buffer-list
|
||||||
(cl-flet ((buffer-list
|
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(cl-remove-if-not #'buffer-live-p (list ,@(reverse (mapcar #'car buffers)))))))
|
(cl-remove-if-not #'buffer-live-p (list ,@(reverse (mapcar #'car buffers)))))))
|
||||||
(let* (persp-mode
|
(let* (persp-mode
|
||||||
,@buffers)
|
,@buffers)
|
||||||
,@body
|
,@body
|
||||||
(mapc #'kill-buffer (buffer-list)))))))
|
(mapc #'kill-buffer (buffer-list))))))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
(def-test! get-buffers
|
(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 (cl-every #'buffer-live-p (buffer-list)))
|
||||||
(should (equal (buffer-list) (list a b c)))
|
(should (equal (buffer-list) (list a b c)))
|
||||||
(dolist (buf (list (cons a doom-emacs-dir)
|
(dolist (buf (list (cons a doom-emacs-dir)
|
||||||
|
@ -26,6 +25,7 @@
|
||||||
(cons c "/tmp/")))
|
(cons c "/tmp/")))
|
||||||
(with-current-buffer (car buf)
|
(with-current-buffer (car buf)
|
||||||
(setq-local default-directory (cdr buf))))
|
(setq-local default-directory (cdr buf))))
|
||||||
|
(projectile-mode +1)
|
||||||
(with-current-buffer a
|
(with-current-buffer a
|
||||||
;; should produce all buffers
|
;; should produce all buffers
|
||||||
(let ((buffers (doom-buffer-list)))
|
(let ((buffers (doom-buffer-list)))
|
||||||
|
@ -37,11 +37,12 @@
|
||||||
;; If no project is available, just get all buffers
|
;; If no project is available, just get all buffers
|
||||||
(with-current-buffer c
|
(with-current-buffer c
|
||||||
(let ((buffers (doom-project-buffer-list)))
|
(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
|
(def-test! real-buffers
|
||||||
(let (doom-real-buffer-functions)
|
(let (doom-real-buffer-functions)
|
||||||
(-with-temp-buffers! (a b c d)
|
(with-temp-buffers!! (a b c d)
|
||||||
(dolist (buf (list a b))
|
(dolist (buf (list a b))
|
||||||
(with-current-buffer buf
|
(with-current-buffer buf
|
||||||
(setq-local buffer-file-name "x")))
|
(setq-local buffer-file-name "x")))
|
||||||
|
@ -62,7 +63,7 @@
|
||||||
;; `doom-visible-buffers'
|
;; `doom-visible-buffers'
|
||||||
;; `doom-buried-buffers'
|
;; `doom-buried-buffers'
|
||||||
(def-test! visible-buffers-and-windows
|
(def-test! visible-buffers-and-windows
|
||||||
(-with-temp-buffers! (a b c d)
|
(with-temp-buffers!! (a b c d)
|
||||||
(switch-to-buffer a)
|
(switch-to-buffer a)
|
||||||
(should (eq (current-buffer) a))
|
(should (eq (current-buffer) a))
|
||||||
(should (eq (selected-window) (get-buffer-window a)))
|
(should (eq (selected-window) (get-buffer-window a)))
|
||||||
|
@ -77,7 +78,7 @@
|
||||||
|
|
||||||
;; `doom-matching-buffers'
|
;; `doom-matching-buffers'
|
||||||
(def-test! matching-buffers
|
(def-test! matching-buffers
|
||||||
(-with-temp-buffers! (a b c)
|
(with-temp-buffers!! (a b c)
|
||||||
(let ((buffers (doom-matching-buffers "^[ac]$")))
|
(let ((buffers (doom-matching-buffers "^[ac]$")))
|
||||||
(should (= 2 (length buffers)))
|
(should (= 2 (length buffers)))
|
||||||
(should (cl-every #'bufferp buffers))
|
(should (cl-every #'bufferp buffers))
|
||||||
|
@ -86,7 +87,7 @@
|
||||||
|
|
||||||
;; `doom-buffers-in-mode'
|
;; `doom-buffers-in-mode'
|
||||||
(def-test! 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))
|
(dolist (buf (list a b))
|
||||||
(with-current-buffer buf
|
(with-current-buffer buf
|
||||||
(emacs-lisp-mode)))
|
(emacs-lisp-mode)))
|
||||||
|
@ -101,7 +102,7 @@
|
||||||
|
|
||||||
;; `doom-kill-buffer'
|
;; `doom-kill-buffer'
|
||||||
(def-test! kill-buffer
|
(def-test! kill-buffer
|
||||||
(-with-temp-buffers! (a b)
|
(with-temp-buffers!! (a b)
|
||||||
(doom-kill-buffer a)
|
(doom-kill-buffer a)
|
||||||
(should-not (buffer-live-p a))
|
(should-not (buffer-live-p a))
|
||||||
;; modified buffer
|
;; modified buffer
|
||||||
|
@ -112,7 +113,7 @@
|
||||||
|
|
||||||
;; `doom--cycle-real-buffers'
|
;; `doom--cycle-real-buffers'
|
||||||
(def-test! kill-buffer-then-show-real-buffer
|
(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))
|
(dolist (buf (list a b d))
|
||||||
(with-current-buffer buf
|
(with-current-buffer buf
|
||||||
(setq-local buffer-file-name "x")))
|
(setq-local buffer-file-name "x")))
|
||||||
|
@ -131,4 +132,4 @@
|
||||||
;; TODO doom/kill-all-buffers
|
;; TODO doom/kill-all-buffers
|
||||||
;; TODO doom/kill-other-buffers
|
;; TODO doom/kill-other-buffers
|
||||||
;; TODO doom/kill-matching-buffers
|
;; TODO doom/kill-matching-buffers
|
||||||
;; TODO doom/cleanup-buffers
|
;; TODO doom/cleanup-session
|
||||||
|
|
|
@ -2,18 +2,16 @@
|
||||||
;;; core/test/autoload-debug.el
|
;;; core/test/autoload-debug.el
|
||||||
|
|
||||||
(def-test! what-face
|
(def-test! what-face
|
||||||
(with-temp-buffer
|
|
||||||
(insert (propertize "Hello " 'face 'font-lock-keyword-face))
|
(insert (propertize "Hello " 'face 'font-lock-keyword-face))
|
||||||
(insert "world")
|
(insert "world")
|
||||||
|
|
||||||
(should (equal (doom/what-face (point-min)) '((font-lock-keyword-face) ())))
|
(should (equal (doom/what-face (point-min)) '((font-lock-keyword-face) ())))
|
||||||
(should-not (doom/what-face (point-max)))))
|
(should-not (doom/what-face (point-max))))
|
||||||
|
|
||||||
(def-test! what-face-overlays
|
(def-test! what-face-overlays
|
||||||
(with-temp-buffer
|
|
||||||
(insert "Hello world")
|
(insert "Hello world")
|
||||||
(let ((ov (make-overlay 1 6)))
|
(let ((ov (make-overlay 1 6)))
|
||||||
(overlay-put ov 'face 'font-lock-keyword-face))
|
(overlay-put ov 'face 'font-lock-keyword-face))
|
||||||
|
|
||||||
(should (equal (doom/what-face (point-min)) '(() (font-lock-keyword-face))))
|
(should (equal (doom/what-face (point-min)) '(() (font-lock-keyword-face))))
|
||||||
(should-not (doom/what-face (point-max)))))
|
(should-not (doom/what-face (point-max))))
|
||||||
|
|
|
@ -1,30 +1,21 @@
|
||||||
;; -*- no-byte-compile: t; -*-
|
;; -*- no-byte-compile: t; -*-
|
||||||
;;; core/test/autoload-package.el
|
;;; 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))
|
(package-desc-create :name name :version version :reqs reqs))
|
||||||
|
|
||||||
(defmacro -with-temp-packages! (&rest forms)
|
(defmacro with-packages!! (packages package-descs &rest body)
|
||||||
"Run FORMS in the context of a temporary package setup (as in, it won't
|
`(let* ((doom-packages-dir ,(expand-file-name "packages/" (file-name-directory load-file-name)))
|
||||||
affects your Emacs packages)."
|
(package-user-dir ,(expand-file-name "elpa" doom-packages-dir))
|
||||||
`(let* ((doom-local-dir ,(expand-file-name "test/.local/" doom-emacs-dir))
|
(quelpa-dir ,(expand-file-name "quelpa" doom-packages-dir)))
|
||||||
(doom-packages-dir (concat doom-local-dir "packages/"))
|
;; (make-directory doom-packages-dir t)
|
||||||
(doom-etc-dir (concat doom-local-dir "etc/"))
|
(let ((doom-packages ,packages)
|
||||||
(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)
|
|
||||||
(package-alist ,package-descs)
|
(package-alist ,package-descs)
|
||||||
doom-core-packages)
|
doom-core-packages)
|
||||||
(cl-letf (((symbol-function 'doom-initialize-packages) (lambda (&rest _)))
|
(cl-letf (((symbol-function 'doom-initialize-packages) (lambda (&rest _))))
|
||||||
((symbol-function 'package-installed-p) (lambda (name &rest _) (assq name package-alist))))
|
,@body))
|
||||||
,@body)))
|
;; (delete-directory doom-packages-dir t)
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
@ -32,18 +23,19 @@ affects your Emacs packages)."
|
||||||
;;
|
;;
|
||||||
|
|
||||||
(def-test! backend-detection
|
(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-cache '((doom-quelpa-dummy :fetcher github :repo "hlissner/does-not-exist")))
|
||||||
(quelpa-initialized-p t))
|
(quelpa-initialized-p t))
|
||||||
(should (eq (doom-package-backend 'doom-dummy) 'elpa))
|
(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
|
(def-test! elpa-outdated-detection
|
||||||
(let* ((doom--last-refresh (current-time))
|
(let* ((doom--last-refresh (current-time))
|
||||||
(package-alist
|
(package-alist
|
||||||
`((doom-dummy ,(-new-package 'doom-dummy '(20160405 1234)))))
|
`((doom-dummy ,(-pkg 'doom-dummy '(20160405 1234)))))
|
||||||
(package-archive-contents
|
(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 _))))
|
(cl-letf (((symbol-function 'package-refresh-contents) (lambda (&rest _))))
|
||||||
(should (equal (doom-package-outdated-p 'doom-dummy)
|
(should (equal (doom-package-outdated-p 'doom-dummy)
|
||||||
'(doom-dummy (20160405 1234) (20170405 1234)))))))
|
'(doom-dummy (20160405 1234) (20170405 1234)))))))
|
||||||
|
@ -52,7 +44,7 @@ affects your Emacs packages)."
|
||||||
|
|
||||||
(def-test! get-packages
|
(def-test! get-packages
|
||||||
(let ((quelpa-initialized-p t))
|
(let ((quelpa-initialized-p t))
|
||||||
(-with-packages!
|
(with-packages!!
|
||||||
'((doom-dummy))
|
'((doom-dummy))
|
||||||
'((doom-dummy nil)
|
'((doom-dummy nil)
|
||||||
(doom-dummy-unwanted nil)
|
(doom-dummy-unwanted nil)
|
||||||
|
@ -62,17 +54,17 @@ affects your Emacs packages)."
|
||||||
(def-test! orphaned-packages
|
(def-test! orphaned-packages
|
||||||
"Test `doom-get-orphaned-packages', which gets a list of packages that are
|
"Test `doom-get-orphaned-packages', which gets a list of packages that are
|
||||||
no longer enabled or depended on."
|
no longer enabled or depended on."
|
||||||
(-with-packages!
|
(with-packages!!
|
||||||
'((doom-dummy))
|
'((doom-dummy))
|
||||||
`((doom-dummy ,(-new-package 'doom-dummy '(20160405 1234) '((doom-dummy-dep (1 0)))))
|
`((doom-dummy ,(-pkg 'doom-dummy '(20160405 1234) '((doom-dummy-dep (1 0)))))
|
||||||
(doom-dummy-unwanted ,(-new-package 'doom-dummy-unwanted '(20160601 1234)))
|
(doom-dummy-unwanted ,(-pkg 'doom-dummy-unwanted '(20160601 1234)))
|
||||||
(doom-dummy-dep ,(-new-package 'doom-dummy-dep '(20160301 1234))))
|
(doom-dummy-dep ,(-pkg 'doom-dummy-dep '(20160301 1234))))
|
||||||
(should (equal (doom-get-orphaned-packages) '(doom-dummy-unwanted)))))
|
(should (equal (doom-get-orphaned-packages) '(doom-dummy-unwanted)))))
|
||||||
|
|
||||||
(def-test! missing-packages
|
(def-test! missing-packages
|
||||||
"Test `doom-get-missing-packages, which gets a list of enabled packages that
|
"Test `doom-get-missing-packages, which gets a list of enabled packages that
|
||||||
aren't installed."
|
aren't installed."
|
||||||
(-with-packages!
|
(with-packages!!
|
||||||
'((doom-dummy) (doom-dummy-installed))
|
'((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))))))
|
(should (equal (doom-get-missing-packages) '((doom-dummy))))))
|
||||||
|
|
|
@ -147,10 +147,13 @@
|
||||||
|
|
||||||
;; --- Settings ---------------------------
|
;; --- Settings ---------------------------
|
||||||
|
|
||||||
(def-setting! :-test-setting (x) x)
|
|
||||||
|
|
||||||
(def-test! set
|
(def-test! set
|
||||||
|
(eval-and-compile
|
||||||
|
(let (doom-settings)
|
||||||
|
(def-setting! :-test-setting (x) `(setq result ,x))
|
||||||
(should (assq :-test-setting doom-settings))
|
(should (assq :-test-setting doom-settings))
|
||||||
(should (set! :-test-setting t))
|
(let ((inhibit-message t)
|
||||||
(let ((inhibit-message t))
|
result)
|
||||||
(should-not (set! :non-existant-setting (error "This shouldn't trigger")))))
|
(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
|
;twitter ; twitter client https://twitter.com/vnought
|
||||||
;write ; emacs as a word processor (latex + org + markdown)
|
;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.
|
;; for your own.
|
||||||
:private hlissner)
|
:private default)
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
:completion
|
:completion
|
||||||
company
|
company
|
||||||
|
|
||||||
|
:ui
|
||||||
|
doom-dashboard
|
||||||
|
|
||||||
:tools
|
:tools
|
||||||
password-store
|
password-store
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
|
|
||||||
|
|
||||||
(def-package! elfeed-org
|
(def-package! elfeed-org
|
||||||
:after elfeed
|
:after (:all org elfeed)
|
||||||
:config
|
:config
|
||||||
(setq rmh-elfeed-org-files
|
(setq rmh-elfeed-org-files
|
||||||
(let ((default-directory +org-dir))
|
(let ((default-directory +org-dir))
|
||||||
|
|
|
@ -14,20 +14,23 @@ This module adds code-completion support, powered by [[https://github.com/compan
|
||||||
- [[#troubleshooting][Troubleshooting]]
|
- [[#troubleshooting][Troubleshooting]]
|
||||||
|
|
||||||
* Install
|
* 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.
|
Check the README.org in that language's module for details.
|
||||||
|
|
||||||
* Configure
|
* Configure
|
||||||
** Auto-completion
|
** 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:
|
To enable auto-completion you must:
|
||||||
|
|
||||||
1. Load ~company~,
|
1. Load ~company~,
|
||||||
2. and change ~company-idle-delay~ to a non-nil float (the default is 0.5)
|
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
|
#+BEGIN_SRC emacs-lisp
|
||||||
(require 'company)
|
(require 'company)
|
||||||
|
@ -36,8 +39,10 @@ For example, add the following to your ~modules/private/<username>/config.el~ mo
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
* Troubleshooting
|
* 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.
|
+ If what you are expecting is popup-as-you-type completion (which is disabled
|
||||||
+ Certain languages may have extra dependencies in order for auto-completion to work. Please look for that module's README.org for details.
|
by default), see the "Configure > Auto-completion" section above, which will
|
||||||
+ Some languages don't have any auto-completion support.
|
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! :completion company)
|
||||||
(require 'company)
|
(require 'company)
|
||||||
|
|
||||||
|
;;
|
||||||
(def-test! set-company-backend
|
(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 'emacs-lisp-mode '(backend-1))
|
||||||
(set! :company-backend 'lisp-interaction-mode 'backend-1 'backend-2)
|
(set! :company-backend 'lisp-interaction-mode 'backend-1 'backend-2)
|
||||||
(set! :company-backend 'text-mode 'backend-1)
|
(set! :company-backend 'text-mode 'backend-1)
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
(emacs-lisp-mode)
|
(emacs-lisp-mode)
|
||||||
(should (equal (car company-backends) '(backend-1))))
|
(should (equal company-backends '((backend-1) default))))
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
(lisp-interaction-mode)
|
(lisp-interaction-mode)
|
||||||
(should (equal company-backends
|
(should (equal company-backends '(backend-1 backend-2 default))))
|
||||||
(append '(backend-1 backend-2) default-backends))))
|
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
(text-mode)
|
(text-mode)
|
||||||
(should (eq (car company-backends) 'backend-1)))
|
(should (equal company-backends '(backend-1 default))))
|
||||||
;; global backends shouldn't be affected
|
;; 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.
|
This module adds Ivy, a completion backend.
|
||||||
|
|
||||||
#+begin_quote
|
#+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
|
#+end_quote
|
||||||
|
|
||||||
+ Project-wide search & replace powered by ~rg~ or ~ag~
|
+ 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.
|
+ Ivy integration for ~M-x~, ~imenu~, ~recentf~ and others.
|
||||||
+ A powerful, interactive in-buffer search using ~swiper~.
|
+ A powerful, interactive in-buffer search using ~swiper~.
|
||||||
+ Ivy-powered TODO/FIXME navigation
|
+ 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
|
* Install
|
||||||
This module optionally depends on [[https://github.com/BurntSushi/ripgrep][ripgrep]] and [[https://github.com/ggreer/the_silver_searcher][the_silver_searcher]].
|
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
|
** MacOS
|
||||||
#+BEGIN_SRC sh :tangle (if (doom-system-os 'macos) "yes")
|
#+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
|
#+END_SRC
|
||||||
|
|
||||||
* Usage
|
* 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
|
** 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]]
|
[[/../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]]
|
[[/../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
|
** 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]]
|
[[/../screenshots/modules/completion/ivy/ivy-projectile.gif]]
|
||||||
|
|
||||||
** In-buffer searching
|
** 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]]
|
[[/../screenshots/modules/completion/ivy/ivy-swiper.gif]]
|
||||||
|
|
||||||
** Task lookup
|
** 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]]
|
[[/../screenshots/modules/completion/ivy/ivy-todo.gif]]
|
||||||
|
|
||||||
* Appendix
|
* Appendix
|
||||||
** Commands
|
** 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 |
|
| 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:swiper~ | ~:sw[iper] [QUERY]~ | Search current buffer |
|
||||||
| ~+ivy:todo~ | ~:todo[!]~ | List all TODO/FIXMEs in project (or current file if BANG) |
|
| ~+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 |
|
| 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 |
|
| =M-RET= | Open the selected candidate in other-window |
|
||||||
|
|
||||||
** Hacks
|
** 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.
|
+ Functions with ivy/counsel equivalents have been globally remapped (like
|
||||||
+ ~counsel-[arp]g~'s 3-character limit was reduced to 1 (mainly for the ex command)
|
~find-file~ => ~counsel-find-file~). So a keybinding to ~find-file~ will
|
||||||
+ ~counsel-[arp]g~'s parentheses quoting behavior was reversed. Now, if you
|
invoke ~counsel-find-file~ instead.
|
||||||
want literal parentheses, you must escape them: e.g. ~\(match\)~ is literal,
|
+ ~counsel-[arp]g~'s 3-character limit was reduced to 1 (mainly for the ex
|
||||||
~(match)~ is a regexp group.
|
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! magit (setq magit-completing-read-function #'ivy-completing-read))
|
||||||
(after! yasnippet (push #'+ivy-yas-prompt yas-prompt-functions))
|
(after! yasnippet (push #'+ivy-yas-prompt yas-prompt-functions))
|
||||||
|
|
||||||
(map! :map ivy-mode-map
|
(map! [remap apropos] #'counsel-apropos
|
||||||
[remap apropos] #'counsel-apropos
|
|
||||||
[remap describe-face] #'counsel-describe-face
|
[remap describe-face] #'counsel-describe-face
|
||||||
[remap find-file] #'counsel-find-file
|
[remap find-file] #'counsel-find-file
|
||||||
[remap switch-to-buffer] #'ivy-switch-buffer
|
[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 recentf-open-files] #'counsel-recentf
|
||||||
[remap imenu] #'counsel-imenu
|
[remap imenu] #'counsel-imenu
|
||||||
[remap bookmark-jump] #'counsel-bookmark
|
[remap bookmark-jump] #'counsel-bookmark
|
||||||
[remap projectile-switch-project] #'counsel-projectile-switch-project
|
|
||||||
[remap projectile-find-file] #'counsel-projectile-find-file
|
[remap projectile-find-file] #'counsel-projectile-find-file
|
||||||
[remap imenu-anywhere] #'ivy-imenu-anywhere
|
[remap imenu-anywhere] #'ivy-imenu-anywhere
|
||||||
[remap execute-extended-command] #'counsel-M-x
|
[remap execute-extended-command] #'counsel-M-x
|
||||||
|
|
|
@ -1,43 +1,52 @@
|
||||||
#+TITLE: :feature eval
|
#+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:
|
* Table of Contents :TOC:
|
||||||
- [[#install][Install]]
|
- [[#install][Install]]
|
||||||
- [[#usage][Usage]]
|
- [[#usage][Usage]]
|
||||||
- [[#configuration][Configuration]]
|
|
||||||
- [[#repls][REPLs]]
|
- [[#repls][REPLs]]
|
||||||
- [[#code-evaluation][Code Evaluation]]
|
- [[#code-evaluation][*Code Evaluation*]]
|
||||||
|
- [[#configuration][Configuration]]
|
||||||
|
- [[#repls-1][REPLs]]
|
||||||
|
- [[#code-evaluation-1][Code Evaluation]]
|
||||||
|
|
||||||
* Install
|
* 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.
|
Check the README.org in that language's module for details.
|
||||||
|
|
||||||
* Usage
|
* Usage
|
||||||
+ *REPLs*
|
** REPLs
|
||||||
Invoked via:
|
Invoked via:
|
||||||
+ ~:repl~ (evil ex-command)
|
+ ~:repl~ (evil ex-command)
|
||||||
+ =<leader> o r= in normal mode (or visual mode, which sends the selection to the open REPL)
|
+ =<leader> o r= in normal mode (or visual mode, which sends the selection to
|
||||||
+ ~M-x +eval/open-repl~
|
the open REPL)
|
||||||
+ ~M-x +eval/send-region-to-repl~ while a selection (and REPL) is active
|
+ ~M-x +eval/open-repl~
|
||||||
|
+ ~M-x +eval/send-region-to-repl~ while a selection (and REPL) is active
|
||||||
|
|
||||||
+ *Code Evaluation*
|
** *Code Evaluation*
|
||||||
Quickrun can be invoked via:
|
Quickrun can be invoked via:
|
||||||
+ ~M-x +eval/buffer~ (or ~gR~, or ~M-r~)
|
+ ~M-x +eval/buffer~ (or ~gR~, or ~M-r~)
|
||||||
+ ~M-x +eval/region~
|
+ ~M-x +eval/region~
|
||||||
+ ~M-x +eval/region-and-replace~
|
+ ~M-x +eval/region-and-replace~
|
||||||
+ Evil users can use the ~gr~ operator to select and run a region.
|
+ Evil users can use the ~gr~ operator to select and run a region.
|
||||||
|
|
||||||
* Configuration
|
* Configuration
|
||||||
** REPLs
|
** 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)~
|
~(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
|
#+BEGIN_SRC emacs-lisp
|
||||||
(defun +emacs-lisp/repl ()
|
(defun +emacs-lisp/repl ()
|
||||||
|
@ -53,9 +62,14 @@ FUNCTION must return the repl buffer. Any window changes are ignored, then hande
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
** Code Evaluation
|
** 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
|
#+BEGIN_SRC emacs-lisp
|
||||||
(set! :eval 'crystal-mode
|
(set! :eval 'crystal-mode
|
||||||
|
|
|
@ -11,12 +11,14 @@ This holy module brings the vim experience to Emacs.
|
||||||
- [[#differences-from-vim][Differences from vim]]
|
- [[#differences-from-vim][Differences from vim]]
|
||||||
|
|
||||||
* Removing evil-mode
|
* 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
|
* Features
|
||||||
+ A better ~:g[lobal]~ command with incremental highlighting.
|
+ A better ~:g[lobal]~ command with incremental highlighting.
|
||||||
+ Adds the ~:al[ign]~ ex command: offers an ex interface to ~align-regexp~ with incremental highlighting.
|
+ Adds the ~:al[ign]~ ex command: offers an ex interface to ~align-regexp~ with
|
||||||
+ Support for more of vim's filename modifiers in ex commands (like ~:p~, ~:p:h~ or ~:t~) than vanilla evil-mode offers.
|
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:
|
+ A list of new text objects:
|
||||||
+ Blocks: ~B~ (from ~evil-textobj-anyblock~)
|
+ Blocks: ~B~ (from ~evil-textobj-anyblock~)
|
||||||
+ Args: ~a~ (from ~evil-args~)
|
+ 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=
|
+ =NERDTree= equivalent is available in =:tools neotree=
|
||||||
|
|
||||||
** Multiple-cursors
|
** 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
|
** 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.
|
Most vim folding keys should work, e.g. =zr=, =zm=, =za=, =zo=, etc.
|
||||||
|
|
||||||
** Hacks
|
** Hacks
|
||||||
+ Automatically moves to new window when splitting
|
+ 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
|
** 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.
|
+ =: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)
|
(error "Failed to delete %s" short-path)
|
||||||
;; Ensures that windows displaying this buffer will be switched
|
;; Ensures that windows displaying this buffer will be switched
|
||||||
;; to real buffers (`doom-real-buffer-p')
|
;; 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)
|
(+evil--forget-file fname)
|
||||||
(message "Successfully deleted %s" short-path))))))))
|
(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
|
;; 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
|
;; so that any plugins that depend on multiple-cursors (which I have no control
|
||||||
;; relative safety.
|
;; over) can still use it in relative safety.
|
||||||
(after! multiple-cursors-core
|
(after! multiple-cursors-core
|
||||||
(map! :map mc/keymap :ne "<escape>" #'mc/keyboard-quit)
|
(map! :map mc/keymap :ne "<escape>" #'mc/keyboard-quit)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
;; -*- no-byte-compile: t; -*-
|
;; -*- no-byte-compile: t; -*-
|
||||||
;;; feature/evil/test/autoload-files.el
|
;;; 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
|
"Run FORMS in the context of a temporary package setup (as in, it won't
|
||||||
affects your Emacs packages)."
|
affects your Emacs packages)."
|
||||||
(declare (indent 2) (doc-string 3))
|
(declare (indent 2) (doc-string 3))
|
||||||
|
@ -23,7 +23,7 @@ affects your Emacs packages)."
|
||||||
;;
|
;;
|
||||||
(def-test! move-this-file
|
(def-test! move-this-file
|
||||||
":mv"
|
":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-error (+evil:move-this-file it))
|
||||||
(should (+evil:move-this-file other t))
|
(should (+evil:move-this-file other t))
|
||||||
(should (file-exists-p other))
|
(should (file-exists-p other))
|
||||||
|
@ -31,7 +31,7 @@ affects your Emacs packages)."
|
||||||
|
|
||||||
(def-test! copy-this-file
|
(def-test! copy-this-file
|
||||||
":cp"
|
":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-error (+evil:copy-this-file it))
|
||||||
(should (+evil:copy-this-file other t))
|
(should (+evil:copy-this-file other t))
|
||||||
(should (file-exists-p other))
|
(should (file-exists-p other))
|
||||||
|
@ -39,7 +39,7 @@ affects your Emacs packages)."
|
||||||
|
|
||||||
(def-test! delete-this-file
|
(def-test! delete-this-file
|
||||||
":rm"
|
":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-error (+evil:delete-this-file "this-file-does-not-exist"))
|
||||||
(should (+evil:delete-this-file nil t))
|
(should (+evil:delete-this-file nil t))
|
||||||
(should (not (file-exists-p it)))))
|
(should (not (file-exists-p it)))))
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
(require! :feature evil)
|
(require! :feature evil)
|
||||||
|
|
||||||
|
;;
|
||||||
;; `evil-ex-replace-special-filenames'
|
;; `evil-ex-replace-special-filenames'
|
||||||
;; NOTE The majority of this function is tested in core/test/core-lib.el, this
|
;; NOTE The majority of this function is tested in core/test/core-lib.el, this
|
||||||
;; only tests the evil-mode-specific functionality.
|
;; only tests the evil-mode-specific functionality.
|
||||||
|
|
|
@ -6,6 +6,11 @@
|
||||||
(expand-file-name "templates/" (file-name-directory load-file-name))
|
(expand-file-name "templates/" (file-name-directory load-file-name))
|
||||||
"The path to a directory of yasnippet folders to use for file templates.")
|
"The path to a directory of yasnippet folders to use for file templates.")
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Plugins
|
||||||
|
;;
|
||||||
|
|
||||||
(def-package! autoinsert ; built-in
|
(def-package! autoinsert ; built-in
|
||||||
:defer 1
|
:defer 1
|
||||||
:init
|
:init
|
||||||
|
@ -18,12 +23,16 @@
|
||||||
(auto-insert-mode 1)
|
(auto-insert-mode 1)
|
||||||
|
|
||||||
(defun +file-templates--expand (key &optional mode project-only)
|
(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)
|
(when (if project-only (doom-project-p) t)
|
||||||
(require 'yasnippet)
|
(require 'yasnippet)
|
||||||
(unless yas-minor-mode (yas-minor-mode-on))
|
(unless yas-minor-mode
|
||||||
|
(yas-minor-mode-on))
|
||||||
(when (and yas-minor-mode
|
(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 (featurep 'evil) evil-mode)
|
||||||
(and yas--active-field-overlay
|
(and yas--active-field-overlay
|
||||||
(overlay-buffer yas--active-field-overlay)
|
(overlay-buffer yas--active-field-overlay)
|
||||||
|
@ -56,10 +65,9 @@
|
||||||
("\\.el$" "__initfile" emacs-lisp-mode)
|
("\\.el$" "__initfile" emacs-lisp-mode)
|
||||||
("/.dir-locals.el$" nil)
|
("/.dir-locals.el$" nil)
|
||||||
("-test\\.el$" "__" emacs-ert-mode)
|
("-test\\.el$" "__" emacs-ert-mode)
|
||||||
("/.emacs.d/.+\\.el$" "__doom-module" emacs-lisp-mode)
|
("/\\(?:.emacs.d\\|doom-emacs\\)?/.+\\.el$" "__doom-module" emacs-lisp-mode)
|
||||||
("/.emacs.d/.+/packages\\.el$" "__doom-packages" emacs-lisp-mode)
|
("/\\(?:.emacs.d\\|doom-emacs\\)?/.+/packages\\.el$" "__doom-packages" emacs-lisp-mode)
|
||||||
("/.emacs.d/.+/test\\.el$" "__doom-test" emacs-lisp-mode)
|
("/\\(?:.emacs.d\\|doom-emacs\\)?/.+/test/.+\\.el$" "__doom-test" emacs-lisp-mode)
|
||||||
("/.emacs.d/.+/README\\.org$" "__doom-readme" org-mode)
|
|
||||||
(snippet-mode "__" snippet-mode)
|
(snippet-mode "__" snippet-mode)
|
||||||
;; Go
|
;; Go
|
||||||
("\\.go$" "__.go" go-mode)
|
("\\.go$" "__.go" go-mode)
|
||||||
|
@ -83,6 +91,7 @@
|
||||||
("\\.md$" "__" markdown-mode)
|
("\\.md$" "__" markdown-mode)
|
||||||
;; Org
|
;; Org
|
||||||
("\\.org$" "__" org-mode)
|
("\\.org$" "__" org-mode)
|
||||||
|
("/\\(?:.emacs.d\\|doom-emacs\\)?/.+/README\\.org$" "__doom-readme" org-mode)
|
||||||
;; PHP
|
;; PHP
|
||||||
("\\.php$" "__" php-mode)
|
("\\.php$" "__" php-mode)
|
||||||
("\\.class\\.php$" "__.class.php" php-mode)
|
("\\.class\\.php$" "__.class.php" php-mode)
|
||||||
|
@ -110,5 +119,5 @@
|
||||||
("/\\(index\\|main\\)\\.slim$" "__" slim-mode)
|
("/\\(index\\|main\\)\\.slim$" "__" slim-mode)
|
||||||
;; Shell scripts
|
;; Shell scripts
|
||||||
("\\.z?sh$" "__" sh-mode)
|
("\\.z?sh$" "__" sh-mode)
|
||||||
|
("\\.fish$" "__" fish-mode)
|
||||||
("\\.zunit$" "__zunit" sh-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
|
$0
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
;; -*- no-byte-compile: t; -*-
|
;; -*- no-byte-compile: t; -*-
|
||||||
;;; `(file-relative-name buffer-file-name doom-modules-dir)`
|
;;; `(file-relative-name buffer-file-truename doom-modules-dir)`
|
||||||
|
|
||||||
$0
|
$0
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
;; -*- no-byte-compile: t; -*-
|
;; -*- no-byte-compile: t; -*-
|
||||||
;;; `(file-relative-name buffer-file-name doom-modules-dir)`
|
;;; `(file-relative-name buffer-file-truename doom-modules-dir)`
|
||||||
|
|
||||||
$0
|
$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)
|
(cond ((plist-member +jump-current-functions :documentation)
|
||||||
(+jump-to :documentation identifier))
|
(+jump-to :documentation identifier))
|
||||||
(t
|
(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)
|
(defun +jump--online-get-provider (&optional force-p)
|
||||||
(or (and (not 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
|
"An alist that maps online resources to their search url or a function that
|
||||||
produces an url. Used by `+jump/online'.")
|
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.")
|
"Function to use to open search urls.")
|
||||||
|
|
||||||
(defvar +jump-function-alist nil
|
(defvar +jump-function-alist nil
|
||||||
|
@ -82,6 +82,18 @@ properties:
|
||||||
;; Packages
|
;; 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
|
(def-package! dumb-jump
|
||||||
:commands (dumb-jump-go dumb-jump-quick-look
|
:commands (dumb-jump-go dumb-jump-quick-look
|
||||||
dumb-jump-back dumb-jump-result-follow)
|
dumb-jump-back dumb-jump-result-follow)
|
||||||
|
@ -92,28 +104,3 @@ properties:
|
||||||
((featurep! :completion helm) 'helm)
|
((featurep! :completion helm) 'helm)
|
||||||
(t 'popup))))
|
(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
|
;;; feature/jump/packages.el
|
||||||
|
|
||||||
(package! dumb-jump)
|
(package! dumb-jump)
|
||||||
(package! gxref)
|
(when (featurep! :completion ivy)
|
||||||
;; (package! ggtags)
|
(package! ivy-xref))
|
||||||
;; (cond ((featurep! :completion ivy)
|
(when (featurep! :completion helm)
|
||||||
;; (package! counsel-gtags))
|
(package! helm-xref))
|
||||||
;; ((featurep! :completion helm)
|
|
||||||
;; (package! helm-gtags)))
|
|
||||||
|
|
||||||
|
|
|
@ -8,20 +8,5 @@ This module adds snippets to Emacs, powered by yasnippet.
|
||||||
* Install
|
* Install
|
||||||
There are no extra dependencies for this module.
|
There are no extra dependencies for this module.
|
||||||
|
|
||||||
By default, this module uses the snippet library included with yasnippet.
|
By default, =private/default= installs a snippet library tailored exclusively
|
||||||
|
for Doom Emacs.
|
||||||
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
|
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,6 @@
|
||||||
(defvar yas-minor-mode-map (make-sparse-keymap))
|
(defvar yas-minor-mode-map (make-sparse-keymap))
|
||||||
|
|
||||||
:init
|
:init
|
||||||
(setq yas-snippet-dirs '(yas-installed-snippets-dir))
|
|
||||||
|
|
||||||
;; Ensure `yas-reload-all' is called as late as possible. Other modules could
|
;; Ensure `yas-reload-all' is called as late as possible. Other modules could
|
||||||
;; have additional configuration for yasnippet. For example, file-templates.
|
;; have additional configuration for yasnippet. For example, file-templates.
|
||||||
(add-transient-hook! 'yas-minor-mode-hook (yas-reload-all))
|
(add-transient-hook! 'yas-minor-mode-hook (yas-reload-all))
|
||||||
|
@ -21,11 +19,9 @@
|
||||||
#'yas-minor-mode-on)
|
#'yas-minor-mode-on)
|
||||||
|
|
||||||
:config
|
:config
|
||||||
(setq yas-verbosity 0
|
(setq yas-verbosity (if doom-debug-mode 3 0)
|
||||||
yas-indent-line 'auto
|
|
||||||
yas-also-auto-indent-first-line t
|
yas-also-auto-indent-first-line t
|
||||||
yas-prompt-functions '(yas-completing-prompt yas-ido-prompt yas-no-prompt)
|
yas-prompt-functions (delq 'yas-dropdown-prompt yas-prompt-functions)
|
||||||
yas-use-menu nil
|
|
||||||
;; Allow nested snippets
|
;; Allow nested snippets
|
||||||
yas-triggers-in-field t)
|
yas-triggers-in-field t)
|
||||||
|
|
||||||
|
@ -40,27 +36,8 @@
|
||||||
;; fix an error caused by smartparens interfering with yasnippet bindings
|
;; fix an error caused by smartparens interfering with yasnippet bindings
|
||||||
(advice-add #'yas-expand :before #'sp-remove-active-pair-overlay)
|
(advice-add #'yas-expand :before #'sp-remove-active-pair-overlay)
|
||||||
|
|
||||||
(after! evil
|
;; Exit snippets on ESC from normal mode
|
||||||
;; Exit snippets on ESC in normal mode
|
(add-hook '+evil-esc-hook #'yas-exit-all-snippets))
|
||||||
(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)))
|
|
||||||
|
|
||||||
|
|
||||||
(def-package! auto-yasnippet
|
(def-package! auto-yasnippet
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
;;; feature/version-control/+git.el -*- lexical-binding: t; -*-
|
;;; feature/version-control/+git.el -*- lexical-binding: t; -*-
|
||||||
;;;###if (not (featurep! -git))
|
;;;###if (not (featurep! -git))
|
||||||
|
|
||||||
|
(when (featurep! :feature evil)
|
||||||
|
(add-hook 'git-commit-mode-hook #'evil-insert-state))
|
||||||
|
|
||||||
|
|
||||||
(def-package! gitconfig-mode
|
(def-package! gitconfig-mode
|
||||||
:mode "/\\.?git/?config$"
|
:mode "/\\.?git/?config$"
|
||||||
:mode "/\\.gitmodules$")
|
:mode "/\\.gitmodules$")
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
#+TITLE: :feature workspaces
|
#+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
|
#+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
|
#+end_quote
|
||||||
|
|
||||||
* Table of Contents :TOC:
|
* Table of Contents :TOC:
|
||||||
|
@ -22,25 +28,33 @@ This module has no additional dependencies.
|
||||||
|
|
||||||
* Features
|
* Features
|
||||||
** Isolated buffer-list
|
** 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
|
** Automatic workspaces
|
||||||
A workspace is automatically created (and switched to) when you:
|
A workspace is automatically created (and switched to) when you:
|
||||||
|
|
||||||
+ Create a new frame (with =make-frame=; bound to =M-N= by default)
|
+ 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)
|
+ Switch to a project using ~projectile-switch-project~.
|
||||||
|
|
||||||
** Session persistence
|
** 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
|
** 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
|
* Appendix
|
||||||
** Commands & Keybindings
|
** 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 |
|
| command | key / ex command | description |
|
||||||
|---------------------------+----------------------------+------------------------------------------------------------|
|
|---------------------------+----------------------------+------------------------------------------------------------|
|
||||||
|
|
|
@ -310,7 +310,7 @@ workspace to delete."
|
||||||
(doom/kill-all-buffers)
|
(doom/kill-all-buffers)
|
||||||
(let ((fallback-buf (doom-fallback-buffer)))
|
(let ((fallback-buf (doom-fallback-buffer)))
|
||||||
(switch-to-buffer fallback-buf)
|
(switch-to-buffer fallback-buf)
|
||||||
(doom/cleanup-buffers)))
|
(doom/cleanup-session)))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun +workspace/kill-session-and-quit ()
|
(defun +workspace/kill-session-and-quit ()
|
||||||
|
|
|
@ -47,10 +47,22 @@ renamed.")
|
||||||
|
|
||||||
;; per-frame and per-project workspaces
|
;; per-frame and per-project workspaces
|
||||||
(setq persp-init-new-frame-behaviour-override nil
|
(setq persp-init-new-frame-behaviour-override nil
|
||||||
persp-interactive-init-frame-behaviour-override #'+workspace-on-new-frame
|
persp-interactive-init-frame-behaviour-override #'+workspace-on-new-frame)
|
||||||
projectile-switch-project-action #'projectile-find-file)
|
|
||||||
(add-hook 'delete-frame-functions #'+workspaces|delete-associated-workspace-maybe)
|
(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
|
;; only auto-save when real buffers are present
|
||||||
(advice-add #'persp-asave-on-exit :around #'+workspaces*autosave-real-buffers)
|
(advice-add #'persp-asave-on-exit :around #'+workspaces*autosave-real-buffers)
|
||||||
|
@ -68,7 +80,10 @@ renamed.")
|
||||||
(remove-hook 'delayed-warnings-hook #'display-delayed-warnings)
|
(remove-hook 'delayed-warnings-hook #'display-delayed-warnings)
|
||||||
(defun +workspaces|init (&optional frame)
|
(defun +workspaces|init (&optional frame)
|
||||||
(unless persp-mode
|
(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))))
|
(let ((frame (or frame (selected-frame))))
|
||||||
(unless noninteractive
|
(unless noninteractive
|
||||||
;; The default perspective persp-mode makes (defined by
|
;; The default perspective persp-mode makes (defined by
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
(require! :feature workspaces)
|
(require! :feature workspaces)
|
||||||
|
|
||||||
(defmacro -with-workspace! (buffer-args &rest body)
|
(defmacro with-workspace!! (buffer-args &rest body)
|
||||||
(declare (indent defun))
|
(declare (indent defun))
|
||||||
(let ((buffers
|
(let ((buffers
|
||||||
(cl-loop for bsym in buffer-args
|
(cl-loop for bsym in buffer-args
|
||||||
|
@ -27,14 +27,19 @@
|
||||||
|
|
||||||
;;
|
;;
|
||||||
(def-test! init
|
(def-test! init
|
||||||
(-with-workspace! ()
|
(with-workspace!! ()
|
||||||
(should (equal (+workspace-current-name) +workspaces-main))))
|
(should (equal (+workspace-current-name) +workspaces-main))))
|
||||||
|
|
||||||
(def-test! advice
|
(def-test! auto-add-buffer-to-persp
|
||||||
(should (advice-member-p #'+workspaces*auto-add-buffer #'switch-to-buffer)))
|
(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
|
(def-test! current
|
||||||
(-with-workspace! ()
|
(with-workspace!! ()
|
||||||
(should (equal (+workspace-current-name) +workspaces-main))
|
(should (equal (+workspace-current-name) +workspaces-main))
|
||||||
(should (+workspace-exists-p +workspaces-main))
|
(should (+workspace-exists-p +workspaces-main))
|
||||||
(let ((workspace (+workspace-get +workspaces-main))
|
(let ((workspace (+workspace-get +workspaces-main))
|
||||||
|
@ -45,7 +50,7 @@
|
||||||
(should (equal workspace current-workspace)))))
|
(should (equal workspace current-workspace)))))
|
||||||
|
|
||||||
(def-test! workspace-list
|
(def-test! workspace-list
|
||||||
(-with-workspace! ()
|
(with-workspace!! ()
|
||||||
(should (equal (+workspace-list-names)
|
(should (equal (+workspace-list-names)
|
||||||
(list (+workspace-current-name))))
|
(list (+workspace-current-name))))
|
||||||
(should (equal (+workspace-list)
|
(should (equal (+workspace-list)
|
||||||
|
@ -53,7 +58,7 @@
|
||||||
|
|
||||||
(def-test! workspace-crud
|
(def-test! workspace-crud
|
||||||
"Creating, reading, updating and deleting workspaces."
|
"Creating, reading, updating and deleting workspaces."
|
||||||
(-with-workspace! ()
|
(with-workspace!! ()
|
||||||
(let ((new-workspace-name "*new-test*")
|
(let ((new-workspace-name "*new-test*")
|
||||||
(renamed-workspace-name "*old-test*"))
|
(renamed-workspace-name "*old-test*"))
|
||||||
(should (+workspace-new new-workspace-name))
|
(should (+workspace-new new-workspace-name))
|
||||||
|
@ -67,14 +72,14 @@
|
||||||
(should (= (length (+workspace-list-names)) 1)))))
|
(should (= (length (+workspace-list-names)) 1)))))
|
||||||
|
|
||||||
(def-test! workspace-switch
|
(def-test! workspace-switch
|
||||||
(-with-workspace! ()
|
(with-workspace!! ()
|
||||||
(let ((new-workspace-name "*new-test*"))
|
(let ((new-workspace-name "*new-test*"))
|
||||||
(should-error (+workspace-switch new-workspace-name))
|
(should-error (+workspace-switch new-workspace-name))
|
||||||
(should (+workspace-switch new-workspace-name t))
|
(should (+workspace-switch new-workspace-name t))
|
||||||
(should (equal (+workspace-current-name) new-workspace-name)))))
|
(should (equal (+workspace-current-name) new-workspace-name)))))
|
||||||
|
|
||||||
(def-test! buffer-list
|
(def-test! buffer-list
|
||||||
(-with-workspace! (a b)
|
(with-workspace!! (a b)
|
||||||
(let ((c (get-buffer-create "c"))
|
(let ((c (get-buffer-create "c"))
|
||||||
(d (get-buffer-create "d")))
|
(d (get-buffer-create "d")))
|
||||||
(should (+workspace-contains-buffer-p a))
|
(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~)
|
+ Code completion (~company-irony~)
|
||||||
+ eldoc support (~irony-eldoc~)
|
+ eldoc support (~irony-eldoc~)
|
||||||
+ Syntax-checking (~flycheck-irony~)
|
+ 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]])
|
+ 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]])
|
+ 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.
|
+ Several improvements to C++11 indentation and syntax highlighting.
|
||||||
|
|
||||||
#+begin_quote
|
#+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
|
#+end_quote
|
||||||
|
|
||||||
* Table of Contents :TOC:
|
* Table of Contents :TOC:
|
||||||
- [[#install][Install]]
|
- [[#install][Install]]
|
||||||
- [[#macos][MacOS]]
|
- [[#irony-server][irony-server]]
|
||||||
- [[#arch-linux][Arch Linux]]
|
- [[#rtags][rtags]]
|
||||||
|
- [[#configure][Configure]]
|
||||||
|
- [[#compile-settings][Compile settings]]
|
||||||
|
|
||||||
* Install
|
* 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:
|
Due to linking issues, MacOS users must compile irony-server manually:
|
||||||
|
|
||||||
#+BEGIN_SRC sh :tangle (if (doom-system-os 'macos) "yes")
|
#+BEGIN_SRC sh :tangle (if (doom-system-os 'macos) "yes")
|
||||||
|
@ -49,10 +59,46 @@ popd
|
||||||
rm -rf irony-mode
|
rm -rf irony-mode
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
** Arch Linux
|
*** Arch Linux
|
||||||
#+BEGIN_SRC sh :tangle (if (doom-system-os 'arch) "yes")
|
#+BEGIN_SRC sh :tangle (if (doom-system-os 'arch) "yes")
|
||||||
sudo pacman --needed --noconfirm -S clang cmake
|
sudo pacman --needed --noconfirm -S clang cmake
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
Then run ~M-x irony-install-server~ in Emacs.
|
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; -*-
|
;;; 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
|
;;;###autoload
|
||||||
(defun +cc*align-lambda-arglist (orig-fun &rest args)
|
(defun +cc*align-lambda-arglist (orig-fun &rest args)
|
||||||
"Improve indentation of continued C++11 lambda function opened as argument."
|
"Improve indentation of continued C++11 lambda function opened as argument."
|
||||||
|
@ -66,8 +85,8 @@
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun +cc|irony-init-compile-options ()
|
(defun +cc|irony-init-compile-options ()
|
||||||
"Initialize compiler options for irony-mode. It searches for the nearest
|
"Initialize compiler options for irony-mode. It searches for the nearest
|
||||||
compilation database and initailizes it. If none was found, it uses
|
compilation database and initailizes it, otherwise falling back on
|
||||||
`+cc-c++-compiler-options'.
|
`+cc-default-compiler-options' and `+cc-default-include-paths'.
|
||||||
|
|
||||||
See https://github.com/Sarcasm/irony-mode#compilation-database for details on
|
See https://github.com/Sarcasm/irony-mode#compilation-database for details on
|
||||||
compilation dbs."
|
compilation dbs."
|
||||||
|
@ -75,8 +94,8 @@ compilation dbs."
|
||||||
(require 'irony-cdb)
|
(require 'irony-cdb)
|
||||||
(unless (irony-cdb-autosetup-compile-options)
|
(unless (irony-cdb-autosetup-compile-options)
|
||||||
(irony-cdb--update-compile-options
|
(irony-cdb--update-compile-options
|
||||||
(append (delq nil (cdr-safe (assq major-mode +cc-compiler-options)))
|
(append (delq nil (cdr-safe (assq major-mode +cc-default-compiler-options)))
|
||||||
(cl-loop for path in +cc-include-paths
|
(cl-loop for path in +cc-default-include-paths
|
||||||
nconc (list "-I" path)))
|
nconc (list "-I" path)))
|
||||||
(doom-project-root)))))
|
(doom-project-root)))))
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
;;; lang/cc/config.el --- c, c++, and obj-c -*- lexical-binding: t; -*-
|
;;; lang/cc/config.el --- c, c++, and obj-c -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
(defvar +cc-include-paths (list "include/")
|
(defvar +cc-default-include-paths (list "include/")
|
||||||
"A list of paths, relative to a project root, to search for headers in C/C++.
|
"A list of default paths, relative to a project root, to search for headers in
|
||||||
Paths can be absolute.
|
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
|
(defvar +cc-default-compiler-options
|
||||||
knows where to look for headers.")
|
|
||||||
|
|
||||||
(defvar +cc-compiler-options
|
|
||||||
`((c-mode . nil)
|
`((c-mode . nil)
|
||||||
(c++-mode
|
(c++-mode
|
||||||
. ,(list "-std=c++11" ; use C++11 by default
|
. ,(list "-std=c++11" ; use C++11 by default
|
||||||
|
@ -112,12 +110,16 @@ compilation database is present in the project.")
|
||||||
:after cc-mode
|
:after cc-mode
|
||||||
:commands irony-install-server
|
:commands irony-install-server
|
||||||
:preface (setq irony-server-install-prefix (concat doom-etc-dir "irony-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
|
:config
|
||||||
(unless (file-directory-p irony-server-install-prefix)
|
(unless (file-directory-p irony-server-install-prefix)
|
||||||
(warn "irony-mode: server isn't installed; run M-x irony-install-server"))
|
(warn "irony-mode: server isn't installed; run M-x irony-install-server"))
|
||||||
;; Initialize compilation database, if present. Otherwise, fall back on
|
;; 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))
|
(add-hook 'irony-mode-hook #'+cc|irony-init-compile-options))
|
||||||
|
|
||||||
(def-package! irony-eldoc
|
(def-package! irony-eldoc
|
||||||
|
@ -144,7 +146,8 @@ compilation database is present in the project.")
|
||||||
;;
|
;;
|
||||||
|
|
||||||
(def-package! cmake-mode
|
(def-package! cmake-mode
|
||||||
:mode "CMakeLists\\.txt$"
|
:mode "/CMakeLists\\.txt$"
|
||||||
|
:mode "\\.cmake\\$"
|
||||||
:config
|
:config
|
||||||
(set! :company-backend 'cmake-mode '(company-cmake company-yasnippet)))
|
(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
|
||||||
(def-package! company-cmake :after cmake-mode)
|
: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
|
(def-package! company-glsl
|
||||||
|
:when (featurep! :completion company)
|
||||||
:after glsl-mode
|
:after glsl-mode
|
||||||
:config
|
:config
|
||||||
(if (executable-find "glslangValidator")
|
(if (executable-find "glslangValidator")
|
||||||
(warn "glsl-mode: couldn't find glslangValidator, disabling company-glsl")
|
(warn "glsl-mode: couldn't find glslangValidator, disabling company-glsl")
|
||||||
(set! :company-backend 'glsl-mode '(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! glsl-mode)
|
||||||
(package! irony)
|
(package! irony)
|
||||||
(package! irony-eldoc)
|
(package! irony-eldoc)
|
||||||
(package! opencl-mode)
|
|
||||||
(package! modern-cpp-font-lock)
|
(package! modern-cpp-font-lock)
|
||||||
|
(package! opencl-mode)
|
||||||
|
|
||||||
(when (featurep! :feature syntax-checker)
|
(when (featurep! :feature syntax-checker)
|
||||||
(package! flycheck-irony))
|
(package! flycheck-irony))
|
||||||
|
@ -19,3 +19,8 @@
|
||||||
(package! company-irony)
|
(package! company-irony)
|
||||||
(package! company-irony-c-headers))
|
(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
|
"Evaluate a region and print it to the echo area (if one line long), otherwise
|
||||||
to a pop up buffer."
|
to a pop up buffer."
|
||||||
(require 'pp)
|
(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*"))
|
(buf (get-buffer-create "*doom eval*"))
|
||||||
(inhibit-read-only t)
|
(inhibit-read-only t)
|
||||||
lines)
|
lines)
|
||||||
|
|
|
@ -10,19 +10,12 @@
|
||||||
meghanada-use-eldoc t
|
meghanada-use-eldoc t
|
||||||
meghanada-use-auto-start 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
|
(set! :jump 'java-mode
|
||||||
:definition #'meghanada-jump-declaration
|
:definition #'meghanada-jump-declaration
|
||||||
:references #'meghanada-reference)
|
:references #'meghanada-reference)
|
||||||
|
|
||||||
|
(add-hook! 'meghanada-mode-hook #'(flycheck-mode eldoc-mode))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
(def-menu! +java/refactor-menu
|
(def-menu! +java/refactor-menu
|
||||||
"Refactoring commands for `java-mode' buffers."
|
"Refactoring commands for `java-mode' buffers."
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
;;; lang/java/config.el -*- lexical-binding: t; -*-
|
;;; lang/java/config.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
(add-hook 'java-mode-hook #'rainbow-delimiters-mode)
|
||||||
|
|
||||||
(cond ((featurep! +meghanada) (load! +meghanada))
|
(cond ((featurep! +meghanada) (load! +meghanada))
|
||||||
((featurep! +eclim) ; FIXME lang/java +eclim
|
((featurep! +eclim) ; FIXME lang/java +eclim
|
||||||
;;(load! +eclim)
|
;;(load! +eclim)
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
;; + `+org-attach/url'
|
;; + `+org-attach/url'
|
||||||
;; + :org [FILE/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).")
|
"Where to store attachments (relative to current org file).")
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
(advice-add #'org-download-enable :override #'ignore)
|
(advice-add #'org-download-enable :override #'ignore)
|
||||||
:config
|
: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-heading-lvl nil
|
||||||
org-download-timestamp "_%Y%m%d_%H%M%S")
|
org-download-timestamp "_%Y%m%d_%H%M%S")
|
||||||
|
|
||||||
|
@ -61,12 +61,12 @@
|
||||||
|
|
||||||
;;
|
;;
|
||||||
(after! org
|
(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)))
|
(push (car (last (split-string +org-attach-dir "/" t)))
|
||||||
projectile-globally-ignored-directories)
|
projectile-globally-ignored-directories)
|
||||||
|
|
||||||
(after! recentf
|
(after! recentf
|
||||||
(push (format "%s.+$" (regexp-quote +org-attach-dir))
|
(push (format "%s.+$" (regexp-quote org-attach-directory))
|
||||||
recentf-exclude)))
|
recentf-exclude)))
|
||||||
|
|
||||||
|
|
|
@ -10,16 +10,19 @@
|
||||||
;; anywhere I can call org-capture (whether or not Emacs is open/running),
|
;; anywhere I can call org-capture (whether or not Emacs is open/running),
|
||||||
;; like, say, from qutebrowser, vimperator, dmenu or a global keybinding.
|
;; 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"
|
(defvar +org-default-notes-file "notes.org"
|
||||||
"TODO")
|
"TODO")
|
||||||
|
|
||||||
(defvar org-capture-templates
|
(defvar org-capture-templates
|
||||||
'(("t" "Todo" entry
|
'(("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%i" :prepend t :kill-buffer t)
|
||||||
|
|
||||||
("n" "Notes" entry
|
("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)))
|
"* %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)
|
(defun +org-attach-download-dnd (uri action)
|
||||||
"TODO"
|
"TODO"
|
||||||
(if (eq major-mode 'org-mode)
|
(if (eq major-mode 'org-mode)
|
||||||
(+org-attach:url uri)
|
(+org-attach/uri uri)
|
||||||
(let ((dnd-protocol-alist
|
(let ((dnd-protocol-alist
|
||||||
(rassq-delete-all '+org-attach-download-dnd
|
(rassq-delete-all '+org-attach-download-dnd
|
||||||
(copy-alist dnd-protocol-alist))))
|
(copy-alist dnd-protocol-alist))))
|
||||||
|
@ -98,7 +98,7 @@ the cursor."
|
||||||
(delete-region (match-beginning 0) (match-end 0))
|
(delete-region (match-beginning 0) (match-end 0))
|
||||||
(newline))
|
(newline))
|
||||||
(cond ((image-type-from-file-name filename)
|
(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)))
|
(setq filename (file-relative-name filename +org-dir)))
|
||||||
(insert
|
(insert
|
||||||
(concat (if (= org-download-image-html-width 0)
|
(concat (if (= org-download-image-html-width 0)
|
||||||
|
@ -113,9 +113,9 @@ the cursor."
|
||||||
(t
|
(t
|
||||||
(insert
|
(insert
|
||||||
(format "%s [[./%s][%s]] "
|
(format "%s [[./%s][%s]] "
|
||||||
(org-attach--icon filename)
|
(+org-attach--icon filename)
|
||||||
(file-relative-name filename buffer-file-name)
|
(file-relative-name filename buffer-file-name)
|
||||||
(file-name-nondirectory (directory-file-name rel-path)))))))
|
(file-name-nondirectory (directory-file-name filename)))))))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun +org-attach*relative-to-attach-dir (orig-fn &rest args)
|
(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)))
|
(let* ((context (save-match-data (org-element-context)))
|
||||||
(file (org-link-unescape (org-element-property :path context)))
|
(file (org-link-unescape (org-element-property :path context)))
|
||||||
(default-directory
|
(default-directory
|
||||||
(if (string-prefix-p
|
(if (file-in-directory-p file org-attach-directory)
|
||||||
(concat "./" (car (last (split-string +org-attach-dir "/" t))))
|
|
||||||
file)
|
|
||||||
+org-dir
|
+org-dir
|
||||||
default-directory)))
|
default-directory)))
|
||||||
(apply orig-fn args))
|
(apply orig-fn args))
|
||||||
|
|
|
@ -28,8 +28,7 @@
|
||||||
:commands org-crypt-use-before-save-magic
|
:commands org-crypt-use-before-save-magic
|
||||||
:config
|
:config
|
||||||
(setq org-tags-exclude-from-inheritance '("crypt")
|
(setq org-tags-exclude-from-inheritance '("crypt")
|
||||||
org-crypt-key user-mail-address
|
org-crypt-key user-mail-address))
|
||||||
epa-file-encrypt-to user-mail-address))
|
|
||||||
|
|
||||||
(def-package! org-bullets
|
(def-package! org-bullets
|
||||||
:commands org-bullets-mode)
|
:commands org-bullets-mode)
|
||||||
|
@ -91,12 +90,13 @@ unfold to point on startup."
|
||||||
(sp--looking-at-p "\\s-*]")))
|
(sp--looking-at-p "\\s-*]")))
|
||||||
|
|
||||||
;; make delimiter auto-closing a little more conservative
|
;; make delimiter auto-closing a little more conservative
|
||||||
|
(after! smartparens
|
||||||
(sp-with-modes 'org-mode
|
(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-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))
|
||||||
(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 +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))
|
||||||
(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 ()
|
(defun +org|enable-auto-reformat-tables ()
|
||||||
"Realign tables exiting insert mode (`evil-mode')."
|
"Realign tables exiting insert mode (`evil-mode')."
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
;; -*- no-byte-compile: t; -*-
|
;; -*- no-byte-compile: t; -*-
|
||||||
;;; lang/org/packages.el
|
;;; lang/org/packages.el
|
||||||
|
|
||||||
;; NOTE This is an insecure source, but unavoidable if we want org 9.0+ (which
|
(when (version< emacs-version "26.1")
|
||||||
;; this module requires). orgmode.org offers no secure access to this repo. If
|
;; We want org 9.1.x, but the org packaged with Emacs 25.x and under is 8.x.
|
||||||
;; this bothers you, comment out this `package!' block and download
|
;; The only secure (and reasonably trustworthy) source for this is via
|
||||||
;; org-plus-contrib from orgmode.org.
|
;; emacsmirror. Emacs 26+ comes with Org 9.1.4.
|
||||||
(package! org-plus-contrib :recipe (:fetcher git :url "http://orgmode.org/org-mode.git"))
|
(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! org-bullets :recipe (:fetcher github :repo "hlissner/org-bullets"))
|
||||||
(package! toc-org)
|
(package! toc-org)
|
||||||
|
|
|
@ -1,40 +1,40 @@
|
||||||
;; -*- no-byte-compile: t; -*-
|
;; -*- no-byte-compile: t; -*-
|
||||||
;;; lang/org/test/autoload-org.el
|
;;; lang/org/test/autoload-org.el
|
||||||
|
|
||||||
(defmacro should-org-buffer! (source expected &rest body)
|
(defmacro should-org-buffer!! (source expected &rest body)
|
||||||
`(should-buffer! ,source ,expected
|
`(should-buffer!! ,source ,expected
|
||||||
(org-mode)
|
(org-mode)
|
||||||
,@body))
|
,@body))
|
||||||
|
|
||||||
|
;;
|
||||||
;; `+org/insert-item'
|
;; `+org/insert-item'
|
||||||
(def-test! insert-item-h1
|
(def-test! insert-item-h1
|
||||||
"Should append/prepend new first-level headers with an extra newline."
|
"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))
|
(+org/insert-item 'below))
|
||||||
(should-org-buffer! ("* {0}Header") ("* {|}\n\n* Header")
|
(should-org-buffer!! ("* {0}Header") ("* {|}\n\n* Header")
|
||||||
(+org/insert-item 'above)))
|
(+org/insert-item 'above)))
|
||||||
|
|
||||||
(def-test! insert-item-h2
|
(def-test! insert-item-h2
|
||||||
"Should append/prepend new second-level (and higher) headers without an extra
|
"Should append/prepend new second-level (and higher) headers without an extra
|
||||||
newline."
|
newline."
|
||||||
(should-org-buffer! ("** {0}Header") ("** Header\n** {|}")
|
(should-org-buffer!! ("** {0}Header") ("** Header\n** {|}")
|
||||||
(+org/insert-item 'below))
|
(+org/insert-item 'below))
|
||||||
(should-org-buffer! ("** {0}Header") ("** {|}\n** Header")
|
(should-org-buffer!! ("** {0}Header") ("** {|}\n** Header")
|
||||||
(+org/insert-item 'above)))
|
(+org/insert-item 'above)))
|
||||||
|
|
||||||
(def-test! insert-item-plain-list
|
(def-test! insert-item-plain-list
|
||||||
"Should append/prepend new second-level (and higher) headers without an extra
|
"Should append/prepend new second-level (and higher) headers without an extra
|
||||||
newline."
|
newline."
|
||||||
(should-org-buffer! ("+ {0}List item") ("+ List item\n+ {|}")
|
(should-org-buffer!! ("+ {0}List item") ("+ List item\n+ {|}")
|
||||||
(+org/insert-item 'below))
|
(+org/insert-item 'below))
|
||||||
(should-org-buffer! ("+ {0}List item"
|
(should-org-buffer!! ("+ {0}List item"
|
||||||
" + Sub item")
|
" + Sub item")
|
||||||
("+ List item"
|
("+ List item"
|
||||||
" + Sub item"
|
" + Sub item"
|
||||||
"+ {|}")
|
"+ {|}")
|
||||||
(+org/insert-item 'below))
|
(+org/insert-item 'below))
|
||||||
(should-org-buffer! ("+ {0}List item"
|
(should-org-buffer!! ("+ {0}List item"
|
||||||
"+ Next item")
|
"+ Next item")
|
||||||
("+ List item"
|
("+ List item"
|
||||||
"+ {|}"
|
"+ {|}"
|
||||||
|
|
|
@ -5,3 +5,5 @@
|
||||||
(require! :lang org)
|
(require! :lang org)
|
||||||
|
|
||||||
(require 'org (locate-library "org" nil doom--package-load-path))
|
(require 'org (locate-library "org" nil doom--package-load-path))
|
||||||
|
|
||||||
|
;;
|
||||||
|
|
|
@ -84,8 +84,7 @@
|
||||||
:config
|
:config
|
||||||
(unless (executable-find "phpctags")
|
(unless (executable-find "phpctags")
|
||||||
(warn "php-mode: phpctags isn't installed, auto-completion will be gimped"))
|
(warn "php-mode: phpctags isn't installed, auto-completion will be gimped"))
|
||||||
|
(setq ac-php-tags-path (concat doom-cache-dir "ac-php/")))
|
||||||
(setq ac-php-tags-path (concat doom-etc-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.
|
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)
|
(defalias 'ex! 'evil-ex-define-cmd)
|
||||||
|
|
||||||
;;; Commands defined elsewhere
|
;;; Commands defined elsewhere
|
||||||
;;(ex! "al[ign]" #'+evil:align)
|
;;(ex! "al[ign]" #'+evil:align)
|
||||||
;;(ex! "g[lobal]" #'+evil:global)
|
;;(ex! "g[lobal]" #'+evil:global)
|
||||||
|
|
||||||
;;; Custom commands
|
;;; Custom commands
|
||||||
;; Editing
|
;; Editing
|
||||||
(ex! "@" #'+evil:macro-on-all-lines) ; TODO Test me
|
(ex! "@" #'+evil:macro-on-all-lines) ; TODO Test me
|
||||||
(ex! "al[ign]" #'+evil:align)
|
(ex! "al[ign]" #'+evil:align)
|
||||||
|
@ -16,7 +16,6 @@
|
||||||
(ex! "iedit" #'evil-multiedit-ex-match)
|
(ex! "iedit" #'evil-multiedit-ex-match)
|
||||||
(ex! "na[rrow]" #'+evil:narrow-buffer)
|
(ex! "na[rrow]" #'+evil:narrow-buffer)
|
||||||
(ex! "retab" #'+evil:retab)
|
(ex! "retab" #'+evil:retab)
|
||||||
|
|
||||||
;; External resources
|
;; External resources
|
||||||
;; TODO (ex! "db" #'doom:db)
|
;; TODO (ex! "db" #'doom:db)
|
||||||
;; TODO (ex! "dbu[se]" #'doom:db-select)
|
;; TODO (ex! "dbu[se]" #'doom:db-select)
|
||||||
|
@ -29,7 +28,6 @@
|
||||||
(ex! "t[mux]" #'+tmux:run) ; send to tmux
|
(ex! "t[mux]" #'+tmux:run) ; send to tmux
|
||||||
(ex! "tcd" #'+tmux:cd-here) ; cd to default-directory in tmux
|
(ex! "tcd" #'+tmux:cd-here) ; cd to default-directory in tmux
|
||||||
(ex! "x" #'doom/open-project-scratch-buffer)
|
(ex! "x" #'doom/open-project-scratch-buffer)
|
||||||
|
|
||||||
;; GIT
|
;; GIT
|
||||||
(ex! "gist" #'+gist:send) ; send current buffer/region to gist
|
(ex! "gist" #'+gist:send) ; send current buffer/region to gist
|
||||||
(ex! "gistl" #'+gist:list) ; list gists by user
|
(ex! "gistl" #'+gist:list) ; list gists by user
|
||||||
|
@ -40,20 +38,18 @@
|
||||||
(ex! "gunstage" #'magit-unstage)
|
(ex! "gunstage" #'magit-unstage)
|
||||||
(ex! "gblame" #'magit-blame)
|
(ex! "gblame" #'magit-blame)
|
||||||
(ex! "grevert" #'git-gutter:revert-hunk)
|
(ex! "grevert" #'git-gutter:revert-hunk)
|
||||||
|
|
||||||
;; Dealing with buffers
|
;; 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]" #'doom/kill-this-buffer)
|
||||||
(ex! "k[ill]all" #'+hlissner:kill-all-buffers)
|
(ex! "k[ill]all" #'+default:kill-all-buffers)
|
||||||
(ex! "k[ill]m" #'+hlissner:kill-matching-buffers)
|
(ex! "k[ill]m" #'+default:kill-matching-buffers)
|
||||||
(ex! "k[ill]o" #'doom/kill-other-buffers)
|
(ex! "k[ill]o" #'doom/kill-other-buffers)
|
||||||
(ex! "l[ast]" #'doom/popup-restore)
|
(ex! "l[ast]" #'doom/popup-restore)
|
||||||
(ex! "m[sg]" #'view-echo-area-messages)
|
(ex! "m[sg]" #'view-echo-area-messages)
|
||||||
(ex! "pop[up]" #'doom/popup-this-buffer)
|
(ex! "pop[up]" #'doom/popup-this-buffer)
|
||||||
|
|
||||||
;; Project navigation
|
;; Project navigation
|
||||||
(ex! "a" #'projectile-find-other-file)
|
(ex! "a" #'projectile-find-other-file)
|
||||||
(ex! "cd" #'+hlissner:cd)
|
(ex! "cd" #'+default:cd)
|
||||||
(cond ((featurep! :completion ivy)
|
(cond ((featurep! :completion ivy)
|
||||||
(ex! "ag" #'+ivy:ag)
|
(ex! "ag" #'+ivy:ag)
|
||||||
(ex! "agc[wd]" #'+ivy:ag-cwd)
|
(ex! "agc[wd]" #'+ivy:ag-cwd)
|
||||||
|
@ -68,17 +64,14 @@
|
||||||
(ex! "rgc[wd]" #'+helm:rg-cwd)
|
(ex! "rgc[wd]" #'+helm:rg-cwd)
|
||||||
(ex! "sw[oop]" #'+helm:swoop)
|
(ex! "sw[oop]" #'+helm:swoop)
|
||||||
(ex! "todo" #'+helm:todo)))
|
(ex! "todo" #'+helm:todo)))
|
||||||
|
|
||||||
;; Project tools
|
;; Project tools
|
||||||
(ex! "build" #'+eval/build)
|
(ex! "build" #'+eval/build)
|
||||||
(ex! "debug" #'+debug/run)
|
(ex! "debug" #'+debug/run)
|
||||||
(ex! "er[rors]" #'flycheck-list-errors)
|
(ex! "er[rors]" #'flycheck-list-errors)
|
||||||
|
|
||||||
;; File operations
|
;; File operations
|
||||||
(ex! "cp" #'+evil:copy-this-file)
|
(ex! "cp" #'+evil:copy-this-file)
|
||||||
(ex! "mv" #'+evil:move-this-file)
|
(ex! "mv" #'+evil:move-this-file)
|
||||||
(ex! "rm" #'+evil:delete-this-file)
|
(ex! "rm" #'+evil:delete-this-file)
|
||||||
|
|
||||||
;; Sessions/tabs
|
;; Sessions/tabs
|
||||||
(ex! "sclear" #'+workspace/kill-session)
|
(ex! "sclear" #'+workspace/kill-session)
|
||||||
(ex! "sl[oad]" #'+workspace:load-session)
|
(ex! "sl[oad]" #'+workspace:load-session)
|
||||||
|
@ -93,6 +86,6 @@
|
||||||
(ex! "tabr[ename]" #'+workspace:rename)
|
(ex! "tabr[ename]" #'+workspace:rename)
|
||||||
(ex! "tabs" #'+workspace/display)
|
(ex! "tabs" #'+workspace/display)
|
||||||
(ex! "tabsave" #'+workspace:save)
|
(ex! "tabsave" #'+workspace:save)
|
||||||
|
|
||||||
;; Org-mode
|
;; Org-mode
|
||||||
(ex! "cap" #'+org-capture/dwim)
|
(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
|
#+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
|
#+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
|
#+end_quote
|
||||||
|
|
|
@ -9,13 +9,15 @@
|
||||||
(require 'neotree)
|
(require 'neotree)
|
||||||
(cond ((and (neo-global--window-exists-p)
|
(cond ((and (neo-global--window-exists-p)
|
||||||
(get-buffer-window neo-buffer-name t))
|
(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)
|
((not (and (neo-global--window-exists-p)
|
||||||
(equal (file-truename (neo-global--with-buffer neo-buffer--start-node))
|
(equal (file-truename (neo-global--with-buffer neo-buffer--start-node))
|
||||||
(file-truename project-root))))
|
(file-truename project-root))))
|
||||||
(neotree-dir project-root)
|
(neotree-dir project-root)
|
||||||
(neotree-find path project-root))
|
(neotree-find path project-root))
|
||||||
(t (neotree-find path project-root)))))
|
(t
|
||||||
|
(neotree-find path project-root)))))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun +neotree/collapse-or-up ()
|
(defun +neotree/collapse-or-up ()
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
(and (or (string-match-p "https?://" url)
|
(and (or (string-match-p "https?://" url)
|
||||||
(error "Field for %s doesn't look like an url" item))
|
(error "Field for %s doesn't look like an url" item))
|
||||||
(browse-url url))
|
(browse-url url))
|
||||||
(error "Username not found.")))
|
(error "url not found.")))
|
||||||
|
|
||||||
(defun +pass-ivy-action--get-field (item)
|
(defun +pass-ivy-action--get-field (item)
|
||||||
(let* ((data (+pass--get-entry item))
|
(let* ((data (+pass--get-entry item))
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
(load! ../autoload)
|
(load! ../autoload)
|
||||||
|
|
||||||
(defmacro -with-passwords! (buffer-args &rest body)
|
(defmacro with-passwords!! (buffer-args &rest body)
|
||||||
(declare (indent defun))
|
(declare (indent defun))
|
||||||
`(cl-letf
|
`(cl-letf
|
||||||
(((symbol-function '+pass--get-entry)
|
(((symbol-function '+pass--get-entry)
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
;;
|
;;
|
||||||
(def-test! get-field
|
(def-test! get-field
|
||||||
(-with-passwords!
|
(with-passwords!!
|
||||||
(should (equal (+pass-get-field "fake/source" "login")
|
(should (equal (+pass-get-field "fake/source" "login")
|
||||||
"HL2532-GANDI"))
|
"HL2532-GANDI"))
|
||||||
(should (equal (+pass-get-field "fake/source" "email")
|
(should (equal (+pass-get-field "fake/source" "email")
|
||||||
|
@ -29,14 +29,14 @@
|
||||||
"henrik@lissner.net"))))
|
"henrik@lissner.net"))))
|
||||||
|
|
||||||
(def-test! missing-fields-return-nil
|
(def-test! missing-fields-return-nil
|
||||||
(-with-passwords!
|
(with-passwords!!
|
||||||
(should-not (+pass-get-field "fake/source" '("x" "y" "z")))))
|
(should-not (+pass-get-field "fake/source" '("x" "y" "z")))))
|
||||||
|
|
||||||
(def-test! missing-entries-throw-error
|
(def-test! missing-entries-throw-error
|
||||||
(-with-passwords!
|
(with-passwords!!
|
||||||
(should-error (+pass-get-field "nonexistent/source" "login"))))
|
(should-error (+pass-get-field "nonexistent/source" "login"))))
|
||||||
|
|
||||||
(def-test! get-login
|
(def-test! get-login
|
||||||
(-with-passwords!
|
(with-passwords!!
|
||||||
(should (equal (+pass-get-user "fake/source") "HL2532-GANDI"))
|
(should (equal (+pass-get-user "fake/source") "HL2532-GANDI"))
|
||||||
(should (equal (+pass-get-secret "fake/source") "defuse-account-gad"))))
|
(should (equal (+pass-get-secret "fake/source") "defuse-account-gad"))))
|
||||||
|
|
|
@ -3,20 +3,38 @@
|
||||||
(defvar +doom-dashboard-name " *doom*"
|
(defvar +doom-dashboard-name " *doom*"
|
||||||
"The name to use for the dashboard buffer.")
|
"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)
|
(defvar +doom-dashboard-widgets '(banner shortmenu loaded)
|
||||||
"List of widgets to display in a blank scratch buffer.")
|
"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 ()
|
(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.")
|
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--width 80)
|
||||||
(defvar +doom-dashboard--height 0)
|
(defvar +doom-dashboard--height 0)
|
||||||
(defvar +doom-dashboard--old-fringe-indicator fringe-indicator-alist)
|
(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)
|
(setq doom-fallback-buffer +doom-dashboard-name)
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,6 +43,8 @@ loading.")
|
||||||
"Major mode for the DOOM dashboard buffer."
|
"Major mode for the DOOM dashboard buffer."
|
||||||
(read-only-mode +1)
|
(read-only-mode +1)
|
||||||
(setq truncate-lines t)
|
(setq truncate-lines t)
|
||||||
|
(setq-local whitespace-style nil)
|
||||||
|
(setq-local show-trailing-whitespace nil)
|
||||||
(cl-loop for (car . _cdr) in fringe-indicator-alist
|
(cl-loop for (car . _cdr) in fringe-indicator-alist
|
||||||
collect (cons car nil) into alist
|
collect (cons car nil) into alist
|
||||||
finally do (setq fringe-indicator-alist alist)))
|
finally do (setq fringe-indicator-alist alist)))
|
||||||
|
@ -51,14 +71,24 @@ loading.")
|
||||||
if in a GUI/non-daemon session."
|
if in a GUI/non-daemon session."
|
||||||
(add-hook 'window-configuration-change-hook #'+doom-dashboard-reload)
|
(add-hook 'window-configuration-change-hook #'+doom-dashboard-reload)
|
||||||
(add-hook 'focus-in-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)))
|
(when (and (display-graphic-p) (not (daemonp)))
|
||||||
(let ((default-directory doom-emacs-dir))
|
(let ((default-directory doom-emacs-dir))
|
||||||
(+doom-dashboard/open (selected-frame)))))
|
(+doom-dashboard/open (selected-frame)))))
|
||||||
|
|
||||||
(defun +doom-dashboard|kill-buffer-query-fn ()
|
(defun +doom-dashboard|reload-on-kill ()
|
||||||
(or (not (+doom-dashboard-p))
|
"If this isn't a dashboard buffer, move along, but record its
|
||||||
(ignore (let (+doom-dashboard-inhibit-refresh)
|
`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))))))
|
(ignore-errors (+doom-dashboard-reload))))))
|
||||||
|
|
||||||
(defun +doom-dashboard|make-frame (frame)
|
(defun +doom-dashboard|make-frame (frame)
|
||||||
|
@ -85,30 +115,34 @@ whose dimensions may not be fully initialized by the time this is run."
|
||||||
(+doom-dashboard-reload)))
|
(+doom-dashboard-reload)))
|
||||||
(setq +doom-dashboard-inhibit-refresh nil)))
|
(setq +doom-dashboard-inhibit-refresh nil)))
|
||||||
|
|
||||||
|
;
|
||||||
(defun +doom-dashboard-p (&optional buffer)
|
(defun +doom-dashboard-p (&optional buffer)
|
||||||
"Returns t if BUFFER is the dashboard buffer."
|
"Returns t if BUFFER is the dashboard buffer."
|
||||||
(let ((buffer (or buffer (current-buffer))))
|
(eq (or buffer (current-buffer))
|
||||||
(and (buffer-live-p buffer)
|
(doom-fallback-buffer)))
|
||||||
(eq buffer (doom-fallback-buffer)))))
|
|
||||||
|
|
||||||
(defun +doom-dashboard-center (len s)
|
(defun +doom-dashboard-update-pwd ()
|
||||||
(concat (make-string (ceiling (max 0 (- len (length s))) 2) ? )
|
"TODO"
|
||||||
s))
|
(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)."
|
"Update the DOOM scratch buffer (or create it, if it doesn't exist)."
|
||||||
(when (get-buffer-window (doom-fallback-buffer))
|
(let ((fallback-buffer (doom-fallback-buffer)))
|
||||||
(unless (or +doom-dashboard-inhibit-refresh
|
(when (or (and after-init-time
|
||||||
(window-minibuffer-p (frame-selected-window)))
|
(not +doom-dashboard-inhibit-refresh)
|
||||||
(let ((old-pwd (or dir default-directory))
|
(get-buffer-window fallback-buffer)
|
||||||
(fallback-buffer (doom-fallback-buffer)))
|
(not (window-minibuffer-p (frame-selected-window))))
|
||||||
|
force)
|
||||||
(with-current-buffer fallback-buffer
|
(with-current-buffer fallback-buffer
|
||||||
|
(+doom-dashboard-update-pwd)
|
||||||
(with-silent-modifications
|
(with-silent-modifications
|
||||||
(unless (eq major-mode '+doom-dashboard-mode)
|
(unless (eq major-mode '+doom-dashboard-mode)
|
||||||
(+doom-dashboard-mode))
|
(+doom-dashboard-mode))
|
||||||
(erase-buffer)
|
(erase-buffer)
|
||||||
(setq default-directory old-pwd)
|
(let ((+doom-dashboard--height
|
||||||
(let ((+doom-dashboard--height (window-height (get-buffer-window fallback-buffer)))
|
(window-height (get-buffer-window fallback-buffer)))
|
||||||
(lines 1)
|
(lines 1)
|
||||||
content)
|
content)
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
|
@ -122,18 +156,46 @@ whose dimensions may not be fully initialized by the time this is run."
|
||||||
?\n)
|
?\n)
|
||||||
content))
|
content))
|
||||||
(unless (button-at (point))
|
(unless (button-at (point))
|
||||||
(goto-char (next-button (point-min))))))))
|
(goto-char (next-button (point-min)))))))
|
||||||
;; Update all dashboard windows
|
;; 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-fringes win 0 0)
|
||||||
(set-window-margins
|
(set-window-margins
|
||||||
win (max 0 (/ (- (window-total-width win) +doom-dashboard--width) 2)))))
|
win (max 0 (/ (- (window-total-width win) +doom-dashboard--width) 2)))))
|
||||||
t)
|
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
|
;; widgets
|
||||||
(defun doom-dashboard-widget--banner ()
|
(defun doom-dashboard-widget--banner ()
|
||||||
(mapc (lambda (line)
|
(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) " ")
|
'face 'font-lock-comment-face) " ")
|
||||||
(insert "\n"))
|
(insert "\n"))
|
||||||
'("================= =============== =============== ======== ========"
|
'("================= =============== =============== ======== ========"
|
||||||
|
@ -160,17 +222,15 @@ whose dimensions may not be fully initialized by the time this is run."
|
||||||
(insert
|
(insert
|
||||||
"\n"
|
"\n"
|
||||||
(propertize
|
(propertize
|
||||||
(+doom-dashboard-center
|
(+doom-dashboard--center
|
||||||
+doom-dashboard--width
|
+doom-dashboard--width
|
||||||
(format "Loaded %d packages in %d modules in %.02fs"
|
(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)
|
(hash-table-size doom-modules)
|
||||||
(if (floatp doom-init-time) doom-init-time 0.0)))
|
(if (floatp doom-init-time) doom-init-time 0.0)))
|
||||||
'face 'font-lock-comment-face)
|
'face 'font-lock-comment-face)
|
||||||
"\n"))
|
"\n"))
|
||||||
|
|
||||||
(defvar all-the-icons-scale-factor)
|
|
||||||
(defvar all-the-icons-default-adjust)
|
|
||||||
(defun doom-dashboard-widget--shortmenu ()
|
(defun doom-dashboard-widget--shortmenu ()
|
||||||
(let ((all-the-icons-scale-factor 1.45)
|
(let ((all-the-icons-scale-factor 1.45)
|
||||||
(all-the-icons-default-adjust -0.02))
|
(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))
|
(propertize (concat " " label) 'face 'font-lock-keyword-face))
|
||||||
'action `(lambda (_) ,fn)
|
'action `(lambda (_) ,fn)
|
||||||
'follow-link t)
|
'follow-link t)
|
||||||
(+doom-dashboard-center (- +doom-dashboard--width 2) (buffer-string)))
|
(+doom-dashboard--center (- +doom-dashboard--width 2) (buffer-string)))
|
||||||
"\n\n"))))
|
"\n\n"))))
|
||||||
`(("Homepage" "mark-github"
|
`(("Homepage" "mark-github"
|
||||||
(browse-url "https://github.com/hlissner/doom-emacs"))
|
(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