Merge branch 'develop' into release-2.0.4

* develop: (45 commits)
  General cleanup
  Update changelog
  Refactor doom-get-packages
  Refactor doom-initialize-packages
  Refactor core.el
  Enable shackle-mode later in startup process
  Appease byte-compiler
  Bind e => debugger-eval-expression in debugger
  Less 'nowhere to go' spam on doom/kill-this-buffer
  Add display-line-numbers support in Emacs 26 #59
  Remove (interactive) from non-interactive funcs
  Refactor doom-popup-size (cond -> pcase)
  Refactor doom-popup-prop (cond -> pcase)
  Fix wrong-type-argument: bufferp error on ESC
  Revert 8edba655: disable undo persistence
  Refactor makefile
  Rename core + module byte-compilation make tasks
  doom/clean-compiled => doom/clean-compiled-files
  Rename doom/clean-cache => doom/reset (+ make reset)
  Rename bin/doctor => bin/doom-doctor
  ...
This commit is contained in:
Henrik Lissner 2017-07-14 15:25:30 +02:00
commit 0541e48370
36 changed files with 644 additions and 286 deletions

View file

@ -2,6 +2,7 @@
- [[#todo][Todo]] - [[#todo][Todo]]
- [[#unreleased-master][Unreleased (master)]] - [[#unreleased-master][Unreleased (master)]]
- [[#204-jul-14-2017][2.0.4 (Jul 14, 2017)]]
- [[#203-jun-11-2017][2.0.3 (Jun 11, 2017)]] - [[#203-jun-11-2017][2.0.3 (Jun 11, 2017)]]
- [[#202-may-13-2017][2.0.2 (May 13, 2017)]] - [[#202-may-13-2017][2.0.2 (May 13, 2017)]]
- [[#201-apr-8-2017][2.0.1 (Apr 8, 2017)]] - [[#201-apr-8-2017][2.0.1 (Apr 8, 2017)]]
@ -21,7 +22,7 @@
+ =lang/latex= [[https://github.com/Malabarba/latex-extra][latex-extra]] (utility commands) + =lang/latex= [[https://github.com/Malabarba/latex-extra][latex-extra]] (utility commands)
+ =lang/latex= [[**https://github.com/jsinglet/latex-preview-pane][latex-preview-pane]] + =lang/latex= [[**https://github.com/jsinglet/latex-preview-pane][latex-preview-pane]]
+ =lang/julia= [[ https://github.com/dennisog/julia-shell-mode][julia-shell]] (unsure if better than inferior-julia in julia-mode) + =lang/julia= [[ https://github.com/dennisog/julia-shell-mode][julia-shell]] (unsure if better than inferior-julia in julia-mode)
+ =lang/python= [[https://github.com/Wilfred/pyimport][pyimport]] + =lang/python= [[https://github.com/Wilfred/pyimport][pyimport]] or [[https://github.com/anachronic/importmagic.el][importmagic]]
+ [[https://github.com/mhayashi1120/Emacs-imagex][emacs-imagex]], for manipulating images at point (zooming?) + [[https://github.com/mhayashi1120/Emacs-imagex][emacs-imagex]], for manipulating images at point (zooming?)
+ =tools/term= [[https://github.com/riscy/shx-for-emacs][shx]], an extension for the shell in Emacs + =tools/term= [[https://github.com/riscy/shx-for-emacs][shx]], an extension for the shell in Emacs
+ =app/crm= [[https://github.com/skeeto/emacsql][emacsql]], a sqlite backend; which would be useful for CRM storage. + =app/crm= [[https://github.com/skeeto/emacsql][emacsql]], a sqlite backend; which would be useful for CRM storage.
@ -44,12 +45,12 @@
+ Syntax highlighter for ~+regex-mode~ (plus make it a major mode) + Syntax highlighter for ~+regex-mode~ (plus make it a major mode)
+ Optimize: communicate with perl process (with ~make-process~ instead of ~call-process~) + Optimize: communicate with perl process (with ~make-process~ instead of ~call-process~)
+ =lang/alda= -- Language support for [[https://github.com/alda-lang/alda][Alda]], the music programming language, using [[https://github.com/jgkamat/alda-mode][alda-mode]]. + =lang/alda= -- Language support for [[https://github.com/alda-lang/alda][Alda]], the music programming language, using [[https://github.com/jgkamat/alda-mode][alda-mode]].
+ =org/org-publish= -- publishing org files to HTML (thanks to [[https://github.com/matthewgraybosch][matthewgraybosch]])
+ =org/org-attach= -- my own, simpler attachment system with drag-drop image attachment support and centralized storage.
+ *Bug fixes:* + *Bug fixes:*
+ =core-ui= Replace or fix ~winner-mode~ unreliability (will close windows trying to revive killed buffers). Perhaps make ~doom/kill-this-buffer~ only disassociate buffer from persp-mode or bury buffer if persp-mode is inactive. + =core-ui= Replace or fix ~winner-mode~ unreliability (will close windows trying to revive killed buffers). Perhaps make ~doom/kill-this-buffer~ only disassociate buffer from persp-mode or bury buffer if persp-mode is inactive.
+ =ui/doom-modeline= Fix ~0/0~ leftover panel in modeline (caused by lingering anzu state). + =ui/doom-modeline= Fix ~0/0~ leftover panel in modeline (caused by lingering anzu state).
+ =lang/org= + =org=
+ Drag-drop image attachment (~org-download~) and central storage
+ Unified export system
+ Better shackle + org-agenda integration + Better shackle + org-agenda integration
+ Fix janky visual line motions (~evil-next-visual-line~, etc) + Fix janky visual line motions (~evil-next-visual-line~, etc)
+ Fix janky cursor positioning when jumping between org-table cells from insert mode. + Fix janky cursor positioning when jumping between org-table cells from insert mode.
@ -64,13 +65,30 @@
+ Document best practices for customizing DOOM emacs. + Document best practices for customizing DOOM emacs.
+ =ui/doom-modeline= fix hardcoded spacing in between segments. + =ui/doom-modeline= fix hardcoded spacing in between segments.
+ Rewrite main README.md to include more information about setting up, customizing, and troubleshooting DOOM Emacs. + Rewrite main README.md to include more information about setting up, customizing, and troubleshooting DOOM Emacs.
+ Update =bin/org-capture= to read from stdin in the absence of arguments.
* Unreleased (master) * Unreleased (master)
+ *New modules:*
+ =tools/password-store= -- Emacs as a password manager, using [[https://www.passwordstore.org/][pass]] as a backend (contributed by [[https://github.com/bandresen][brandresen]]). * 2.0.4 (Jul 14, 2017)
+ =app/irc= -- Emacs as an IRC client, using circe (contributed by [[https://github.com/bandresen][brandresen]]). + *Module changes:*
+ Added =tools/password-store= -- Emacs as a password manager, using [[https://www.passwordstore.org/][pass]] as a backend (contributed by [[https://github.com/bandresen][brandresen]]).
+ Added =app/irc= -- Emacs as an IRC client, using circe (contributed by [[https://github.com/bandresen][brandresen]]).
+ ~+pass/ivy~ for ivy integration, with edit/copy field/open url actions. + ~+pass/ivy~ for ivy integration, with edit/copy field/open url actions.
+ ~helm-pass~ for helm integration. + ~helm-pass~ for helm integration.
+ Added =lang/hy= -- support for [[http://hylang.org][hylang]], a combination of Lisp and Python (thanks to [[https://github.com/bandresen][bandresen]]).
+ Added =lang/ocaml= -- support for [[https://ocaml.org/][OCAML]] (thanks to [[https://github.com/Ptival][Ptival]])
+ Added =lang/plantuml= -- drawing diagrams in plain text
+ Added =lang/perl= -- Perl6 support for Emacs
+ Added =ui/tabbar= -- add tabs to Doom via [[https://github.com/dholm/tabbar][tabbar]] (I don't recommend using it)
+ Removed =lang/org=
+ Added =org= -- a new module category for org and org extensions
+ Removed =app/present= (replaced mostly with =org/org-present=)
+ =org/org-babel= -- executable code snippets in org-mode, with support for a variety of languages.
+ =org/org-capture= -- a better org-capture, in or outside of Emacs.
+ =org/org-export= -- a centralized export system with more export backends.
+ =org/org-notebook= -- org-mode as a general notebook.
+ =org/org-present= -- org-mode for presentations.
+ Added =tools/impatient-mode= -- show off live buffers via HTTP.
+ =core= + =core=
+ New variable: ~doom-host-dir~, as a base path for ~doom-etc-dir~ and ~doom-cache-dir~. + New variable: ~doom-host-dir~, as a base path for ~doom-etc-dir~ and ~doom-cache-dir~.
+ New hooks: ~doom-init-hook~ and ~doom-post-init-hook~, which are run on ~emacs-startup-hook~. This is meant to simplify post-Emacs initialization hooks (~after-init-hook~, ~emacs-startup-hook~ and ~window-setup-hook~) into two unambiguous ones. + New hooks: ~doom-init-hook~ and ~doom-post-init-hook~, which are run on ~emacs-startup-hook~. This is meant to simplify post-Emacs initialization hooks (~after-init-hook~, ~emacs-startup-hook~ and ~window-setup-hook~) into two unambiguous ones.
@ -78,20 +96,29 @@
+ Improve error handling across the board. Emacs should now report more helpful errors. Catastrophic errors will be less likely to inhibit later modules from being loaded. + Improve error handling across the board. Emacs should now report more helpful errors. Catastrophic errors will be less likely to inhibit later modules from being loaded.
+ Unit-tests have been moved to their respective modules (and =core/test/=). + Unit-tests have been moved to their respective modules (and =core/test/=).
+ Fix ~def-setting!~ to act more like ~defmacro~; don't aggressively evaluate its arguments on expansion. + Fix ~def-setting!~ to act more like ~defmacro~; don't aggressively evaluate its arguments on expansion.
+ New function: ~doom-set-buffer-real BUFFER FLAG~ -- makes Doom consider BUFFER real, no matter what.
+ Add ~INSTALLED-ONLY-P~ argument to ~doom-get-packages~ to filter packages that aren't installed.
+ =core-ui= + =core-ui=
+ Add quit confirmation when trying to close a frame that contains real buffers. + Add quit confirmation when trying to close a frame that contains real buffers.
+ Fix quit confirmations for clients connected to ~emacs --daemon~ with ~emacsclient~. + Fix quit confirmations for clients connected to ~emacs --daemon~ with ~emacsclient~.
+ Brought back [[https://github.com/hlissner/emacs-nlinum-hl][nlinum-hl]], which offers some line number fixes for web-mode and markdown-mode. + Brought back [[https://github.com/hlissner/emacs-nlinum-hl][nlinum-hl]], which offers some line number fixes for web-mode and markdown-mode.
+ Don't report the buffer modified when injecting (or deleting) trailing whitespace in ~doom|inject-trailing-whitespace~ and ~doom|init-highlight-indentation~. + Don't report the buffer modified when injecting (or deleting) trailing whitespace in ~doom|inject-trailing-whitespace~ and ~doom|init-highlight-indentation~.
+ [[https://github.com/domtronn/all-the-icons.el][all-the-icons]] now fails gracefully in the terminal. + [[https://github.com/domtronn/all-the-icons.el][all-the-icons]] now fails gracefully in the terminal.
+ New hook: ~doom-init-ui-hook~, run whenever the UI needs to be reloaded (and once at startup). Theme and font loading is also attached to this hook.
+ New variables for font and theme loading: ~doom-theme~, ~doom-font~, ~doom-variable-pitch-font~, and ~doom-unicode-font~.
+ New variables for customizing line numbers: ~doom-line-number-lpad~, ~doom-line-number-rpad~, and ~doom-line-number-pad-char~. These were added to facilitate custom whitespace characters in line numbers, e.g. /u2002 (a unicode character that looks like a space). Doing so fixes an issue where ~whitespace-mode~ with ~space-mark~ would replace all space characters indiscriminately, even in line numbers.
+ Add hooks ~doom-pre-reload-theme-hook~ and ~doom-post-reload-theme-hook~ to ~doom/reload-theme~ command.
+ =core-popups= + =core-popups=
+ Fix an issue where more specific popup rules were being overriden by more general rules. + Fix an issue where more specific popup rules were being overriden by more general rules.
+ New command: ~doom/other-popup~ -- cycles between open popup windows and the original buffer that you originated from. Discussed in [[https://github.com/hlissner/.emacs.d/issues/141][#141]].
+ =core-editor= + =core-editor=
+ Change what files recentf will ignore: everything in ~doom-host-dir~ is now ignored and anything else in ~doom-local-dir~ won't be. + Change what files recentf will ignore: everything in ~doom-host-dir~ is now ignored and anything else in ~doom-local-dir~ won't be.
+ New interactive command: ~doom/scratch-buffer~ (replaces ~+doom:scratch-buffer~ in =:ui doom=).
+ =core-packages= + =core-packages=
+ Generalize ~doom-package-*-p~ functions into ~(doom-package-prop NAME PROPERTY)~. + Generalize ~doom-package-*-p~ functions into ~(doom-package-prop NAME PROPERTY)~.
+ Fix quelpa temporary files (in ~quelpa-build-dir~) not being removed when a quelpa package is uninstalled. + Fix quelpa temporary files (in ~quelpa-build-dir~) not being removed when a quelpa package was uninstalled.
+ New hook: ~doom-reload-hook~ (sort of). This has been around for a while, but now it is defined and documented. It runs when ~doom/reload~ is called (which gets called remotely if you run package management while an Emacs session is active). + New hook: ~doom-reload-hook~ (sort of). This has been around for a while, but now it is defined and documented. It runs when ~doom/reload~ is called (which gets called remotely if you run package management while an Emacs session is active).
+ ~load!~ can now accept a string as its first argument (the path).
+ =feature= + =feature=
+ =feature/evil= + =feature/evil=
+ Remove =goto-last-change=, which conflicts with =goto-chg=, which is a dependency of evil (that does the exact same thing, but is what evil uses). + Remove =goto-last-change=, which conflicts with =goto-chg=, which is a dependency of evil (that does the exact same thing, but is what evil uses).
@ -102,25 +129,43 @@
+ ~:references~: lists all references of the symbol at point and lets you jump to them. + ~:references~: lists all references of the symbol at point and lets you jump to them.
+ ~:documentation~: shows documentation for the symbol at point. + ~:documentation~: shows documentation for the symbol at point.
+ ~:xref-backend~: a function that serves as an xref backend; this replaces ~:definition~ and ~:references~. + ~:xref-backend~: a function that serves as an xref backend; this replaces ~:definition~ and ~:references~.
+ =feature/workspaces=
+ New function: ~+workspace-contains-buffer-p &optional BUFFER PERSP~ -- return non-nil if BUFFER (defaults to current buffer) is in PERSP (defaults to current perspective).
+ Fix ~+workspace-p~ not detecting a perspective struct.
+ Fix ~+workspace-buffer-list~ not preserving buffer order (by recency).
+ =completion=
+ =completion/company=
+ Add ~company-dabbrev~ and ~company-ispell~ to the default Company backends. This ensures you have some completion available in buffers previously without any. This is especially useful for text-mode buffers. Discussed in [[https://github.com/hlissner/.emacs.d/issues/134][#134]].
+ =ui= + =ui=
+ =ui/doom= + =ui/doom=
+ Vastly improve daemon and terminal support for doom-themes by reloading the theme when a new client is attached, or new terminal/daemon frame is created. This prevents incorrect colors from bleeding across face class barriers. + Vastly improve daemon and terminal support for doom-themes by reloading the theme when a new client is attached, or new terminal/daemon frame is created. This prevents incorrect colors from bleeding across face class barriers.
+ Removed evil command ~+doom:scratch-buffer~ (replaced with ~doom/scratch-buffer~ in =core-ui=).
+ Decoupled font and theme loading from this module. This has now been delegated to =core-ui=. These variables no longer exist: ~+doom-theme~, ~+doom-font~, ~+doom-variable-pitch-font~, ~+doom-unicode-font~. Discussed in [[https://github.com/hlissner/.emacs.d/issues/117][#117]].
+ =ui/doom-dashboard= + =ui/doom-dashboard=
+ Fix dashboard not opening in emacsclient/daemon frames. + Fix dashboard not opening in emacsclient/daemon frames.
+ Add =gg= and =G= keybinds in dashboard for moving to the first and last button (respectively). + Add =gg= and =G= keybinds in dashboard for moving to the first and last button (respectively).
+ =ui/doom-modeline= + =ui/doom-modeline=
+ Reorganize order of modeline segments, placing the vc branch last. This minimizes the non-uniform spacing that all-the-icon icons cause. + Reorganize order of modeline segments, placing the vc branch last. This minimizes the non-uniform spacing caused by all-the-icon icons.
+ Fix blank mode-line caused by a nil buffer-file-name (used in vcs segment). For example, in org indirect buffers.
+ =tools= + =tools=
+ =tools/neotree= + =tools/neotree=
+ Fix neotree refusing to open when it was already open in another frame. This is especially frustrating when neotree is open in a (likely buried) terminal emacsclient session, and you're trying to open neotree in another. + Fix neotree refusing to open when it was already open in another frame. This is especially frustrating when neotree is open in a (likely buried) terminal emacsclient session, and you're trying to open neotree in another.
+ =lang= + =lang=
+ =lang/cc=
+ Add code completion to glsl-mode (powered by [[https://github.com/Kaali/company-glsl][company-glsl]]).
+ =lang/markdown= + =lang/markdown=
+ Source blocks are now fontified natively, with the fontification of their native major-modes (see ~markdown-fontify-code-blocks-natively~). + Source blocks are now fontified natively, with the fontification of their native major-modes (see ~markdown-fontify-code-blocks-natively~).
+ =lang/org= + =lang/sh=
+ Fix fontification of command substitutions in double-quoted strings to help distinguish them from the rest of string literals.
+ =lang/web=
+ Fix HTML entity encoding/decoding functions.
+ =org=
+ =org/org=
+ Fix M-RET in plain lists not preserving indent level for new items. + Fix M-RET in plain lists not preserving indent level for new items.
+ Fix cursor jumping away when toggling folds or realigning org tables (pressing TAB). + Fix cursor jumping away when toggling folds or realigning org tables (pressing TAB).
+ =lang/sh= + Minimized keybindings into the bare necessities; most custom bindings have been moved to my private module.
+ Fix fontification of command substitutions in double-quoted strings to help distinguish them from the rest of the string literal. + =org/org-capture=
+ Start org-capture-mode in insert-mode (if evil is loaded).
* 2.0.3 (Jun 11, 2017) * 2.0.3 (Jun 11, 2017)
+ *New modules* + *New modules*
@ -142,6 +187,9 @@
+ New variable: ~doom-ui-mode-names~ (alist) -- for changing ~mode-name~ of major-modes. + New variable: ~doom-ui-mode-names~ (alist) -- for changing ~mode-name~ of major-modes.
+ Fix left-over hl-line overlays when hl-line-mode is uncleanly killed (e.g. when the major-mode is changed). + Fix left-over hl-line overlays when hl-line-mode is uncleanly killed (e.g. when the major-mode is changed).
+ Fix disappearing line numbers in nlinum (thanks to [[https://github.com/gilbertw1][gilbertw1]]). + Fix disappearing line numbers in nlinum (thanks to [[https://github.com/gilbertw1][gilbertw1]]).
+ Move theme/font bootstrap to core-ui.
+ New hook: ~doom-init-ui-hook~
+ New global minor-mode ~doom-big-font-mode~ and variable ~doom-big-font~.
+ =core-keybinds= + =core-keybinds=
+ New property for ~map!~: ~:textobj~ -- for binding to evil text objects keymaps. + New property for ~map!~: ~:textobj~ -- for binding to evil text objects keymaps.
+ Fix ~:after~ & ~:map*~ properties in ~map!~ macro (wasn't working at all). + Fix ~:after~ & ~:map*~ properties in ~map!~ macro (wasn't working at all).
@ -176,16 +224,28 @@
+ Call ~recenter~ after using [[https://github.com/jacktasia/dumb-jump][dumb-jump]]. + Call ~recenter~ after using [[https://github.com/jacktasia/dumb-jump][dumb-jump]].
+ =feature/workspaces= + =feature/workspaces=
+ No longer saves session on quit if session was blank. + No longer saves session on quit if session was blank.
+ Fix persp-mode switching to main workspace if auto-resume is on.
+ Fix ~+workspace-get~ returning a non-nil "null perspective" on some occasions where NAME doesn't exist. This is because ~persp-get-by-name~ returns the value of ~persp-not-persp~ to signify null instead of actual nil.
+ Decouple workspace buffer-list functions from doom buffer library. Now, the workspaces module will explicitly advise ~doom-buffer-list~.
+ ~+workspace-list~ now returns a list of perspective structs, rather than a list of strings. ~+workspace-list-names~ was introduced for the latter.
+ =completion= + =completion=
+ =completion/company=
+ Change ~:company-backends~ to accept a variadic list of backends to prepend to ~company-backends~. Its signature is now ~(set! :company-backends MODES &rest BACKENDS)~ ([[https://github.com/hlissner/.emacs.d/pull/125][#125]]).
+ =completion/ivy= + =completion/ivy=
+ Flexible column width for ~+ivy/tasks~. + Flexible column width for ~+ivy/tasks~.
+ =ui= + =ui=
+ =ui/doom= + =ui/doom=
+ New plugin: [[https://github.com/hlissner/emacs-solaire-mode][solaire-mode]] -- replaces ~doom-buffer-mode~; brightens source windows and dims transient, temporary, or popup windows. + New plugin: [[https://github.com/hlissner/emacs-solaire-mode][solaire-mode]] -- replaces ~doom-buffer-mode~; brightens source windows and dims transient, temporary, or popup windows.
+ BREAKING CHANGE: Decoupled theme and font loading from ui/doom. This has been moved to core-ui. The following variables have been renamed:
+ ~+doom-theme~ => ~doom-theme~
+ ~+doom-font~ => ~doom-font~
+ ~+doom-variable-pitch-font~ => ~doom-variable-pitch-font~
+ ~+doom-unicode-font~ => ~doom-unicode-font~
+ =ui/doom-modeline= + =ui/doom-modeline=
+ Reduce excess whitespace on right of flycheck segment. + Reduce excess whitespace on right of flycheck segment.
+ Buffer-path and file-name segments now use different faces. + Buffer-path and file-name segments now use different faces.
+ The vcs segment now uses a slightly darker color (in clean branches). + The vcs segment now uses a slightly darker color (in clean branches).
+ Fix blank mode-line when buffer-file-name is nil ([[https://github.com/hlissner/.emacs.d/pull/130][#130]])
+ =ui/nav-flash= + =ui/nav-flash=
+ Fix over-aggressive nav-flash'ing on evil-multiedit or in eshell/term buffers. + Fix over-aggressive nav-flash'ing on evil-multiedit or in eshell/term buffers.
+ =tools= + =tools=
@ -201,6 +261,8 @@
+ Don't enable ~flycheck-mode~ in emacs.d files. + Don't enable ~flycheck-mode~ in emacs.d files.
+ =lang/org= + =lang/org=
+ Replace org-bullets source with more up-to-date fork. + Replace org-bullets source with more up-to-date fork.
+ =lang/scala=
+ Fix ~void-variable imenu-auto-rescan~ error caused by ~ensime--setup-imenu~ trying to use imenu variables before loading imenu.
+ =private/hlissner= + =private/hlissner=
+ Add =gzz= binding (~+evil/mc-make-cursor-here~) + Add =gzz= binding (~+evil/mc-make-cursor-here~)
+ Add =:mc= ex command (~+evil:mc~) + Add =:mc= ex command (~+evil:mc~)

View file

@ -5,9 +5,9 @@ EMACSI=emacs -q $(EMACS_FLAGS)
MODULES=$(patsubst modules/%, %, $(shell find modules/ -maxdepth 2 -type d)) MODULES=$(patsubst modules/%, %, $(shell find modules/ -maxdepth 2 -type d))
# Tasks
all: autoloads autoremove install all: autoloads autoremove install
## Package management
install: init.el .local/autoloads.el install: init.el .local/autoloads.el
@$(EMACS) -f doom/packages-install @$(EMACS) -f doom/packages-install
@ -20,28 +20,40 @@ autoremove: init.el .local/autoloads.el
autoloads: init.el autoloads: init.el
@$(EMACS) -f doom/reload-autoloads @$(EMACS) -f doom/reload-autoloads
recompile: init.el
@$(EMACS) -f doom/recompile
## Byte compilation
# compile
# compile:core
# compile:module
# compile:module/submodule
compile: init.el clean compile: init.el clean
@$(EMACS) -f doom/compile @$(EMACS) -f doom/compile
core: init.el clean compile\:core: init.el clean
@$(EMACS) -f doom/compile -- init.el core @$(EMACS) -f doom/compile -- init.el core
$(MODULES): init.el .local/autoloads.el $(patsubst %, compile\:%, $(MODULES)): init.el .local/autoloads.el
@rm -fv $(shell find modules/$@ -type f -name '*.elc') @rm -fv $(shell find $(patsubst compile:%, modules/%, $@) -type f -name '*.elc')
@$(EMACS) -f doom/compile -- modules/$@ @$(EMACS) -f doom/compile -- $(patsubst compile:%, modules/%, $@)
recompile: init.el
@$(EMACS) -f doom/recompile
clean: clean:
@$(EMACS) -f doom/clean-compiled @$(EMACS) -f doom/clean-compiled-files
clean-cache:
@$(EMACS) -f doom/clean-cache
clean-pcache: clean-pcache:
@$(EMACS) -l persistent-soft --eval '(delete-directory pcache-directory t)' @$(EMACS) -l persistent-soft --eval '(delete-directory pcache-directory t)'
reset:
@$(EMACS) -f doom/reset
## Unit tests
# test
# test:core
# test:module
# test:module/submodule
test: init.el .local/autoloads.el test: init.el .local/autoloads.el
@$(EMACS) -f doom-run-tests @$(EMACS) -f doom-run-tests
@ -52,16 +64,19 @@ test\:core $(patsubst %, test\:%, $(MODULES)): init.el .local/autoloads.el
testi: init.el .local/autoloads.el testi: init.el .local/autoloads.el
@$(EMACSI) -f doom-run-tests -f ert @$(EMACSI) -f doom-run-tests -f ert
# For running Emacs from a different folder than ~/.emacs.d
## Utility tasks
# Runs Emacs from a different folder than ~/.emacs.d
run: run:
@$(EMACSI) $(EMACS_FLAGS) -l init.el @$(EMACSI) -l init.el
# Diagnoses potential OS/environment issues
doctor: doctor:
@./bin/doctor @./bin/doom-doctor
# ## Internal tasks
init.el: init.el:
@[ -e init.el ] || $(error No init.el file; create one or copy init.example.el) @$(error No init.el file; create one or copy init.example.el)
.local/autoloads.el: .local/autoloads.el:
@$(EMACS) -f doom-initialize-autoloads @$(EMACS) -f doom-initialize-autoloads
@ -69,5 +84,4 @@ init.el:
%.elc: %.el %.elc: %.el
@$(EMACS) -f doom/compile -- $< @$(EMACS) -f doom/compile -- $<
.PHONY: all compile test testi
.PHONY: all test $(MODULES)

View file

@ -16,6 +16,7 @@
(require 'pp) (require 'pp)
;; ;;
(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))
@ -95,8 +96,25 @@
(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" (indented 2 (autofill (shell-command-to-string "uname -a"))))
(msg! "----\n")
(let (doom-core-packages doom-debug-mode)
(condition-case ex
(progn
(let ((inhibit-message t))
(load "~/.emacs.d/core/core.el" nil t))
(doom-initialize-packages)
(doom|finalize)
(success! "Attempt to load DOOM: success! Loaded v%s" doom-version)
(when (executable-find "git")
(msg! "Revision %s"
(or (ignore-errors
(let ((default-directory user-emacs-directory))
(shell-command-to-string "git rev-parse HEAD")))
"\n"))))
('error (warn! "Attempt to load DOOM: failed\n %s\n"
(or (cdr-safe ex) (car ex))))))
(msg! "----\n")
;; --- is emacs set up properly? ------------------------------ ;; --- is emacs set up properly? ------------------------------
@ -111,6 +129,15 @@
;; --- is the environment set up properly? -------------------- ;; --- is the environment set up properly? --------------------
(when (boundp 'doom-font)
(cond ((fboundp 'find-font)
(unless (find-font doom-font)
(warn! "Warning: couldn't find %s font" (font-get doom-font :family))
(explain! "If you use a different font, you may ignore this warning.")))
(t
(warn! "Couldn't detect font!")
(explain! "This could indicate the incorrect version of Emacs is being used!"))))
;; gnutls-cli & openssl ;; gnutls-cli & openssl
(cond ((executable-find "gnutls-cli")) (cond ((executable-find "gnutls-cli"))
((executable-find "openssl") ((executable-find "openssl")
@ -217,21 +244,6 @@
(when (getenv "DEBUG") (when (getenv "DEBUG")
(msg! "\n====\nHave some debug information:\n") (msg! "\n====\nHave some debug information:\n")
(let (doom-core-packages doom-debug-mode)
(condition-case ex
(progn
(let ((inhibit-message t))
(load "~/.emacs.d/core/core.el" nil t))
(doom-initialize-packages)
(success! " + Attempt to load DOOM: success! Loaded v%s" doom-version)
(when (executable-find "git")
(msg! " Revision %s"
(or (ignore-errors
(let ((default-directory user-emacs-directory))
(shell-command-to-string "git rev-parse HEAD")))
"\n"))))
('error (warn! " + Attempt to load DOOM: failed\n %s\n" (or (cdr-safe ex) (car ex))))))
(when (bound-and-true-p doom-modules) (when (bound-and-true-p doom-modules)
(msg! " + enabled modules:\n%s" (msg! " + enabled modules:\n%s"
(indented 4 (indented 4

View file

@ -6,6 +6,9 @@
(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 functions that are run to determine if a buffer is real.")
(defvar-local doom-real-buffer-p nil
"If non-nil, this buffer should be considered real no matter what.")
;;;###autoload ;;;###autoload
(defvar doom-fallback-buffer "*scratch*" (defvar doom-fallback-buffer "*scratch*"
"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
@ -122,7 +125,7 @@ buffers. If there's nothing left, switch to `doom-fallback-buffer'. See
;; `switch-to-prev-buffer' properly update buffer list order. ;; `switch-to-prev-buffer' properly update buffer list order.
(cl-loop with move-func = (cl-loop with move-func =
(if (> n 0) #'switch-to-next-buffer #'switch-to-prev-buffer) (if (> n 0) #'switch-to-next-buffer #'switch-to-prev-buffer)
for _i to 20 for i to 20
while (not (memq (current-buffer) buffers)) while (not (memq (current-buffer) buffers))
do do
(dotimes (_i (abs n)) (dotimes (_i (abs n))
@ -136,7 +139,8 @@ buffers. If there's nothing left, switch to `doom-fallback-buffer'. See
"Returns t if BUFFER-OR-NAME is a 'real' buffer. Real means it a) isn't a "Returns t if BUFFER-OR-NAME is a 'real' buffer. Real means it a) isn't a
popup window/buffer and b) isn't a special buffer." popup window/buffer and b) isn't a special buffer."
(let ((buf (window-normalize-buffer buffer-or-name))) (let ((buf (window-normalize-buffer buffer-or-name)))
(or (run-hook-with-args-until-success 'doom-real-buffer-functions buf) (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) (not (or (doom-popup-p buf)
(minibufferp buf) (minibufferp buf)
(string-match-p "^\\s-*\\*" (buffer-name buf)) (string-match-p "^\\s-*\\*" (buffer-name buf))
@ -241,7 +245,7 @@ regex PATTERN. Returns the number of killed buffers."
(defun doom/kill-this-buffer () (defun doom/kill-this-buffer ()
"Use `doom-kill-buffer' on the current buffer." "Use `doom-kill-buffer' on the current buffer."
(interactive) (interactive)
(when (and (doom-kill-buffer) (called-interactively-p 'interactive)) (when (and (not (doom-kill-buffer)) (called-interactively-p 'interactive))
(message "Nowhere left to go!"))) (message "Nowhere left to go!")))
;;;###autoload ;;;###autoload
@ -295,3 +299,8 @@ project."
(when (called-interactively-p 'interactive) (when (called-interactively-p 'interactive)
(message "Cleaned up %s buffers" n)))) (message "Cleaned up %s buffers" n))))
;;;###autoload
(defun doom-set-buffer-real (buffer flag)
"Forcibly mark a buffer's real property, no matter what."
(with-current-buffer buffer
(setq doom-real-buffer-p flag)))

View file

@ -80,7 +80,7 @@ list of the package."
(plist-get (cdr (assq name doom-packages)) prop)) (plist-get (cdr (assq name doom-packages)) prop))
;;;###autoload ;;;###autoload
(defun doom-get-packages () (defun doom-get-packages (&optional installed-only-p)
"Retrieves a list of explicitly installed packages (i.e. non-dependencies). "Retrieves a list of explicitly installed packages (i.e. non-dependencies).
Each element is a cons cell, whose car is the package symbol and whose cdr is Each element is a cons cell, whose car is the package symbol and whose cdr is
the quelpa recipe (if any). the quelpa recipe (if any).
@ -89,13 +89,17 @@ BACKEND can be 'quelpa or 'elpa, and will instruct this function to return only
the packages relevant to that backend. the packages relevant to that backend.
Warning: this function is expensive; it re-evaluates all of doom's config files. Warning: this function is expensive; it re-evaluates all of doom's config files.
Be careful not to use it in a loop." Be careful not to use it in a loop.
If INSTALLED-ONLY-P, only return packages that are installed."
(doom-initialize-packages t) (doom-initialize-packages t)
(cl-loop with packages = (append doom-core-packages (mapcar #'car doom-packages)) (cl-loop with packages = (append doom-core-packages (mapcar #'car doom-packages))
for sym in (cl-delete-duplicates packages) for sym in (cl-delete-duplicates packages)
if (or (assq sym doom-packages) if (and (or (not installed-only-p)
(and (assq sym package-alist) (package-installed-p sym))
(list sym))) (or (assq sym doom-packages)
(and (assq sym package-alist)
(list sym))))
collect it)) collect it))
;;;###autoload ;;;###autoload
@ -121,7 +125,7 @@ If INCLUDE-FROZEN-P is non-nil, check frozen packages as well.
Used by `doom/packages-update'." Used by `doom/packages-update'."
(let (quelpa-pkgs elpa-pkgs) (let (quelpa-pkgs elpa-pkgs)
;; Separate quelpa from elpa packages ;; Separate quelpa from elpa packages
(dolist (pkg (doom-get-packages)) (dolist (pkg (doom-get-packages t))
(let ((sym (car pkg))) (let ((sym (car pkg)))
(when (and (or (not (doom-package-prop sym :freeze)) (when (and (or (not (doom-package-prop sym :freeze))
include-frozen-p) include-frozen-p)

View file

@ -1,5 +1,7 @@
;;; core/autoload/popups.el -*- lexical-binding: t; -*- ;;; core/autoload/popups.el -*- lexical-binding: t; -*-
(defvar doom-popup-remember-history)
;;;###autoload ;;;###autoload
(defun doom-popup-p (&optional target) (defun doom-popup-p (&optional target)
"Return TARGET (a window) if TARGET (a window or buffer) is a popup. Uses "Return TARGET (a window) if TARGET (a window or buffer) is a popup. Uses
@ -47,7 +49,7 @@ possible rules."
;;;###autoload ;;;###autoload
(defun doom-popup-windows () (defun doom-popup-windows ()
"Get a list of open pop up windows." "Get a list of open pop up windows."
(cl-remove-if-not #'doom-popup-p (window-list))) (cl-remove-if-not #'doom-popup-p doom-popup-windows))
;;;###autoload ;;;###autoload
(defun doom/popup-restore () (defun doom/popup-restore ()
@ -129,7 +131,7 @@ only close popups that have an :autoclose property in their rule (see
(delete-window))) (delete-window)))
;;;###autoload ;;;###autoload
(defun doom/popup () (defun doom/popup-this-buffer ()
"Display currently selected buffer in a popup window." "Display currently selected buffer in a popup window."
(interactive) (interactive)
(doom-popup-buffer (current-buffer) :align t :autokill t)) (doom-popup-buffer (current-buffer) :align t :autokill t))
@ -146,14 +148,15 @@ only close popups that have an :autoclose property in their rule (see
(defun doom-popup-prop (prop &optional window) (defun doom-popup-prop (prop &optional window)
"Returns a `doom-popup-rules' PROPerty from WINDOW." "Returns a `doom-popup-rules' PROPerty from WINDOW."
(or (plist-get (or (if window (or (plist-get (or (if window
(buffer-local-value 'doom-popup-rules (window-buffer window)) (ignore-errors
(buffer-local-value 'doom-popup-rules
(window-buffer window)))
doom-popup-rules) doom-popup-rules)
(window-parameter window 'popup)) (window-parameter window 'popup))
prop) prop)
(cond ((eq prop :size) (pcase prop
shackle-default-size) (:size shackle-default-size)
((eq prop :align) (:align shackle-default-alignment))))
shackle-default-alignment))))
;;;###autoload ;;;###autoload
(defun doom-popup-side (&optional window) (defun doom-popup-side (&optional window)
@ -168,11 +171,9 @@ only close popups that have an :autoclose property in their rule (see
;;;###autoload ;;;###autoload
(defun doom-popup-size (&optional window) (defun doom-popup-size (&optional window)
"Return the size of a popup WINDOW." "Return the size of a popup WINDOW."
(let ((side (doom-popup-side window))) (pcase (doom-popup-side window)
(cond ((memq side '(left right)) ((or 'left 'right) (window-width window))
(window-width window)) ((or 'above 'below) (window-height window))))
((memq side '(above below))
(window-height window)))))
(defun doom--popup-data (window) (defun doom--popup-data (window)
(when-let (buffer (window-buffer window)) (when-let (buffer (window-buffer window))
@ -183,9 +184,26 @@ only close popups that have an :autoclose property in their rule (see
;;;###autoload ;;;###autoload
(defmacro with-popup-rules! (rules &rest body) (defmacro with-popup-rules! (rules &rest body)
"TODO"
(declare (indent defun)) (declare (indent defun))
`(let ((old-shackle-rules shackle-rules)) `(let ((old-shackle-rules shackle-rules))
,@(cl-loop for rule in rules ,@(cl-loop for rule in rules
collect `(set! :popup ,@rule)) collect `(set! :popup ,@rule))
,@body ,@body
(setq shackle-rules old-shackle-rules))) (setq shackle-rules old-shackle-rules)))
;;;###autoload
(defun doom/other-popup (count)
"Cycle through popup windows. Like `other-window', but for popups."
(interactive "p")
(if-let (popups (if (doom-popup-p)
(cdr (memq (selected-window) doom-popup-windows))
(setq doom-popup-other-window (selected-window))
doom-popup-windows))
(select-window (nth (mod (1- count) (length popups)) popups))
(unless (eq (selected-window) doom-popup-other-window)
(when doom-popup-other-window
(select-window doom-popup-other-window t)
(cl-decf count))
(when (/= count 0)
(other-window count)))))

View file

@ -21,14 +21,14 @@ command line args following a double dash (each arg should be in the
'module/submodule' format). 'module/submodule' format).
If neither is available, run all tests in all enabled modules." If neither is available, run all tests in all enabled modules."
(interactive) ;; TODO Add completing-read selection of tests (interactive) ; must be interactive to be run from batch
;; FIXME Refactor this ;; FIXME Refactor this
(condition-case-unless-debug ex (condition-case-unless-debug ex
(let (targets) (let (targets)
;; ensure DOOM is initialized ;; ensure DOOM is initialized
(unload-feature 'core t)
(let (noninteractive) (let (noninteractive)
(load (expand-file-name "core/core.el" user-emacs-directory) nil t)) (load (expand-file-name "init.el" user-emacs-directory) nil t))
(remove-hook 'doom-init-hook #'doom--display-benchmark)
;; collect targets ;; collect targets
(cond ((and command-line-args-left (cond ((and command-line-args-left
(equal (car command-line-args-left) "--")) (equal (car command-line-args-left) "--"))

View file

@ -13,7 +13,9 @@
(defun doom/toggle-line-numbers (&optional arg) (defun doom/toggle-line-numbers (&optional arg)
"Toggle `linum-mode'." "Toggle `linum-mode'."
(interactive "P") (interactive "P")
(cond ((featurep 'nlinum) (cond ((boundp 'display-line-numbers)
(setq display-line-numbers (not display-line-numbers)))
((featurep 'nlinum)
(nlinum-mode (or arg (if nlinum-mode -1 +1)))) (nlinum-mode (or arg (if nlinum-mode -1 +1))))
((featurep 'linum) ((featurep 'linum)
(linum-mode (or arg (if linum-mode -1 +1)))) (linum-mode (or arg (if linum-mode -1 +1))))

View file

@ -89,6 +89,45 @@ 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)
;; ensure indirect buffers have buffer-file-name
(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)
;; ;;
;; Built-in plugins ;; Built-in plugins
@ -205,16 +244,13 @@ fundamental-mode) for performance sake."
(def-package! undo-tree (def-package! undo-tree
:demand t :demand t
:config :config
(global-undo-tree-mode +1)
;; persistent undo history is known to cause undo history corruption, which ;; persistent undo history is known to cause undo history corruption, which
;; can be very destructive! So disable it! ;; can be very destructive! So disable it!
(setq undo-tree-auto-save-history nil (setq undo-tree-auto-save-history nil
undo-tree-history-directory-alist undo-tree-history-directory-alist
(list (cons "." (concat doom-cache-dir "undo-tree-hist/")))) (list (cons "." (concat doom-cache-dir "undo-tree-hist/")))))
(defun doom*silence-undo-tree-load (orig-fn &rest args)
"Silence undo-tree load errors."
(quiet! (apply orig-fn args)))
(advice-add #'undo-tree-load-history-hook :around #'doom*silence-undo-tree-load))
;; ;;

View file

@ -4,11 +4,18 @@
;; together `use-package', `quelpa' and package.el to create my own, ;; together `use-package', `quelpa' and package.el to create my own,
;; rolling-release, lazily-loaded package management system for Emacs. ;; rolling-release, lazily-loaded package management system for Emacs.
;; ;;
;; The three key commands are `doom/packages-install', `doom/packages-update' ;; The three key commands are:
;; and `doom/packages-autoremove', which can be called via 'make' on the command ;;
;; line (make {install,update,autoremove}). These read packages.el files in each ;; + `make install` or `doom/packages-install': Installs packages that are
;; activated module in `doom-modules-dir' (and one in `doom-core-dir') which ;; wanted, but not installed.
;; tell DOOM what plugins to install and where from. ;; + `make update` or `doom/packages-update': Updates packages that are
;; out-of-date.
;; + `make autoremove` or `doom/packages-autoremove': Uninstalls packages that
;; are no longer needed.
;;
;; This system reads packages.el files located in each activated module (and one
;; in `doom-core-dir'). These contain `package!` blocks that tell DOOM what
;; plugins to install and where from.
;; ;;
;; Why all the trouble? Because: ;; Why all the trouble? Because:
;; 1. Scriptability: I live in the command line. I want a programmable ;; 1. Scriptability: I live in the command line. I want a programmable
@ -178,7 +185,7 @@ to speed up startup."
(unless (file-exists-p doom-autoload-file) (unless (file-exists-p doom-autoload-file)
(quiet! (doom/reload-autoloads)))) (quiet! (doom/reload-autoloads))))
(defun doom-initialize-packages (&optional force-p load-p) (defun doom-initialize-packages (&optional force-p)
"Crawls across your emacs.d to fill `doom-modules' (from init.el) and "Crawls across your emacs.d to fill `doom-modules' (from init.el) and
`doom-packages' (from packages.el files), if they aren't set already. `doom-packages' (from packages.el files), if they aren't set already.
@ -186,33 +193,26 @@ 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 force-p)
(let ((noninteractive t) (unwind-protect
(load-fn (let ((noninteractive t)
(lambda (file &optional noerror) (load-fn
(condition-case-unless-debug ex (lambda (file &optional noerror)
(load file noerror :nomessage :nosuffix) (condition-case-unless-debug ex
('error (load file noerror :nomessage :nosuffix)
(error (format "(doom-initialize-packages) %s in %s: %s" ('error
(car ex) (error (format "(doom-initialize-packages) %s in %s: %s"
(file-relative-name file doom-emacs-dir) (car ex)
(error-message-string ex)) (file-relative-name file doom-emacs-dir)
:error)))))) (error-message-string ex))))))))
(when (or force-p (not doom-modules)) (when (or force-p (not doom-modules))
(setq doom-modules nil) (setq doom-modules nil)
(funcall load-fn (expand-file-name "init.el" doom-emacs-dir)) (funcall load-fn (expand-file-name "init.el" doom-emacs-dir)))
(funcall load-fn (doom-module-path :private user-login-name "init.el") t) (when (or force-p (not doom-packages))
(when load-p (setq doom-packages nil)
(cl-loop for file (funcall load-fn (expand-file-name "packages.el" doom-core-dir))
in (append (nreverse (file-expand-wildcards (expand-file-name "core*.el" doom-core-dir))) (dolist (file (doom--module-paths "packages.el"))
(file-expand-wildcards (expand-file-name "autoload/*.el" doom-core-dir)) (funcall load-fn file t))))
(doom--module-paths "config.el")) (doom|finalize)))
do (funcall load-fn file t)))
(doom|finalize))
(when (or force-p (not doom-packages))
(setq doom-packages nil)
(funcall load-fn (expand-file-name "packages.el" doom-core-dir))
(dolist (file (doom--module-paths "packages.el"))
(funcall load-fn file t)))))
(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.
@ -305,6 +305,12 @@ MODULES is an malformed plist of modules to load."
(setq doom-modules ',doom-modules) (setq doom-modules ',doom-modules)
(unless noninteractive (unless noninteractive
(require 'core-ui) ; draw me like one of your French editors
(require 'core-popups) ; taming sudden yet inevitable windows
(require 'core-editor) ; baseline configuration for text editing
(require 'core-projects) ; making Emacs project-aware
(require 'core-keybinds) ; centralized keybind system + which-key
(load ,(doom-module-path :private user-login-name "init") t t) (load ,(doom-module-path :private user-login-name "init") t t)
,@(cl-loop for (module . submodule) in (doom--module-pairs) ,@(cl-loop for (module . submodule) in (doom--module-pairs)
collect `(require! ,module ,submodule t)) collect `(require! ,module ,submodule t))
@ -563,7 +569,7 @@ If ONLY-RECOMPILE-P is non-nil, only recompile out-of-date files."
(interactive "P") (interactive "P")
;; Ensure all relevant config files are loaded and up-to-date. This way we ;; Ensure all relevant config files are loaded and up-to-date. This way we
;; don't need eval-when-compile and require blocks scattered all over. ;; don't need eval-when-compile and require blocks scattered all over.
(doom-initialize-packages t noninteractive) (doom-initialize-packages t)
(let ((targets (let ((targets
(cond ((equal (car command-line-args-left) "--") (cond ((equal (car command-line-args-left) "--")
(cl-loop for file in (cdr command-line-args-left) (cl-loop for file in (cdr command-line-args-left)
@ -614,18 +620,19 @@ If ONLY-RECOMPILE-P is non-nil, only recompile out-of-date files."
"Recompile any out-of-date compiled *.el files in your Emacs configuration." "Recompile any out-of-date compiled *.el files in your Emacs configuration."
(interactive) (interactive)
(doom/compile nil :recompile) (doom/compile nil :recompile)
;; In case `load-path' has changed (e.g. after an update) ;; Forcibly recompile core.el in case `load-path' has changed
(byte-recompile-file (expand-file-name "core.el" doom-core-dir) t)) (byte-recompile-file (expand-file-name "core.el" doom-core-dir) t))
(defun doom/clean-cache () (defun doom/reset ()
"Clear the local cache completely (in `doom-cache-dir'). "Clear the local cache completely (in `doom-cache-dir').
You must restart Emacs for some components to feel its effects." This resets Emacs to a blank slate. You must restart Emacs for some components
to feel its effects."
(interactive) (interactive)
(delete-directory doom-cache-dir t) (delete-directory doom-cache-dir t)
(make-directory doom-cache-dir t)) (make-directory doom-cache-dir t))
(defun doom/clean-compiled () (defun doom/clean-compiled-files ()
"Delete all compiled elc files in your Emacs configuration. "Delete all compiled elc files in your Emacs configuration.
This excludes compiled packages in `doom-packages-dir'." This excludes compiled packages in `doom-packages-dir'."

View file

@ -28,6 +28,9 @@
(defvar doom-popup-no-fringes t (defvar doom-popup-no-fringes t
"If non-nil, disable fringes in popup windows.") "If non-nil, disable fringes in popup windows.")
(defvar doom-popup-windows ()
"A list of open popup windows.")
(defvar-local doom-popup-rules nil (defvar-local doom-popup-rules nil
"The shackle rule that caused this buffer to be recognized as a popup.") "The shackle rule that caused this buffer to be recognized as a popup.")
@ -94,7 +97,7 @@ recognized by DOOM's popup system. They are:
("^ \\*" :regexp t :size 12 :noselect t :autokill t :autoclose t))) ("^ \\*" :regexp t :size 12 :noselect t :autokill t :autoclose t)))
:config :config
(add-hook 'doom-init-hook #'shackle-mode) (add-hook 'doom-post-init-hook #'shackle-mode)
(defun doom*shackle-always-align (plist) (defun doom*shackle-always-align (plist)
"Ensure popups are always aligned and selected by default. Eliminates the need "Ensure popups are always aligned and selected by default. Eliminates the need
@ -215,6 +218,7 @@ and setting `doom-popup-rules' within it. Returns the window."
(setcar args (clone-indirect-buffer (buffer-name (car args)) nil t))) (setcar args (clone-indirect-buffer (buffer-name (car args)) nil t)))
(unless (setq window (apply orig-fn args)) (unless (setq window (apply orig-fn args))
(error "No popup window was found for %s: %s" (car args) plist)) (error "No popup window was found for %s: %s" (car args) plist))
(cl-pushnew window doom-popup-windows :test #'eq)
(with-selected-window window (with-selected-window window
(unless (eq plist t) (unless (eq plist t)
(setq-local doom-popup-rules plist)) (setq-local doom-popup-rules plist))
@ -241,6 +245,7 @@ prevent the popup(s) from messing up the UI (or vice versa)."
properties." properties."
(let ((window (or window (selected-window)))) (let ((window (or window (selected-window))))
(when (doom-popup-p window) (when (doom-popup-p window)
(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 (plist-get doom-popup-rules :autokill))) (let ((autokill-p (plist-get doom-popup-rules :autokill)))
@ -407,19 +412,19 @@ the command buffer."
(advice-add #'helm-ag--edit :around #'doom*helm-ag-edit))) (advice-add #'helm-ag--edit :around #'doom*helm-ag-edit)))
(defsubst doom--switch-from-popup (location)
(doom/popup-close)
(switch-to-buffer (car location) nil t)
(if (not (cdr location))
(message "Unable to find location in file")
(goto-char (cdr location))
(recenter)))
(after! help-mode (after! help-mode
;; Help buffers use `other-window' to decide where to open followed links, ;; Help buffers use `other-window' to decide where to open followed links,
;; which can be unpredictable. It should *only* replace the original buffer we ;; which can be unpredictable. It should *only* replace the original buffer we
;; opened the popup from. To fix this these three button types need to be ;; opened the popup from. To fix this these three button types need to be
;; redefined to set aside the popup before following a link. ;; redefined to set aside the popup before following a link.
(defsubst doom--switch-from-popup (location)
(doom/popup-close)
(switch-to-buffer (car location) nil t)
(if (not (cdr location))
(message "Unable to find location in file")
(goto-char (cdr location))
(recenter)))
(define-button-type 'help-function-def (define-button-type 'help-function-def
:supertype 'help-xref :supertype 'help-xref
'help-function 'help-function
@ -553,6 +558,18 @@ you came from."
(advice-add #'xref-goto-xref :around #'doom*xref-follow-and-close)) (advice-add #'xref-goto-xref :around #'doom*xref-follow-and-close))
;;
;; Major modes
;;
(after! plantuml-mode
(defun doom*plantuml-preview-in-popup-window (orig-fn &rest args)
(save-window-excursion
(apply orig-fn args))
(pop-to-buffer plantuml-preview-buffer))
(advice-add #'plantuml-preview-string
:around #'doom*plantuml-preview-in-popup-window))
;; Ensure these settings are attached to org-load-hook as late as possible, ;; Ensure these settings are attached to org-load-hook as late as possible,
;; giving other modules a chance to add their own hooks. ;; giving other modules a chance to add their own hooks.
(defun doom|init-org-popups () (defun doom|init-org-popups ()

View file

@ -108,7 +108,6 @@ like a space that `whitespace-mode' won't affect.")
(defun doom-quit-p (&optional prompt) (defun doom-quit-p (&optional prompt)
"Return t if this session should be killed. Prompts the user for "Return t if this session should be killed. Prompts the user for
confirmation." confirmation."
(interactive)
(if (ignore-errors (doom-real-buffer-list)) (if (ignore-errors (doom-real-buffer-list))
(or (yes-or-no-p (format " %s" (or prompt "Quit Emacs?"))) (or (yes-or-no-p (format " %s" (or prompt "Quit Emacs?")))
(ignore (message "Aborted"))) (ignore (message "Aborted")))
@ -257,6 +256,13 @@ 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)
;; line numbers in newer version of Emacs
(when (boundp 'display-line-numbers)
(defun doom|init-line-numbers ()
(unless (eq major-mode 'org-mode)
(setq display-line-numbers t)))
(add-hook! (prog-mode text-mode) #'doom|init-line-numbers))
;; ;;
;; Plugins ;; Plugins
@ -319,8 +325,10 @@ local value, whether or not it's permanent-local. Therefore, we cycle
(add-hook 'evil-visual-state-exit-hook #'hl-line-mode))) (add-hook 'evil-visual-state-exit-hook #'hl-line-mode)))
;; Line number column. A faster (or equivalent, in the worst case) line number ;; Line number column. A faster (or equivalent, in the worst case) line number
;; plugin than the built-in `linum'. ;; plugin than the built-in `linum'. This will be ignored if you're using Emacs
;; 26.1+, which has native line number support.
(def-package! nlinum (def-package! nlinum
:unless (boundp 'display-line-numbers)
:commands nlinum-mode :commands nlinum-mode
:init :init
(defun doom|init-nlinum-mode () (defun doom|init-nlinum-mode ()
@ -358,6 +366,7 @@ local value, whether or not it's permanent-local. Therefore, we cycle
;; Fixes disappearing line numbers in nlinum and other quirks ;; Fixes disappearing line numbers in nlinum and other quirks
(def-package! nlinum-hl (def-package! nlinum-hl
:unless (boundp 'display-line-numbers)
:after nlinum :after nlinum
:config :config
;; With `markdown-fontify-code-blocks-natively' enabled in `markdown-mode', ;; With `markdown-fontify-code-blocks-natively' enabled in `markdown-mode',

View file

@ -53,10 +53,10 @@ config files that are stable (i.e. it should be unlikely that you need to delete
them if something goes wrong).") them if something goes wrong).")
(defvar doom-cache-dir (concat doom-host-dir "/cache/") (defvar doom-cache-dir (concat doom-host-dir "/cache/")
"Host-namespaced directory for volatile storage. Deleted when "Host-namespaced directory for volatile storage. Deleted when `doom/reset' is
`doom/clean-cache' is called. Use this for transient files that are generated on called. Use this for transient files that are generated on the fly like caches
the fly like caches and temporary files. Anything that may need to be cleared if and temporary files. Anything that may need to be cleared if there are
there are problems.") 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.")
@ -146,30 +146,18 @@ ability to invoke the debugger in debug mode."
(car ex) fn (error-message-string ex)))) (car ex) fn (error-message-string ex))))
nil) nil)
;; Automatic minor modes (defun doom|finalize ()
(defvar doom-auto-minor-mode-alist '() (unless doom-init-p
"Alist mapping filename patterns to corresponding minor mode functions, like (dolist (hook '(doom-init-hook doom-post-init-hook))
`auto-mode-alist'. All elements of this alist are checked, meaning you can (run-hook-wrapped hook #'doom-try-run-hook hook))
enable multiple minor modes for the same regexp.") (setq doom-init-p t))
(defun doom|enable-minor-mode-maybe () ;; Don't keep gc-cons-threshold too high. It helps to stave off the GC while
"Check file name against `doom-auto-minor-mode-alist'." ;; Emacs starts up, but afterwards it causes stuttering and random freezes. So
(when buffer-file-name ;; reset it to a reasonable default.
(let ((name buffer-file-name) (setq gc-cons-threshold 16777216
(remote-id (file-remote-p buffer-file-name)) gc-cons-percentage 0.1
(alist doom-auto-minor-mode-alist)) file-name-handler-alist doom--file-name-handler-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)
;;; ;;;
@ -190,26 +178,6 @@ enable multiple minor modes for the same regexp.")
(setq load-path (eval-when-compile load-path) (setq load-path (eval-when-compile load-path)
doom--package-load-path (eval-when-compile doom--package-load-path)) doom--package-load-path (eval-when-compile doom--package-load-path))
(defun doom|finalize ()
;; 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)
(unless doom-init-p
(dolist (hook '(doom-init-hook doom-post-init-hook))
(run-hook-wrapped hook #'doom-try-run-hook hook))
(setq file-name-handler-alist doom--file-name-handler-alist
doom-init-p t)))
(add-hook! '(emacs-startup-hook doom-reload-hook)
#'doom|finalize)
;;;
;; Bootstrap
(load! core-os) ; consistent behavior across OSes (load! core-os) ; consistent behavior across OSes
(condition-case-unless-debug ex (condition-case-unless-debug ex
(require 'autoloads doom-autoload-file t) (require 'autoloads doom-autoload-file t)
@ -218,12 +186,8 @@ enable multiple minor modes for the same regexp.")
"%s in autoloads.el -> %s" "%s in autoloads.el -> %s"
(car ex) (error-message-string ex)))) (car ex) (error-message-string ex))))
(unless noninteractive (add-hook! '(emacs-startup-hook doom-reload-hook)
(load! core-ui) ; draw me like one of your French editors #'doom|finalize)
(load! core-popups) ; taming sudden yet inevitable windows
(load! core-editor) ; baseline configuration for text editing
(load! core-projects) ; making Emacs project-aware
(load! core-keybinds)) ; centralized keybind system + which-key
(provide 'core) (provide 'core)
;;; core.el ends here ;;; core.el ends here

View file

@ -17,8 +17,9 @@
(package! fringe-helper) (package! fringe-helper)
(package! highlight-indentation) (package! highlight-indentation)
(package! highlight-numbers) (package! highlight-numbers)
(package! nlinum) (unless (boundp 'display-line-numbers)
(package! nlinum-hl) (package! nlinum)
(package! nlinum-hl))
(package! rainbow-delimiters) (package! rainbow-delimiters)
(package! vi-tilde-fringe) (package! vi-tilde-fringe)
(package! visual-fill-column) (package! visual-fill-column)

View file

@ -18,6 +18,14 @@ affects your Emacs packages)."
(package-initialize) (package-initialize)
,@forms)) ,@forms))
(defmacro -with-packages! (packages package-descs &rest body)
`(let ((doom-packages ,packages)
(package-alist ,package-descs)
doom-core-packages)
(cl-letf (((symbol-function 'doom-initialize-packages) (lambda (&rest _)))
((symbol-function 'package-installed-p) (lambda (name &rest _) (assq name package-alist))))
,@body)))
;; ;;
;; Tests ;; Tests
@ -31,45 +39,40 @@ affects your Emacs packages)."
(should (eq (doom-package-backend 'doom-quelpa-dummy) 'quelpa)))) (should (eq (doom-package-backend 'doom-quelpa-dummy) 'quelpa))))
(def-test! elpa-outdated-detection (def-test! elpa-outdated-detection
(cl-letf (((symbol-function 'package-refresh-contents) (lambda (&rest _)))) (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 ,(-new-package 'doom-dummy '(20160405 1234))))) (package-archive-contents
(package-archive-contents `((doom-dummy ,(-new-package 'doom-dummy '(20170405 1234))))))
`((doom-dummy ,(-new-package 'doom-dummy '(20170405 1234))))) (cl-letf (((symbol-function 'package-refresh-contents) (lambda (&rest _))))
(outdated (doom-package-outdated-p 'doom-dummy))) (should (equal (doom-package-outdated-p 'doom-dummy)
(should outdated) '(doom-dummy (20160405 1234) (20170405 1234)))))))
(should (equal outdated '(doom-dummy (20160405 1234) (20170405 1234)))))))
;; TODO quelpa-outdated-detection ;; TODO quelpa-outdated-detection
(def-test! get-packages (def-test! get-packages
(let ((quelpa-initialized-p t) (let ((quelpa-initialized-p t))
(doom-packages '((doom-dummy))) (-with-packages!
(package-alist '((doom-dummy))
`((doom-dummy nil) '((doom-dummy nil)
(doom-dummy-dep nil))) (doom-dummy-unwanted nil)
doom-core-packages) (doom-dummy-dep nil))
(cl-letf (((symbol-function 'doom-initialize-packages) (lambda (&rest _)))) (should (equal (doom-get-packages) '((doom-dummy)))))))
(should (equal (doom-get-packages) '((doom-dummy)))))))
(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."
(let ((doom-packages '((doom-dummy))) (-with-packages!
(package-alist '((doom-dummy))
`((doom-dummy ,(-new-package 'doom-dummy '(20160405 1234) '((doom-dummy-dep (1 0))))) `((doom-dummy ,(-new-package 'doom-dummy '(20160405 1234) '((doom-dummy-dep (1 0)))))
(doom-dummy-unwanted ,(-new-package 'doom-dummy-unwanted '(20160601 1234))) (doom-dummy-unwanted ,(-new-package 'doom-dummy-unwanted '(20160601 1234)))
(doom-dummy-dep ,(-new-package 'doom-dummy-dep '(20160301 1234))))) (doom-dummy-dep ,(-new-package 'doom-dummy-dep '(20160301 1234))))
doom-core-packages) (should (equal (doom-get-orphaned-packages) '(doom-dummy-unwanted)))))
(cl-letf (((symbol-function 'doom-initialize-packages) (lambda (&rest _))))
(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."
(let ((doom-packages '((doom-dummy) (doom-dummy-installed))) (-with-packages!
(package-alist `((doom-dummy-installed ,(-new-package 'doom-dummy-installed '(20160405 1234))))) '((doom-dummy) (doom-dummy-installed))
doom-core-packages) `((doom-dummy-installed ,(-new-package 'doom-dummy-installed '(20160405 1234))))
(cl-letf (((symbol-function 'doom-initialize-packages) (lambda (&rest _)))) (should (equal (doom-get-missing-packages) '((doom-dummy))))))
(should (equal (doom-get-missing-packages) '((doom-dummy)))))))

View file

@ -42,7 +42,7 @@
;debug ; FIXME stepping through code, to help you add bugs ;debug ; FIXME stepping through code, to help you add bugs
:completion :completion
company ; code completion backend company ; the ultimate code completion backend
ivy ; a search engine for love and life ivy ; a search engine for love and life
;helm ; the *other* search engine for love and life ;helm ; the *other* search engine for love and life
;ido ; the other *other* search engine... ;ido ; the other *other* search engine...
@ -91,7 +91,9 @@
lua ; one-based indices? one-based indices lua ; one-based indices? one-based indices
markdown ; writing docs for people to ignore markdown ; writing docs for people to ignore
ocaml ; an objective camel ocaml ; an objective camel
perl ; write code no one else can comprehend
php ; make php less awful to work with php ; make php less awful to work with
plantuml ; diagrams for confusing people more
purescript ; javascript, but functional purescript ; javascript, but functional
python ; beautiful is better than ugly python ; beautiful is better than ugly
rest ; Emacs as a REST client rest ; Emacs as a REST client
@ -115,9 +117,10 @@
;org-publish ; TODO org + blogs ;org-publish ; TODO org + blogs
;; Applications are complex and opinionated modules that transform Emacs ;; Applications are complex and opinionated modules that transform Emacs
;; toward a specific purpose. They should be loaded last. ;; toward a specific purpose. They may have additional dependencies and
;; should be loaded last.
:app :app
email ; Emacs as an email client email ; emacs as an email client
irc ; how neckbeards socialize irc ; how neckbeards socialize
rss ; emacs as an RSS reader rss ; emacs as an RSS reader
twitter ; twitter client https://twitter.com/vnought twitter ; twitter client https://twitter.com/vnought

View file

@ -2,8 +2,18 @@
(require 'core (concat user-emacs-directory "core/core")) (require 'core (concat user-emacs-directory "core/core"))
(doom! :feature evil (doom! :feature
:completion company evil
:tools password-store workspaces
:lang web
:private hlissner) :completion
company
:tools
password-store
:lang
web
:private
hlissner)

View file

@ -163,6 +163,6 @@ These are /not/ loaded automatically. Use ~load!~ to do so.
+ ~doom/reload-autoloads~ + ~doom/reload-autoloads~
+ ~doom/compile~ + ~doom/compile~
+ ~doom/recompile~ + ~doom/recompile~
+ ~doom/clean-cache~ + ~doom/reset~
+ ~doom/clean-compiled~ + ~doom/clean-compiled~

View file

@ -140,7 +140,7 @@ default/fallback account."
mu4e-marks) mu4e-marks)
;; This hook correctly modifies gmail flags on emails when they are marked. ;; This hook correctly modifies gmail flags on emails when they are marked.
;; Without it refiling (archiving), trashing, and flagging (starring) email ;; Without it, refiling (archiving), trashing, and flagging (starring) email
;; won't properly result in the corresponding gmail action, since the marks ;; won't properly result in the corresponding gmail action, since the marks
;; are ineffectual otherwise. ;; are ineffectual otherwise.
(defun +email|gmail-fix-flags (mark msg) (defun +email|gmail-fix-flags (mark msg)

View file

@ -20,10 +20,10 @@
(defvar +ivy--file-search-all-files-p nil) (defvar +ivy--file-search-all-files-p nil)
(defun +ivy--file-search (engine beg end query &optional directory) (defun +ivy--file-search (engine beg end query &optional directory)
(let* ((directory (or directory (doom-project-root))) (let* ((project-root (doom-project-root))
(directory (or directory project-root))
(recursion-p +ivy--file-search-recursion-p) (recursion-p +ivy--file-search-recursion-p)
(all-files-p +ivy--file-search-all-files-p) (all-files-p +ivy--file-search-all-files-p)
(project-root (doom-project-root))
(query (query
(or query (or query
(and beg end (and beg end
@ -40,24 +40,22 @@
(t (t
(file-relative-name directory project-root)))))) (file-relative-name directory project-root))))))
(setq +ivy--file-last-search query) (setq +ivy--file-last-search query)
(cond ((eq engine 'ag) (pcase engine
(let ((args (concat ('ag
(if all-files-p " -a") (let ((args (concat
(unless recursion-p " -n")))) (if all-files-p " -a")
(counsel-ag query directory args (format prompt args)))) (unless recursion-p " -n"))))
(counsel-ag query directory args (format prompt args))))
((eq engine 'rg) ('rg
;; smart-case instead of case-insensitive flag ;; smart-case instead of case-insensitive flag
(let ((counsel-rg-base-command (let ((counsel-rg-base-command
(replace-regexp-in-string " -i " " -S " counsel-rg-base-command)) (replace-regexp-in-string " -i " " -S " counsel-rg-base-command))
(args (concat (args (concat
(if all-files-p " -uu") (if all-files-p " -uu")
(unless recursion-p " --maxdepth 0")))) (unless recursion-p " --maxdepth 0"))))
(counsel-rg query directory args (format prompt args)))) (counsel-rg query directory args (format prompt args))))
('pt) ;; TODO pt search engine (necessary?)
((eq engine 'pt)) ; TODO pt search engine (necessary?) (_ (error "No search engine specified")))))
(t (error "No search engine specified")))))
;;;###autoload (autoload '+ivy:ag "completion/ivy/autoload/evil" nil t) ;;;###autoload (autoload '+ivy:ag "completion/ivy/autoload/evil" nil t)
(evil-define-operator +ivy:ag (beg end query &optional all-files-p directory) (evil-define-operator +ivy:ag (beg end query &optional all-files-p directory)

View file

@ -3,9 +3,8 @@
;; Show more information in ivy-switch-buffer; and only display ;; Show more information in ivy-switch-buffer; and only display
;; workgroup-relevant buffers. ;; workgroup-relevant buffers.
(defun +ivy--get-buffers (&optional buffer-list) (defun +ivy--get-buffers (&optional buffer-list)
(when-let (buffer-list (or buffer-list (doom-buffer-list))) (when-let (buffer-list (delq (current-buffer) (or buffer-list (doom-buffer-list))))
(let* ((buffer-list (or buffer-list (doom-buffer-list))) (let* ((min-name
(min-name
(+ 5 (cl-loop for buf in buffer-list (+ 5 (cl-loop for buf in buffer-list
maximize (length (buffer-name buf))))) maximize (length (buffer-name buf)))))
(min-mode (min-mode
@ -38,35 +37,39 @@
(defun +ivy--select-buffer-action (buffer) (defun +ivy--select-buffer-action (buffer)
(ivy--switch-buffer-action (ivy--switch-buffer-action
(s-chop-suffix (string-remove-suffix
"[+]" "[+]"
(substring buffer 0 (string-match-p (regexp-quote " ") buffer))))) (substring buffer 0 (string-match-p (regexp-quote " ") buffer)))))
(defun +ivy--select-buffer-other-window-action (buffer) (defun +ivy--select-buffer-other-window-action (buffer)
(ivy--switch-buffer-other-window-action (ivy--switch-buffer-other-window-action
(s-chop-suffix (string-remove-suffix
"[+]" "[+]"
(substring buffer 0 (string-match-p (regexp-quote " ") buffer))))) (substring buffer 0 (string-match-p (regexp-quote " ") buffer)))))
;;;###autoload ;;;###autoload
(defun +ivy/switch-workspace-buffer (&optional other-window-p) (defun +ivy/switch-workspace-buffer (&optional other-window-p)
"Switch to an open buffer in the current workspace." "Switch to an open buffer in the current workspace.
If OTHER-WINDOW-P (universal arg), then open target in other window."
(interactive "P") (interactive "P")
(+ivy/switch-buffer other-window-p t)) (+ivy/switch-buffer other-window-p t))
;;;###autoload ;;;###autoload
(defun +ivy/switch-buffer (&optional other-window-p workspace-only-p) (defun +ivy/switch-buffer (&optional other-window-p workspace-only-p)
"Switch to an open buffer in the global buffer list. If WORKSPACE-ONLY-P, "Switch to an open buffer in the global buffer list.
limit to buffers in the current workspace."
If OTHER-WINDOW-P (universal arg), then open target in other window.
If WORKSPACE-ONLY-P (universal arg), limit to buffers in the current workspace."
(interactive "P") (interactive "P")
(ivy-read (format "%s buffers: " (if workspace-only-p "Workspace" "Global")) (ivy-read (format "%s buffers: " (if workspace-only-p "Workspace" "Global"))
(+ivy--get-buffers (unless workspace-only-p (buffer-list))) (+ivy--get-buffers (unless workspace-only-p (buffer-list)))
:action (if other-window-p :action (if other-window-p
'+ivy--select-buffer-other-window-action #'+ivy--select-buffer-other-window-action
'+ivy--select-buffer-action) #'+ivy--select-buffer-action)
:matcher 'ivy--switch-buffer-matcher :matcher #'ivy--switch-buffer-matcher
:keymap ivy-switch-buffer-map :keymap ivy-switch-buffer-map
:caller '+ivy/switch-workspace-buffer)) :caller #'+ivy/switch-workspace-buffer))
(defun +ivy--tasks-candidates (tasks) (defun +ivy--tasks-candidates (tasks)
"Generate a list of task tags (specified by `+ivy-task-tags') for "Generate a list of task tags (specified by `+ivy-task-tags') for

View file

@ -13,8 +13,8 @@
;;;###autoload (autoload '+evil/mc-make-cursor-here "feature/evil/autoload/evil-mc" nil t) ;;;###autoload (autoload '+evil/mc-make-cursor-here "feature/evil/autoload/evil-mc" nil t)
(evil-define-command +evil/mc-make-cursor-here () (evil-define-command +evil/mc-make-cursor-here ()
"Create a cursor at point. If in visual block or line mode, then create "Create a cursor at point. If in visual block or line mode, then create
cursors in column beneath+above the point on each line. Otherwise pauses cursors on each line of the selection, on the column of the cursor. Otherwise
cursors." pauses cursors."
:repeat nil :repeat nil
:keep-visual nil :keep-visual nil
:evil-mc t :evil-mc t

View file

@ -29,25 +29,28 @@
(defun +workspace-buffer-list (&optional persp) (defun +workspace-buffer-list (&optional persp)
"Return a list of buffers in PERSP (defaults to the current perspective). "Return a list of buffers in PERSP (defaults to the current perspective).
The buffer list is ordered by recency (same as `buffer-list').
PERSP can be a string (name of a workspace) or a perspective hash (satisfies PERSP can be a string (name of a workspace) or a perspective hash (satisfies
`+workspace-p'). `+workspace-p').
If PERSP is t, then return a list of orphaned buffers associated with no If PERSP is t, then return a list of orphaned buffers associated with no
perspectives." perspectives."
(cond ((not persp) (unless persp
(persp-buffer-list-restricted)) (setq persp (get-current-persp)))
((eq persp t) (if (eq persp t)
(cl-remove-if #'persp--buffer-in-persps (doom-buffer-list))) (cl-remove-if #'persp--buffer-in-persps (buffer-list))
((+workspace-p persp) (when (stringp persp)
(safe-persp-buffers persp)) (setq persp (+workspace-get persp t)))
((stringp persp) (cl-loop for buf in (buffer-list)
(safe-persp-buffers (+workspace-get persp t))))) if (persp-contain-buffer-p buf persp)
collect buf)))
;;;###autoload ;;;###autoload
(defun +workspace-p (obj) (defun +workspace-p (obj)
"Return t if OBJ is a perspective hash table." "Return t if OBJ is a perspective hash table."
(and obj (and obj
(hash-table-p obj) (cl-struct-p obj)
(perspective-p obj))) (perspective-p obj)))
;;;###autoload ;;;###autoload
@ -70,11 +73,21 @@ perspectives."
(error "%s is not an available workspace" name)) (error "%s is not an available workspace" name))
persp))) persp)))
;;;###autoload
(defalias '+workspace-current #'get-current-persp)
;;;###autoload ;;;###autoload
(defun +workspace-current-name () (defun +workspace-current-name ()
"Get the name of the currently active workspace." "Get the name of the currently active workspace."
(safe-persp-name (get-current-persp))) (safe-persp-name (get-current-persp)))
;;;###autoload
(defun +workspace-contains-buffer-p (&optional buffer workspace)
"Return non-nil if buffer is in workspace (defaults to current workspace)."
(unless workspace
(setq workspace (+workspace-current)))
(persp-contain-buffer-p buffer workspace nil))
;;;###autoload ;;;###autoload
(defun +workspace-load (name) (defun +workspace-load (name)
"Loads and inserts a single workspace (named NAME) into the current session. "Loads and inserts a single workspace (named NAME) into the current session.

View file

@ -55,16 +55,20 @@ renamed.")
;; 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)
(defun +workspaces|on-persp-mode ()
;; Remap `buffer-list' to current workspace's buffers in `doom-buffer-list'
(if persp-mode
(advice-add #'doom-buffer-list :override #'+workspace-buffer-list)
(advice-remove #'doom-buffer-list #'+workspace-buffer-list)))
(add-hook 'persp-mode-hook #'+workspaces|on-persp-mode)
;; Defer delayed warnings even further, so they appear after persp-mode is ;; Defer delayed warnings even further, so they appear after persp-mode is
;; started and the main workspace is ready to display them. Otherwise, warning ;; started and the main workspace is ready to display them. Otherwise, warning
;; buffers will be hidden on startup. ;; buffers will be hidden on startup.
(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))
;; Remap `buffer-list' to current workspace's buffers in
;; `doom-buffer-list'
(advice-add #'doom-buffer-list :override #'+workspace-buffer-list))
(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

View file

@ -0,0 +1,89 @@
;;; feature/workspaces/test/autoload-workspaces.el -*- lexical-binding: t; -*-
(require! :feature workspaces)
(defmacro -with-workspace! (buffer-args &rest body)
(declare (indent defun))
(let ((buffers
(cl-loop for bsym in buffer-args
collect `(,bsym (get-buffer-create ,(symbol-name bsym))))))
`(let (noninteractive)
(+workspaces|init)
(save-window-excursion
(let* (,@buffers)
(cl-loop with persp = (get-current-persp)
for buf in (list ,@(mapcar #'car buffers))
do (persp-add-buffer buf persp)
do (with-current-buffer buf
(setq buffer-file-name (make-temp-file "workspaces-test-"))))
,@body
(dolist (buf (list ,@(mapcar #'car buffers)))
(persp-remove-buffer buf)
(kill-buffer buf))))
(persp-mode -1)
(setq *persp-hash* nil
persp-buffer-props-hash nil))))
;;
(def-test! init
(-with-workspace! ()
(should (equal (+workspace-current-name) +workspaces-main))))
(def-test! advice
(should (advice-member-p #'+workspaces*auto-add-buffer #'switch-to-buffer)))
(def-test! current
(-with-workspace! ()
(should (equal (+workspace-current-name) +workspaces-main))
(should (+workspace-exists-p +workspaces-main))
(let ((workspace (+workspace-get +workspaces-main))
(current-workspace (+workspace-current)))
(should workspace)
(should (+workspace-p workspace))
(should (+workspace-p current-workspace))
(should (equal workspace current-workspace)))))
(def-test! workspace-list
(-with-workspace! ()
(should (equal (+workspace-list-names)
(list (+workspace-current-name))))
(should (equal (+workspace-list)
(list (+workspace-current))))))
(def-test! workspace-crud
"Creating, reading, updating and deleting workspaces."
(-with-workspace! ()
(let ((new-workspace-name "*new-test*")
(renamed-workspace-name "*old-test*"))
(should (+workspace-new new-workspace-name))
(should (seq-contains (+workspace-list-names) new-workspace-name))
(should (equal new-workspace-name
(+workspace-rename new-workspace-name renamed-workspace-name)))
(should-not (seq-contains (+workspace-list-names) new-workspace-name))
(should (seq-contains (+workspace-list-names) renamed-workspace-name))
(should (= (length (+workspace-list-names)) 2))
(+workspace-delete renamed-workspace-name)
(should (= (length (+workspace-list-names)) 1)))))
(def-test! workspace-switch
(-with-workspace! ()
(let ((new-workspace-name "*new-test*"))
(should-error (+workspace-switch new-workspace-name))
(should (+workspace-switch new-workspace-name t))
(should (equal (+workspace-current-name) new-workspace-name)))))
(def-test! buffer-list
(-with-workspace! (a b)
(let ((c (get-buffer-create "c"))
(d (get-buffer-create "d")))
(should (+workspace-contains-buffer-p a))
(should (+workspace-contains-buffer-p b))
(should-not (+workspace-contains-buffer-p c))
;; New (and real) buffers should be added to workspace buffer list.
(doom-set-buffer-real c t)
(switch-to-buffer "c")
(should (+workspace-contains-buffer-p c))
;; unreal buffers shouldn't
(switch-to-buffer "d")
(should-not (+workspace-contains-buffer-p d)))))

View file

@ -145,18 +145,6 @@
(def-package! disaster :commands disaster) (def-package! disaster :commands disaster)
;;
;; Plugins
;;
(when (featurep! :completion company)
(def-package! company-cmake :after cmake-mode)
(def-package! company-irony :after irony)
(def-package! company-irony-c-headers :after company-irony))
;; ;;
;; Major modes ;; Major modes
;; ;;
@ -166,8 +154,6 @@
:config :config
(set! :company-backend 'cmake-mode '(company-cmake company-yasnippet))) (set! :company-backend 'cmake-mode '(company-cmake company-yasnippet)))
(def-package! glsl-mode :mode ("\\.glsl$" "\\.vert$" "\\.frag$" "\\.geom$"))
(def-package! cuda-mode :mode "\\.cuh?$") (def-package! cuda-mode :mode "\\.cuh?$")
(def-package! opencl-mode :mode "\\.cl$") (def-package! opencl-mode :mode "\\.cl$")
@ -175,3 +161,29 @@
(def-package! demangle-mode (def-package! demangle-mode
:commands demangle-mode :commands demangle-mode
:init (add-hook 'llvm-mode-hook #'demangle-mode)) :init (add-hook 'llvm-mode-hook #'demangle-mode))
(def-package! glsl-mode
:mode "\\.glsl$"
:mode "\\.vert$"
:mode "\\.frag$"
:mode "\\.geom$")
;;
;; Plugins
;;
(when (featurep! :completion company)
(def-package! company-cmake :after cmake-mode)
(def-package! company-irony :after irony)
(def-package! company-irony-c-headers :after company-irony)
(def-package! company-glsl
:when (featurep! :completion company)
:after glsl-mode
:config
(if (executable-find "glslangValidator")
(warn "glsl-mode: couldn't find glslangValidator, disabling company-glsl")
(set! :company-backend 'glsl-mode '(company-glsl)))))

View file

@ -15,6 +15,7 @@
(package! flycheck-irony)) (package! flycheck-irony))
(when (featurep! :completion company) (when (featurep! :completion company)
(package! company-glsl :recipe (:fetcher github :repo "Kaali/company-glsl"))
(package! company-irony) (package! company-irony)
(package! company-irony-c-headers)) (package! company-irony-c-headers))

View file

@ -0,0 +1,15 @@
;;; lang/perl/config.el -*- lexical-binding: t; -*-
;; There's also `perl-mode' for perl < 6, which is already set up.
(when (featurep! :feature syntax-checker)
(add-hook 'perl-mode-hook #'flycheck-mode))
(def-package! perl6-mode
:init (require 'perl6-detect))
(def-package! flycheck-perl6
:after perl6-mode
:when (featurep! :feature syntax-checker)
:config (add-hook 'perl6-mode-hook #'flycheck-mode))

View file

@ -0,0 +1,7 @@
;; -*- no-byte-compile: t; -*-
;;; lang/perl/packages.el
(package! perl6-mode)
(when (featurep! :feature syntax-checker)
(package! flycheck-perl6))

View file

@ -0,0 +1,10 @@
;;; lang/plantuml/autoload.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +plantuml/install ()
"Install plantuml.jar."
(interactive)
(unless (file-exists-p plantuml-jar-path)
(user-error "plantuml.jar already installed"))
(url-copy-file "https://kent.dl.sourceforge.net/project/plantuml/plantuml.jar"
plantuml-jar-path))

View file

@ -0,0 +1,18 @@
;;; lang/plantuml/config.el -*- lexical-binding: t; -*-
(def-package! plantuml-mode
:mode "\\.p\\(lant\\)?uml$"
:config
(setq plantuml-jar-path (concat doom-etc-dir "plantuml.jar"))
(set! :popup "*PLANTUML Preview*" :size 25 :noselect t :autokill t)
(unless (executable-find "java")
(warn "plantuml-mode: can't find java, preview disabled."))
(unless (file-exists-p plantuml-jar-path)
(warn "plantuml-mode: can't find plantuml.jar; run M-x +plantuml/install.")))
(def-package! flycheck-plantuml
:when (featurep! :feature syntax-checker)
:after plantuml-mode
:config (flycheck-plantuml-setup))

View file

@ -0,0 +1,6 @@
;; -*- no-byte-compile: t; -*-
;;; lang/plantuml/packages.el
(package! plantuml-mode)
(when (featurep! :feature syntax-checker)
(package! flycheck-plantuml))

View file

@ -50,6 +50,6 @@
:when (featurep! :completion company) :when (featurep! :completion company)
:after sh-script :after sh-script
:config :config
(set! :company-backend 'sh-mode '(company-shell)) (set! :company-backend 'sh-mode '(company-shell company-files))
(setq company-shell-delete-duplicates t)) (setq company-shell-delete-duplicates t))

View file

@ -190,6 +190,11 @@ between the two."
:i "C-H" #'+org/table-previous-field :i "C-H" #'+org/table-previous-field
:i "C-K" #'+org/table-previous-row :i "C-K" #'+org/table-previous-row
:i "C-J" #'+org/table-next-row :i "C-J" #'+org/table-next-row
;; Expand tables (or shiftmeta move)
:ni "C-S-l" #'+org/table-append-field-or-shift-right
:ni "C-S-h" #'+org/table-prepend-field-or-shift-left
:ni "C-S-k" #'+org/table-prepend-row-or-shift-up
:ni "C-S-j" #'+org/table-append-row-or-shift-down
:n [tab] #'+org/toggle-fold :n [tab] #'+org/toggle-fold
:i [tab] #'+org/indent-or-next-field-or-yas-expand :i [tab] #'+org/indent-or-next-field-or-yas-expand

View file

@ -66,6 +66,9 @@
:m "A-j" #'+hlissner:multi-next-line :m "A-j" #'+hlissner:multi-next-line
:m "A-k" #'+hlissner:multi-previous-line :m "A-k" #'+hlissner:multi-previous-line
(:prefix "C-x"
"p" #'doom/other-popup)
;; --- <leader> ------------------------------------- ;; --- <leader> -------------------------------------
(:leader (:leader
@ -628,6 +631,7 @@
;; For elisp debugging ;; For elisp debugging
:map debugger-mode-map :map debugger-mode-map
:n "RET" #'debug-help-follow :n "RET" #'debug-help-follow
:n "e" #'debugger-eval-expression
:n "n" #'debugger-step-through :n "n" #'debugger-step-through
:n "c" #'debugger-continue) :n "c" #'debugger-continue)
@ -695,7 +699,7 @@
(evilem-default-keybindings prefix) (evilem-default-keybindings prefix)
(evilem-define (kbd (concat prefix " n")) #'evil-ex-search-next) (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 " N")) #'evil-ex-search-previous)
(evilem-define (kbd (concat prefix " s")) 'evil-snipe-repeat (evilem-define (kbd (concat prefix " s")) #'evil-snipe-repeat
:pre-hook (save-excursion (call-interactively #'evil-snipe-s)) :pre-hook (save-excursion (call-interactively #'evil-snipe-s))
:bind ((evil-snipe-scope 'buffer) :bind ((evil-snipe-scope 'buffer)
(evil-snipe-enable-highlight) (evil-snipe-enable-highlight)
@ -748,7 +752,9 @@
(:after org-mode (:after org-mode
(:map org-mode-map (:map org-mode-map
:i [remap doom/inflate-space-maybe] #'org-self-insert-command)) :i [remap doom/inflate-space-maybe] #'org-self-insert-command
:i "C-e" #'org-end-of-line
:i "C-a" #'org-beginning-of-line))
;; Make ESC quit all the things ;; Make ESC quit all the things
(:map (minibuffer-local-map (:map (minibuffer-local-map

View file

@ -57,7 +57,7 @@
(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) ; open current buffer in popup (ex! "pop[up]" #'doom/popup-this-buffer)
;; Project navigation ;; Project navigation
(ex! "a" #'projectile-find-other-file) (ex! "a" #'projectile-find-other-file)