diff --git a/README.md b/README.md index 60125414e..755b648e6 100644 --- a/README.md +++ b/README.md @@ -1,185 +1,253 @@ - - Made with Doom Emacs - - - Supports Emacs 26.x - 27.0.50 - - - Build status: develop - - - Join our discord server - -

+
+ +# Doom Emacs + +[Install](#install) • [Documentation] • [FAQ] • [Screenshots] • [Contribute](#contribute) + +![Made with Doom Emacs](https://img.shields.io/github/tag/hlissner/doom-emacs.svg?style=flat-square&label=release&color=58839b) +![Supports Emacs 26-27](https://img.shields.io/badge/Supports-Emacs_26.1_--_27.x-blueviolet.svg?style=flat-square&logo=GNU%20Emacs&logoColor=white) +![Latest commit](https://img.shields.io/github/last-commit/hlissner/doom-emacs/develop?style=flat-square) +![Build status: develop](https://img.shields.io/github/workflow/status/hlissner/doom-emacs/CI/develop?style=flat-square) +[![Discord Server](https://img.shields.io/discord/406534637242810369?color=blue&label=Discord%20Chat&logo=discord&logoColor=white&style=flat-square)][Discord] ![Doom Emacs Screenshot](https://raw.githubusercontent.com/hlissner/doom-emacs/screenshots/main.png) -

- Screenshots - | - Get started - | - Contribute - | - Documentation - | - FAQ -

+
--- -**Quick start** +### Table of Contents +- [Introduction](#introduction) +- [Features](#features) +- [Prerequisites](#prerequisites) +- [Install](#install) +- [Roadmap](#roadmap) +- [Getting help](#getting-help) +- [Contributing](#contributing) -1. **Install Emacs 26.1+**. 27 is recommended. _28+ is not supported_. -2. Install [ripgrep](https://github.com/BurntSushi/ripgrep) 11.0+. -3. Windows and BSD users will need GNU Find. -4. Clone Doom and run its installer: - - ```bash - git clone https://github.com/hlissner/doom-emacs ~/.emacs.d - ~/.emacs.d/bin/doom install - ``` - -Find more detailed install instructions [in the -documentation](docs/getting_started.org#install). - -**Table of Contents** - -- [What is Doom Emacs](#what-is-doom-emacs) - - [Doom's mantras](#dooms-mantras) - - [Features](#features) -- [Getting Help](#getting-help) - - [Community](#community) - - [Troubleshooting](#troubleshooting) - - [Contributing](#contributing) - -# What is Doom Emacs +# Introduction - + -It is a story as old as time. A stubborn, shell-dwelling, and melodramatic -vimmer -- envious of the features of modern text editors -- spirals into despair -before succumbing to the [dark side][url:evil-mode]. This is his config. +> It is a story as old as time. A stubborn, shell-dwelling, and melodramatic +> vimmer—envious of the features of modern text editors—spirals into +> despair before he succumbs to the [dark side][evil-mode]. This is his config. -Doom is a configuration framework for [GNU -Emacs](https://www.gnu.org/software/emacs/) tailored for Emacs bankruptcy -veterans who want less framework in their frameworks and the performance of a -hand rolled config (or better). It can be a foundation for your own config or a -resource for Emacs enthusiasts to learn more about our favorite OS. +Doom is a configuration framework for [GNU Emacs] tailored for Emacs bankruptcy +veterans who want less framework in their frameworks, a modicum of stability +(and reproducibility) from their package manager, and the performance of a hand +rolled config (or better). It can be a foundation for your own config or a +resource for Emacs enthusiasts to learn more about our favorite operating +system. -## Doom's mantras +Its design is guided by these mantras: -- **Gotta go fast.** Startup and run-time performance are priorities. Doom goes - beyond lazy loading packages by modifying them to be snappier and load lazier! -- **Close to metal.** There's less between you and vanilla Emacs by design. - There's less to grok, on top of Emacs. -- **Readability counts.** Internals ought to be written as if reading them were - part of the user experience, and it is! Modules should be syntactically sweet. - Backend logic should be functional (as much as elisp permits), abstraction - light and (hopefully) documented. -- **Opinionated, but not stubborn.** Doom is a bundle of reasonable defaults and - curated opinions, but all of it should be optional. Use as little or as much - of it as you like. -- **Your system, your rules.** There are more ways to set up your development - environment than there are dislikes on Youtube Rewind '18, so Doom leaves it - to you. Doom will not *automatically* install system dependencies (and will - coerce its plugins not to do so either). Use `doom doctor` to figure out - what's missing. ++ **Gotta go fast.** Startup and run-time performance are priorities. Doom goes + beyond by modifying packages to be snappier and load lazier. ++ **Close to metal.** There's less between you and vanilla Emacs by design. + That's less to grok and less to work around when you tinker. Internals ought + to be written as if reading them were part of Doom's UX, and it is! ++ **Opinionated, but not stubborn.** Doom is about reasonable defaults and + curated opinions, but use as little or as much of it as you like. ++ **Your system, your rules.** You know better. At least, Doom hopes so! It + won't *automatically* install system dependencies (and will force plugins not + to either). Rely on `doom doctor` to tell you what's missing. ++ **Nix/Guix was a great idea!** The Emacs ecosystem is temperamental. Things + break and they break often. Disaster recovery should be a priority! Doom's + package management should be declarative and your private config reproducible, + and comes with a means to roll back releases and updates (still a WIP). + +Check out [the FAQ][FAQ] for answers to common questions about the project. -## Features +# Features - Minimalistic good looks inspired by modern editors. -- A modular architecture that can be extended to your own configs. -- A standard library suited to simplifying your config. -- A declarative [package management system][doom:packages] (powered by - [straight.el][url:straight]) with a command line interface. Install packages - from anywhere, not just (M)ELPA. -- (Optional) Vim-emulation powered by [evil-mode][url:evil-mode], including - ports of popular vim plugins and functionality. - Curated and sane defaults for many packages, (major) OSes, and Emacs itself. +- A modular organizational structure for separating concerns in your config. +- A standard library designed to simplify your elisp bike shedding. +- A declarative [package management system][package-management] (powered by + [straight.el]) with a command line interface. Install packages from anywhere, + not just (M)ELPA, and pin them to any commit. +- Optional vim emulation powered by [evil-mode], including ports of popular vim + plugins like [vim-sneak], [vim-easymotion], [vim-unimpaired] and + [more][ported-vim-plugins]! +- Opt-in LSP integration for many languages, using [lsp-mode]. - Support for *many* programming languages. Includes syntax highlighting, linters/checker integration, inline code evaluation, code completion (where possible), REPLs, documentation lookups, snippets, and more! - Support for *many* tools, like docker, pass, ansible, terraform, and more. -- A Spacemacs-esque [keybinding scheme][doom:bindings], centered around leader - and localleader prefix keys (SPC and SPCm, by - default). -- A rule-based [popup management system][doom:popups] to control how temporary - or disposable buffers are displayed (and disposed of). -- Automatic indentation detection and [editorconfig][url:editorconfig] - integration. Let someone else argue about tabs vs **\_\***spaces**\*\_**. +- A Spacemacs-esque [keybinding scheme][bindings], centered around leader + and localleader prefix keys (SPC and SPCm for + evil users, C-c and C-c l for vanilla users). +- A rule-based [popup manager][popup-system] to control how temporary buffers + are displayed (and disposed of). +- Per-file indentation style detection and [editorconfig] integration. Let + someone else can argue about tabs vs **_spaces_**. - Project-management tools and framework-specific minor modes with their own snippets libraries. -- Project search (and replace) utilities, powered by [ripgrep][url:ripgrep]. +- Project search (and replace) utilities, powered by [ripgrep] and [ivy] or + [helm]. - Isolated and persistent workspaces (also substitutes for vim tabs). -- An envvar file generator that captures a snapshot of your shell environment - for Doom to load at startup. No more struggling to get Emacs to inherit your - `PATH`, among other things. +- Support for Chinese and Japanese input systems. +- Save a snapshot of your shell environment to a file for Emacs to load at + startup. No more struggling to get Emacs to inherit your `PATH`, among other + things. -# Getting Help -## Community +# Prerequisites ++ Git 2.23+ ++ Emacs 26.1+ (*27 is recommended*) with GNUTLS support ++ [ripgrep] 11.0+ ++ GNU `find` ++ *OPTIONAL:* [fd] 7.3.0+ (improves file indexing performance for some commands) + +Doom is comprised of [~150 optional modules][Modules], some of which may have +additional dependencies. [Visit their documentation][Modules] or run `bin/doom +doctor` to check for any that you may have missed. -We have [a Discord server][url:discord]! Hop on and say hi! -## Troubleshooting +# Install +``` sh +git clone --depth 1 https://github.com/hlissner/doom-emacs ~/.emacs.d +~/.emacs.d/bin/doom install +``` -Encountered a problem? Here are some things to try before shooting off that bug -report: +Then [read our Getting Started guide][getting-started] to be walked through +installing, configuring and maintaining Doom Emacs. -- Run `bin/doom sync`. This ensures Doom is properly set up and its autoloads - files are up-to-date. -- Folks who have byte-compiled their config (with `bin/doom compile`) should run - `bin/doom clean` to rule out stale bytecode. Never debug with a byte-compiled - config. It makes your job harder. -- Run `bin/doom doctor` to detect common issues in your development environment - and missing third party dependencies. -- Search [Doom's issue tracker][github:issues] in case your issue was already +It's a good idea to add `~/.emacs.d/bin` to your `PATH`! Other `bin/doom` +commands you should know about: + ++ `doom sync` to synchronize your private config with Doom. Installs new + packages, removes orphaned packages and regenerates caches. Run this whenever + you modify your private `init.el` or `packages.el`, or install/remove an Emacs + package through your OS package manager (e.g. mu4e or agda). ++ `doom upgrade` to update Doom to the latest release & all installed packages. ++ `doom doctor` to diagnose common issues with your system and config. ++ `doom env` to dump a snapshot of your shell environment to a file that Doom + will load at startup. This allows Emacs to inherit your `PATH`, among other + things. ++ `doom build` to recompile all installed packages (use this if you up/downgrade + Emacs). + + +# Roadmap +Doom is an active and ongoing project. To make that development more +transparent, its roadmap (and other concerns) are published across three github +project boards and a newsletter: + ++ [Development Roadmap](https://github.com/hlissner/doom-emacs/projects/3): + roughly outlines our goals between release milestones and their progress. ++ [Plugins under review](https://github.com/hlissner/doom-emacs/projects/2): + lists plugins we are watching and considering for inclusion, and what their + status for inclusion is. Please consult this list before requesting new + packages/features. ++ [Upstream bugs](https://github.com/hlissner/doom-emacs/projects/5): lists + issues that originate from elsewhere, and whether or not we have local + workarounds or temporary fixes for them. ++ ~~Doom's newsletter~~ (not finished) will contain changelogs in between + releases. + + +# Getting help +Emacs is no journey of a mere thousand miles. You _will_ run into problems and +mysterious errors. When you do, here are some places you can look for help: + ++ [Our documentation][documentation] covers many use cases. + + [The Configuration section][configuration] covers how to configure Doom and + its packages. + + [The Package Management section][package-management] covers how to install + and disable packages. + + [This section][bin/doom] explains the `bin/doom` script's most important + commands. + + [This section][common-mistakes] lists some common configuration mistakes new + users make, when migrating a config from another distro or their own. + + [This answer][change-theme] shows you how to add your own themes to your + private config. + + [This answer][change-font] shows you how to change the default font. + + Your issue may be documented in the [FAQ]. ++ With Emacs built-in help system documentation is a keystroke away: + + For functions: SPC h f or C-h f + + For variables: SPC h v or C-h v + + For a keybind: SPC h k or C-h k + + To search available keybinds: SPC h b b or C-h b b ++ Run `bin/doom doctor` to detect common issues with your development + environment and private config. ++ Check out the [FAQ], in case your question has already been answered. ++ Search [Doom's issue tracker](/issues) in case your issue was already reported. -- [Visit our FAQ][docs:faq] to see if your issue is listed. - -If all else fails, [file that bug report][github:new-issue]! **Please do not -ignore the issue template!** It's a great help if you can [include a backtrace -with errors][docs:backtrace]. - -## Contributing - -Doom (and my Emacs work in general) is a labor of love and incurable madness, -done on my spare time. If you'd like to support my work, there are many things -you can do to help. I welcome contributions! - -- I love pull requests and bug reports. Check out the [Contributing - Guidelines][docs:contributing] to find out how you can help out. -- I welcome Elisp pointers! Don't hesitate to [tell me my Elisp-fu - sucks][github:new-issue] (but please tell me why). -- Hop on [our Discord server][url:discord] and say hi! Help others out, hang out - or talk to me about Emacs, or gamedev, or programming, machine learning, - physics, pixel art, anime, gaming -- anything you like. Nourish this lonely - soul! -- If you'd like to support my work financially, consider buying me a drink - through [liberapay][url:liberapay] or [paypal][url:paypal]. Donations are a - great help. My work here contends with studies, ventures in indie gamedev, and - my freelance work. ++ Hop on [our Discord server][discord]; it's active and friendly! Keep an eye on + the #announcements channel, where I announce breaking updates and releases. -[docs:wiki]: docs/index.org -[docs:wiki-quickstart]: docs/getting_started.org -[docs:wiki-modules]: docs/index.org#Module%20List -[docs:wiki-customization]: docs/getting_started.org#Customize -[docs:contributing]: docs/contributing.org -[docs:faq]: docs/faq.org -[docs:backtrace]: https://github.com/hlissner/doom-emacs/blob/develop/docs/getting_started.org#how-to-extract-a-backtrace-from-an-error -[github:new-issue]: https://github.com/hlissner/doom-emacs/issues/new -[github:issues]: https://github.com/hlissner/doom-emacs/issues -[doom:bindings]: modules/config/default/+evil-bindings.el -[doom:packages]: core/autoload/packages.el -[doom:popups]: modules/ui/popup/README.org -[url:discord]: https://discord.gg/qvGgnVx -[url:liberapay]: https://liberapay.com/hlissner/donate -[url:paypal]: https://paypal.me/henriklissner/10 -[url:editorconfig]: http://editorconfig.org/ -[url:evil-mode]: https://github.com/emacs-evil/evil -[url:ripgrep]: https://github.com/BurntSushi/ripgrep -[url:straight]: https://github.com/raxod502/straight.el +# Contribute +[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) +[![Elisp styleguide](https://img.shields.io/badge/elisp-style%20guide-purple?style=flat-square)](https://github.com/bbatsov/emacs-lisp-style-guide) +[![Donate on liberapay](https://img.shields.io/badge/liberapay-donate-1.svg?style=flat-square&logo=liberapay&color=blue)][liberapay] +[![Donate on paypal](https://img.shields.io/badge/paypal-donate-1?style=flat-square&logo=paypal&color=blue)][paypal] + +Doom is a labor of love and incurable madness, but I'm only one guy. Doom +wouldn't be where it is today without your help. I welcome contributions of any +kind! + ++ I :heart: pull requests and bug reports (see the [Contributing + Guidelines][contribute])! ++ Don't hesitate to [tell me my Elisp-fu + sucks](https://github.com/hlissner/doom-emacs/issues/new), but please tell me + why. ++ Hop on [our Discord server][Discord] and say hi! Help others, hang out or talk + to me about Emacs, gamedev, programming, physics, pixel art, anime, gaming -- + anything you like. Nourish this lonely soul. ++ If you'd like to support my work financially, buy me a drink through + [liberapay] or [paypal]. My work contends with studies, adventures in indie + gamedev and freelance work. Donations help me allocate more time to my Emacs + and OSS capers. + +[![](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/images/0)](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/links/0) +[![](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/images/1)](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/links/1) +[![](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/images/2)](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/links/2) +[![](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/images/3)](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/links/3) +[![](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/images/4)](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/links/4) +[![](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/images/5)](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/links/5) +[![](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/images/6)](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/links/6) +[![](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/images/7)](https://sourcerer.io/fame/hlissner/hlissner/doom-emacs/links/7) + + +[contribute]: docs/contributing.org +[discord]: https://discord.gg/qvGgnVx +[documentation]: docs/index.org +[faq]: docs/faq.org +[getting-started]: docs/getting_started.org +[install]: docs/getting_started.org#install +[backtrace]: docs/getting_started.org#how-to-extract-a-backtrace-from-an-error +[configuration]: docs/getting_started.org#configuring-doom +[package-management]: docs/getting_started.org#package-management +[bin/doom]: docs/getting_started.org#the-bindoom-utility +[common-mistakes]: docs/getting_started.org#common-mistakes-when-configuring-doom-emacs +[change-theme]: docs/faq.org#how-do-i-change-the-theme +[change-font]: docs/faq.org#how-do-i-change-the-fonts +[modules]: docs/modules.org +[popup-system]: modules/ui/popup/README.org +[screenshots]: #screenshots + +[bindings]: modules/config/default/+evil-bindings.el +[editorconfig]: http://editorconfig.org/ +[evil-mode]: https://github.com/emacs-evil/evil +[fd]: https://github.com/sharkdp/fd +[gnu emacs]: https://www.gnu.org/software/emacs/ +[helm]: https://github.com/emacs-helm/helm +[ivy]: https://github.com/abo-abo/swiper +[lsp-mode]: https://github.com/emacs-lsp/lsp-mode +[nix]: https://nixos.org +[ported-vim-plugins]: modules/editor/evil/README.org#ported-vim-plugins +[ripgrep]: https://github.com/BurntSushi/ripgrep +[straight.el]: https://github.com/raxod502/straight.el +[vim-easymotion]: https://github.com/easymotion/vim-easymotion +[vim-lion]: https://github.com/tommcdo/vim-lion +[vim-sneak]: https://github.com/justinmk/vim-sneak +[vim-unimpaired]: https://github.com/tpope/vim-unimpaired + +[liberapay]: https://liberapay.com/hlissner/donate +[paypal]: https://paypal.me/henriklissner/10 diff --git a/core/autoload/config.el b/core/autoload/config.el index 11113482e..cacd0d32d 100644 --- a/core/autoload/config.el +++ b/core/autoload/config.el @@ -76,7 +76,7 @@ Runs `doom-reload-hook' afterwards." (interactive) (require 'core-cli) (when (and IS-WINDOWS (file-exists-p doom-env-file)) - (warn "Can't regenerate envvar file from within Emacs. Run 'doom env' from the console")) + (message "Can't regenerate envvar file from within Emacs. Run 'doom env' from the console")) ;; In case doom/reload is run before incrementally loaded packages are loaded, ;; which could cause odd load order issues. (mapc #'require (cdr doom-incremental-packages)) diff --git a/core/autoload/files.el b/core/autoload/files.el index 65d0a6639..b62925d43 100644 --- a/core/autoload/files.el +++ b/core/autoload/files.el @@ -203,52 +203,29 @@ single file or nested compound statement of `and' and `or' statements." ;; ;;; Helpers -(defun doom--forget-file (path) - "Ensure `recentf', `projectile' and `save-place' forget OLD-PATH." - (when (bound-and-true-p recentf-mode) - (recentf-remove-if-non-kept path)) - (when (and (bound-and-true-p projectile-mode) - (doom-project-p) - (projectile-file-cached-p path (doom-project-root))) - (projectile-purge-file-from-cache path)) - (when (bound-and-true-p save-place-mode) - (save-place-forget-unreadable-files))) - -(defun doom--update-file (path) - (when (featurep 'vc) - (vc-file-clearprops path) - (vc-resynch-buffer path nil t)) - (when (featurep 'magit) - (when-let (default-directory (magit-toplevel (file-name-directory path))) - (magit-refresh)))) - -(defun doom--copy-file (old-path new-path &optional force-p) - (let* ((new-path (expand-file-name new-path)) - (old-path (file-truename old-path)) - (new-path (apply #'expand-file-name - (if (or (directory-name-p new-path) - (file-directory-p new-path)) - (list (file-name-nondirectory old-path) new-path) - (list new-path)))) - (new-path-dir (file-name-directory new-path)) - (project-root (doom-project-root)) - (short-new-name (if (and project-root (file-in-directory-p new-path project-root)) - (file-relative-name new-path project-root) - (abbreviate-file-name new-path)))) - (unless (file-directory-p new-path-dir) - (make-directory new-path-dir t)) - (when (buffer-modified-p) - (save-buffer)) - (cond ((file-equal-p old-path new-path) - (throw 'status 'overwrite-self)) - ((and (file-exists-p new-path) - (not force-p) - (not (y-or-n-p (format "File already exists at %s, overwrite?" short-new-name)))) - (throw 'status 'aborted)) - ((file-exists-p old-path) - (copy-file old-path new-path t) - short-new-name) - (short-new-name)))) +(defun doom--update-files (&rest files) + "Ensure FILES are updated in `recentf', `magit' and `save-place'." + (let (toplevels) + (dolist (file files) + (when (featurep 'vc) + (vc-file-clearprops file) + (when-let (buffer (get-file-buffer file)) + (with-current-buffer buffer + (vc-refresh-state)))) + (when (featurep 'magit) + (when-let (default-directory (magit-toplevel (file-name-directory file))) + (cl-pushnew default-directory toplevels))) + (unless (file-readable-p file) + (when (bound-and-true-p recentf-mode) + (recentf-remove-if-non-kept file)) + (when (and (bound-and-true-p projectile-mode) + (doom-project-p) + (projectile-file-cached-p file (doom-project-root))) + (projectile-purge-file-from-cache file)))) + (dolist (default-directory toplevels) + (magit-refresh)) + (when (bound-and-true-p save-place-mode) + (save-place-forget-unreadable-files)))) ;; @@ -256,73 +233,67 @@ single file or nested compound statement of `and' and `or' statements." ;;;###autoload (defun doom/delete-this-file (&optional path force-p) - "Delete FILENAME (defaults to the file associated with current buffer) and -kills the buffer. If FORCE-P, force the deletion (don't ask for confirmation)." + "Delete PATH, kill its buffers and expunge it from vc/magit cache. + +If PATH is not specified, default to the current buffer's file. + +If FORCE-P, delete without confirmation." (interactive - (list (file-truename (buffer-file-name)) + (list (buffer-file-name (buffer-base-buffer)) current-prefix-arg)) - (let* ((fbase (file-name-sans-extension (file-name-nondirectory path))) - (buf (current-buffer))) - (cond ((not (file-exists-p path)) - (error "File doesn't exist: %s" path)) - ((not (or force-p (y-or-n-p (format "Really delete %s?" fbase)))) - (message "Aborted") - nil) - ((unwind-protect - (progn (delete-file path) t) - (let ((short-path (file-relative-name path (doom-project-root)))) - (if (file-exists-p path) - (error "Failed to delete %s" short-path) - ;; Ensures that windows displaying this buffer will be switched - ;; to real buffers (`doom-real-buffer-p') - (doom/kill-this-buffer-in-all-windows buf t) - (doom--forget-file path) - (doom--update-file path) - (message "Successfully deleted %s" short-path)))))))) + (let* ((path (or path (buffer-file-name (buffer-base-buffer)))) + (short-path (abbreviate-file-name path))) + (unless (and path (file-exists-p path)) + (user-error "Buffer is not visiting any file")) + (unless (file-exists-p path) + (error "File doesn't exist: %s" path)) + (unless (or force-p (y-or-n-p (format "Really delete %S?" short-path))) + (user-error "Aborted")) + (let ((buf (current-buffer))) + (unwind-protect + (progn (delete-file path) t) + (if (file-exists-p path) + (error "Failed to delete %S" short-path) + ;; Ensures that windows displaying this buffer will be switched to + ;; real buffers (`doom-real-buffer-p') + (doom/kill-this-buffer-in-all-windows buf t) + (doom--update-files path) + (message "Deleted %S" short-path)))))) ;;;###autoload (defun doom/copy-this-file (new-path &optional force-p) - "Copy current buffer's file to NEW-PATH. If FORCE-P, overwrite the destination -file if it exists, without confirmation." + "Copy current buffer's file to NEW-PATH. + +If FORCE-P, overwrite the destination file if it exists, without confirmation." (interactive (list (read-file-name "Copy file to: ") current-prefix-arg)) - (pcase (catch 'status - (when-let (dest (doom--copy-file (buffer-file-name) new-path force-p)) - (doom--update-file new-path) - (message "File successfully copied to %s" dest))) - (`overwrite-self (error "Cannot overwrite self")) - (`aborted (message "Aborted")) - (_ t))) + (unless (and buffer-file-name (file-exists-p buffer-file-name)) + (user-error "Buffer is not visiting any file")) + (let ((old-path (buffer-file-name (buffer-base-buffer))) + (new-path (expand-file-name new-path))) + (make-directory (file-name-directory new-path) 't) + (copy-file old-path new-path (or force-p 1)) + (doom--update-files old-path new-path) + (message "File copied to %S" (abbreviate-file-name new-path)))) ;;;###autoload (defun doom/move-this-file (new-path &optional force-p) - "Move current buffer's file to NEW-PATH. If FORCE-P, overwrite the destination -file if it exists, without confirmation." + "Move current buffer's file to NEW-PATH. + +If FORCE-P, overwrite the destination file if it exists, without confirmation." (interactive (list (read-file-name "Move file to: ") current-prefix-arg)) - (pcase (catch 'status - (let ((old-path (buffer-file-name)) - (new-path (expand-file-name new-path))) - (when-let (dest (doom--copy-file old-path new-path force-p)) - (doom--forget-file old-path) - (when (file-exists-p old-path) - (delete-file old-path)) - (mapc #'doom--update-file - (delq - nil (list (if (ignore-errors - (file-equal-p (doom-project-root old-path) - (doom-project-root new-path))) - nil - old-path) - new-path))) - (kill-current-buffer) - (find-file new-path) - (message "File successfully moved to %s" dest)))) - (`overwrite-self (error "Cannot overwrite self")) - (`aborted (message "Aborted")) - (_ t))) + (unless (and buffer-file-name (file-exists-p buffer-file-name)) + (user-error "Buffer is not visiting any file")) + (let ((old-path (buffer-file-name (buffer-base-buffer))) + (new-path (expand-file-name new-path))) + (make-directory (file-name-directory new-path) 't) + (rename-file old-path new-path (or force-p 1)) + (set-visited-file-name new-path t t) + (doom--update-files old-path new-path) + (message "File moved to %S" (abbreviate-file-name new-path)))) (defun doom--sudo-file-path (file) (let ((host (or (file-remote-p file 'host) "localhost"))) diff --git a/core/autoload/help.el b/core/autoload/help.el index 3c5954d7d..7cd190969 100644 --- a/core/autoload/help.el +++ b/core/autoload/help.el @@ -3,9 +3,6 @@ (defvar doom--help-major-mode-module-alist '((dockerfile-mode :tools docker) (agda2-mode :lang agda) - (haxor-mode :lang assembly) - (mips-mode :lang assembly) - (nasm-mode :lang assembly) (c-mode :lang cc) (c++-mode :lang cc) (objc++-mode :lang cc) diff --git a/core/cli/autoloads.el b/core/cli/autoloads.el index 4cd2e5fd0..cfc03ba57 100644 --- a/core/cli/autoloads.el +++ b/core/cli/autoloads.el @@ -90,7 +90,6 @@ one wants that.") (defun doom-cli--byte-compile-file (file) (condition-case-unless-debug e (let ((byte-compile-warnings (if doom-debug-mode byte-compile-warnings)) - (byte-compile-dynamic t) (byte-compile-dynamic-docstrings t)) (when (byte-compile-file file) (unless doom-interactive-mode diff --git a/core/cli/doctor.el b/core/cli/doctor.el index 5f790ccfa..22e690e2e 100644 --- a/core/cli/doctor.el +++ b/core/cli/doctor.el @@ -123,11 +123,8 @@ in." "both is rarely intentional; you should one or the other.")) ;; Check for fonts - (if (not (fboundp 'find-font)) - (progn - (warn! "Warning: unable to detect font") - (explain! "The `find-font' function is missing. This could indicate the incorrect " - "version of Emacs is being used!")) + (if (not (executable-find "fc-list")) + (warn! "Warning: unable to detect fonts because fontconfig isn't installed") ;; all-the-icons fonts (when (and (pcase system-type (`gnu/linux (concat (or (getenv "XDG_DATA_HOME") diff --git a/core/core-editor.el b/core/core-editor.el index a6f194cf9..1702c4d8e 100644 --- a/core/core-editor.el +++ b/core/core-editor.el @@ -174,6 +174,8 @@ possible." (push '("/LICENSE\\'" . text-mode) auto-mode-alist) (push '("\\.log\\'" . text-mode) auto-mode-alist) +(push '("rc\\'" . conf-mode) auto-mode-alist) +(push '("\\.\\(?:hex\\|nes\\)\\'" . hexl-mode) auto-mode-alist) ;; @@ -383,8 +385,6 @@ files, so we replace calls to `pp' with the much faster `prin1'." ;; Reduced from the default of 5000 for slightly faster analysis (setq dtrt-indent-max-lines 2000) - ;; Add support for more languages - (add-to-list 'dtrt-indent-hook-mapping-list '(typescript-mode javascript typescript-indent-level)) ;; always keep tab-width up-to-date (push '(t tab-width) dtrt-indent-hook-generic-mapping-list) diff --git a/core/core-keybinds.el b/core/core-keybinds.el index a79258aee..19b0517c4 100644 --- a/core/core-keybinds.el +++ b/core/core-keybinds.el @@ -77,7 +77,8 @@ all hooks after it are ignored.") :init ;; Convenience aliases (defalias 'define-key! #'general-def) - (defalias 'unmap! #'general-unbind)) + (defalias 'undefine-key! #'general-unbind)) + ;; HACK `map!' uses this instead of `define-leader-key!' because it consumes ;; 20-30% more startup time, so we reimplement it ourselves. @@ -108,8 +109,8 @@ all hooks after it are ignored.") (general--concat t doom-leader-key ,key) ,desc)))))))) (macroexp-progn - (cons `(after! which-key ,@(nreverse wkforms)) - (nreverse forms))))) + (append (and wkforms `((after! which-key ,@(nreverse wkforms)))) + (nreverse forms))))) (defmacro define-leader-key! (&rest args) "Define keys. diff --git a/core/core-modules.el b/core/core-modules.el index c0125b8dd..f3c22fb71 100644 --- a/core/core-modules.el +++ b/core/core-modules.el @@ -481,39 +481,6 @@ WARNINGS: (lambda () ,@body) 'append))) -(defmacro require! (category module &rest flags) - "Loads the CATEGORY MODULE module with FLAGS. - -CATEGORY is a keyword, MODULE is a symbol and FLAGS are symbols. - - (require! :lang php +lsp) - -This is for testing and internal use. This is not the correct way to enable a -module." - `(let ((doom-modules (or ,doom-modules (doom-modules))) - (module-path (doom-module-locate-path ,category ',module))) - (doom-module-set - ,category ',module - (let ((plist (doom-module-get ,category ',module))) - ,(when flags - `(plist-put plist :flags `,flags)) - (unless (plist-member plist :path) - (plist-put plist :path ,(doom-module-locate-path category module))) - plist)) - (if (directory-name-p module-path) - (condition-case-unless-debug ex - (let ((doom--current-module ',(cons category module)) - (doom--current-flags ',flags)) - (load! "init" module-path :noerror) - (load! "config" module-path :noerror)) - ('error - (lwarn 'doom-modules :error - "%s in '%s %s' -> %s" - (car ex) ,category ',module - (error-message-string ex)))) - (warn 'doom-modules :warning "Couldn't find module '%s %s'" - ,category ',module)))) - (defmacro featurep! (category &optional module flag) "Returns t if CATEGORY MODULE is enabled. @@ -538,18 +505,5 @@ CATEGORY and MODULE can be omitted When this macro is used from inside a module (memq category (doom-module-get (car module) (cdr module) :flags))))) t)) -;; DEPRECATED -(defmacro def-package! (&rest args) - "Do not use this macro. Use `use-package!' instead." - (warn "`def-package!' is deprecated and was renamed to `use-package!'") - `(use-package! ,@args)) -(make-obsolete 'def-package! 'use-package! "2.0.9") - -(defmacro def-package-hook! (&rest args) - "Do not use this macro. Use `use-package!' instead." - (warn "`def-package-hook!' is deprecated and was renamed to `use-package-hook!'") - `(use-package-hook! ,@args)) -(make-obsolete 'def-package-hook! 'use-package-hook! "2.0.9") - (provide 'core-modules) ;;; core-modules.el ends here diff --git a/core/core-packages.el b/core/core-packages.el index 388a5b16c..416e0f2d0 100644 --- a/core/core-packages.el +++ b/core/core-packages.el @@ -94,7 +94,7 @@ missing) and shouldn't be deleted.") ;;; Straight (setq straight-base-dir doom-local-dir - straight-repository-branch "develop" + straight-repository-branch "master" straight-cache-autoloads nil ; we already do this, and better. ;; Doom doesn't encourage you to modify packages in place. Disabling this ;; makes 'doom sync' instant (once everything set up), which is much nicer diff --git a/core/core-projects.el b/core/core-projects.el index 8b65e1ee9..ebb8d803e 100644 --- a/core/core-projects.el +++ b/core/core-projects.el @@ -15,9 +15,6 @@ Emacs.") "fd") "name of `fd-find' executable binary") -(defvar doom-projectile-cache-timer-file (concat doom-cache-dir "projectile.timers") - "Where to save project file cache timers.") - ;; ;;; Packages @@ -43,6 +40,16 @@ Emacs.") :config (projectile-mode +1) + ;; REVIEW Resolve the project root once, when the file/buffer is opened. This + ;; speeds up projectile's project root resolution by leaps, but does + ;; put you at risk of having a stale project root. + (setq-hook! '(after-change-major-mode-hook + ;; In case the user saves the file to a new location + after-save-hook + ;; ...or makes external changes then returns to Emacs + focus-in-hook) + projectile-project-root (if default-directory (doom-project-root))) + ;; Projectile runs four functions to determine the root (in this order): ;; ;; + `projectile-root-local' -> checks the `projectile-project-root' variable diff --git a/core/core-ui.el b/core/core-ui.el index 71f75c035..6ff9e85ba 100644 --- a/core/core-ui.el +++ b/core/core-ui.el @@ -138,10 +138,11 @@ size.") e.g. If you indent with spaces by default, tabs will be highlighted. If you indent with tabs, spaces at BOL are highlighted. -Does nothing if `whitespace-mode' is already active or the current buffer is -read-only or not file-visiting." +Does nothing if `whitespace-mode' or 'global-whitespace-mode' is already +active or if the current buffer is read-only or not file-visiting." (unless (or (eq major-mode 'fundamental-mode) buffer-read-only + (bound-and-true-p global-whitespace-mode) (null buffer-file-name)) (require 'whitespace) (set (make-local-variable 'whitespace-style) @@ -277,9 +278,6 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original (setq indicate-buffer-boundaries nil indicate-empty-lines nil) -;; remove continuation arrow on right fringe -(delq! 'continuation fringe-indicator-alist 'assq) - ;; ;;; Windows/frames @@ -421,7 +419,7 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original (use-package! hl-line ;; Highlights the current line - :hook ((prog-mode text-mode conf-mode) . hl-line-mode) + :hook ((prog-mode text-mode conf-mode special-mode) . hl-line-mode) :config ;; Not having to render the hl-line overlay in multiple buffers offers a tiny ;; performance boost. I also don't need to see it in other buffers. @@ -597,20 +595,25 @@ behavior). Do not set this directly, this is let-bound in `doom-init-theme-h'.") (let ((doom--prefer-theme-elc t)) ; DEPRECATED in Emacs 27 (load-theme doom-theme t))))) -(defadvice! doom--run-load-theme-hooks-a (theme &optional _no-confirm no-enable) - "Set up `doom-load-theme-hook' to run after `load-theme' is called." - :after-while #'load-theme - (unless no-enable - (setq doom-theme theme - doom-init-theme-p t) - (run-hooks 'doom-load-theme-hook))) +(defadvice! doom--load-theme-a (orig-fn theme &optional no-confirm no-enable) + "Run `doom-load-theme-hook' on `load-theme' and fix its issues. -(defadvice! doom--disable-enabled-themes-a (theme &optional _no-confirm no-enable) - "Disable previously enabled themes before loading a new one. -Otherwise, themes can conflict with each other." - :after-while #'load-theme - (unless no-enable - (mapc #'disable-theme (remq theme custom-enabled-themes)))) +1. Disable previously enabled themes. +2. Don't let face-remapping screw up loading the new theme + (*cough*`mixed-pitch-mode'). +3. Record the current theme in `doom-theme'." + :around #'load-theme + ;; HACK Run `load-theme' from an estranged buffer, where we can be assured + ;; that buffer-local face remaps (by `mixed-pitch-mode', for instance) + ;; won't interfere with changing themes. + (with-temp-buffer + (when-let (result (funcall orig-fn theme no-confirm no-enable)) + (unless no-enable + (setq doom-theme theme + doom-init-theme-p t) + (mapc #'disable-theme (remq theme custom-enabled-themes)) + (run-hooks 'doom-load-theme-hook)) + result))) (unless EMACS27+ ;; DEPRECATED Not needed in Emacs 27 diff --git a/core/core.el b/core/core.el index 9a9b5d0db..7d0596ba7 100644 --- a/core/core.el +++ b/core/core.el @@ -8,6 +8,7 @@ "Current version of Doom Emacs.") (defconst EMACS27+ (> emacs-major-version 26)) +(defconst EMACS28+ (> emacs-major-version 27)) (defconst IS-MAC (eq system-type 'darwin)) (defconst IS-LINUX (eq system-type 'gnu/linux)) (defconst IS-WINDOWS (memq system-type '(cygwin windows-nt ms-dos))) @@ -196,11 +197,12 @@ users).") (setq gnutls-verify-error (not (getenv "INSECURE")) gnutls-algorithm-priority (when (boundp 'libgnutls-version) - (concat "SECURE128:+SECURE192:-VERS-ALL:+VERS-TLS1.2" + (concat "SECURE128:+SECURE192:-VERS-ALL" (if (and (not IS-WINDOWS) (not (version< emacs-version "26.3")) (>= libgnutls-version 30605)) - ":+VERS-TLS1.3"))) + ":+VERS-TLS1.3") + ":+VERS-TLS1.2")) ;; `gnutls-min-prime-bits' is set based on recommendations from ;; https://www.keylength.com/en/4/ gnutls-min-prime-bits 3072 @@ -272,6 +274,11 @@ users).") ;; quickly self-correct. (setq fast-but-imprecise-scrolling t) +;; Font locking is the source of much slowness in Emacs. jit-lock-mode tries to +;; defer fontification until the user is idle. This should help... in theory. +(setq jit-lock-defer-time 0 ; only defer while processing input + jit-lock-stealth-time 2) ; fontify the rest of the buffer after a delay + ;; Resizing the Emacs frame can be a terribly expensive part of changing the ;; font. By inhibiting this, we halve startup times, particularly when we use ;; fonts that are larger than the system default (which would resize the frame). diff --git a/docs/getting_started.org b/docs/getting_started.org index 5745cbd2d..5e04916a9 100644 --- a/docs/getting_started.org +++ b/docs/getting_started.org @@ -910,7 +910,7 @@ also be helpful for debugging. + define-key + global-set-key + map! -+ unmap! ++ undefine-key! + define-key! ** Writing your own modules diff --git a/docs/modules.org b/docs/modules.org index 276f7ebb4..cd5b7e282 100644 --- a/docs/modules.org +++ b/docs/modules.org @@ -92,7 +92,6 @@ Modules that reconfigure or augment packages or features built into Emacs. Modules that bring support for a language or group of languages to Emacs. + [[file:../modules/lang/agda/README.org][agda]] - TODO -+ assembly - TODO + [[file:../modules/lang/cc/README.org][cc]] =+lsp= - TODO + [[file:../modules/lang/clojure/README.org][clojure]] =+lsp= - TODO + common-lisp - TODO @@ -112,11 +111,12 @@ Modules that bring support for a language or group of languages to Emacs. + [[file:../modules/lang/haskell/README.org][haskell]] =+dante +ghcide +lsp= - TODO + hy - TODO + [[file:../modules/lang/idris/README.org][idris]] - TODO ++ [[file:../modules/lang/json/README.org][json]] =+lsp= - TODO + java =+meghanada +lsp= - TODO + [[file:../modules/lang/javascript/README.org][javascript]] =+lsp= - JavaScript, TypeScript, and CoffeeScript support + julia =+lsp= - TODO + kotlin =+lsp+= - TODO -+ [[file:../modules/lang/latex/README.org][latex]] =+latexmk +cdlatex +fold= - TODO ++ [[file:../modules/lang/latex/README.org][latex]] =+latexmk +cdlatex +fold +lsp= - TODO + lean - TODO + [[file:../modules/lang/ledger/README.org][ledger]] - TODO + lua =+moonscript= - TODO @@ -129,7 +129,7 @@ Modules that bring support for a language or group of languages to Emacs. + [[file:../modules/lang/php/README.org][php]] =+lsp= - TODO + plantuml - TODO + purescript - TODO -+ [[file:../modules/lang/python/README.org][python]] =+lsp +pyenv +conda= - TODO ++ [[file:../modules/lang/python/README.org][python]] =+lsp +pyenv +conda +poetry= - TODO + qt - TODO + racket - TODO + [[file:../modules/lang/rest/README.org][rest]] - TODO @@ -143,6 +143,7 @@ Modules that bring support for a language or group of languages to Emacs. + swift =+lsp= - TODO + terra - TODO + web =+lsp= - HTML and CSS (SCSS/SASS/LESS/Stylus) support. ++ [[file:../modules/lang/yaml/README.org][yaml]] =+lsp= - TODO * :term Modules that offer terminal emulation. @@ -156,7 +157,7 @@ Modules that offer terminal emulation. Small modules that give Emacs access to external tools & services. + ansible - TODO -+ debugger - A (nigh-)universal debugger in Emacs ++ debugger =+lsp= - A (nigh-)universal debugger in Emacs + [[file:../modules/tools/direnv/README.org][direnv]] - TODO + [[file:../modules/tools/docker/README.org][docker]] =+lsp= - TODO + [[file:../modules/tools/editorconfig/README.org][editorconfig]] - TODO @@ -167,7 +168,7 @@ Small modules that give Emacs access to external tools & services. backend + [[file:../modules/tools/lsp/README.org][lsp]] =+peek= - TODO + macos - TODO -+ magit - TODO ++ [[file:../modules/tools/magit/README.org][magit]] =+forge= - TODO + make - TODO + pass - TODO + pdf - TODO diff --git a/init.example.el b/init.example.el index 2ffe28979..370dd77d4 100644 --- a/init.example.el +++ b/init.example.el @@ -1,11 +1,11 @@ ;;; init.el -*- lexical-binding: t; -*- -;; This file controls what Doom modules are enabled and what order they load in. -;; Remember to run 'doom sync' after modifying it! +;; This file controls what Doom modules are enabled and what order they load +;; in. Remember to run 'doom sync' after modifying it! ;; NOTE Press 'SPC h d h' (or 'C-h d h' for non-vim users) to access Doom's -;; documentation. There you'll find information about all of Doom's modules -;; and what flags they support. +;; documentation. There you'll find information about all of Doom's +;; modules and what flags they support. ;; NOTE Move your cursor over a module's name (or its flags) and press 'K' (or ;; 'C-c g k' for non-vim users) to view its documentation. This works on @@ -34,7 +34,7 @@ ;;hydra ;;indent-guides ; highlighted indent columns modeline ; snazzy, Atom-inspired modeline, plus API - nav-flash ; blink the current line after jumping + ;;nav-flash ; blink cursor line after big motions ;;neotree ; a project drawer, like NERDTree for vim ophints ; highlight the region an operation acts on (popup +defaults) ; tame sudden yet inevitable temporary windows @@ -44,7 +44,7 @@ ;;unicode ; extended unicode support for various languages vc-gutter ; vcs diff in the fringe vi-tilde-fringe ; fringe tildes to mark beyond EOB - window-select ; visually switch windows + ;;window-select ; visually switch windows workspaces ; tab emulation, persistence & separate workspaces ;;zen ; distraction-free coding or writing @@ -104,14 +104,13 @@ :lang ;;agda ; types of types of types of types... - ;;assembly ; assembly for fun or debugging ;;cc ; C/C++/Obj-C madness ;;clojure ; java with a lisp ;;common-lisp ; if you've seen one lisp, you've seen them all ;;coq ; proofs-as-programs ;;crystal ; ruby at the speed of c ;;csharp ; unity, .NET, and mono shenanigans - data ; config/data formats + ;;data ; config/data formats ;;(dart +flutter) ; paint ui and not much else ;;elixir ; erlang done right ;;elm ; care for a cup of TEA? @@ -121,10 +120,11 @@ ;;faust ; dsp, but you get to keep your soul ;;fsharp ; ML stands for Microsoft's Language ;;fstar ; (dependent) types and (monadic) effects and Z3 - ;;go ; the hipster dialect + ;;(go +lsp) ; the hipster dialect ;;(haskell +dante) ; a language that's lazier than I am ;;hy ; readability of scheme w/ speed of python ;;idris ; + ;;json ; At least it ain't XML ;;(java +meghanada) ; the poster child for carpal tunnel syndrome ;;javascript ; all(hope(abandon(ye(who(enter(here)))))) ;;julia ; a better, faster MATLAB @@ -158,6 +158,7 @@ ;;swift ; who asked for emoji variables? ;;terra ; Earth and Moon in alignment for performance. ;;web ; the tubes + ;;yaml ; JSON, but readable :email ;;(mu4e +gmail) diff --git a/modules/checkers/syntax/config.el b/modules/checkers/syntax/config.el index 6d82bb0f5..f6c52c0a1 100644 --- a/modules/checkers/syntax/config.el +++ b/modules/checkers/syntax/config.el @@ -12,7 +12,12 @@ ;; Check only when saving or opening files. Newline & idle checks are a mote ;; excessive and can catch code in an incomplete state, producing false ;; positives, so we removed them. - (setq flycheck-check-syntax-automatically '(save mode-enabled)) + (setq flycheck-check-syntax-automatically '(save mode-enabled idle-buffer-switch)) + + ;; For the above functionality, check syntax in a buffer that you switched to + ;; only briefly. This allows "refreshing" the syntax check state for several + ;; buffers quickly after e.g. changing a config file. + (setq flycheck-buffer-switch-check-intermediate-buffers t) ;; Display errors a little quicker (default is 0.9s) (setq flycheck-display-errors-delay 0.25) diff --git a/modules/completion/helm/config.el b/modules/completion/helm/config.el index c27d30113..66e8d7b9a 100644 --- a/modules/completion/helm/config.el +++ b/modules/completion/helm/config.el @@ -101,14 +101,7 @@ be negative.") :config (set-popup-rule! "^\\*helm" :vslot -100 :size 0.22 :ttl nil) - ;; HACK Doom doesn't support these commands, which invite the user to install - ;; the package via ELPA. Force them to use +helm/* instead, because they work - ;; out of the box. - (advice-add #'helm-projectile-rg :override #'+helm/project-search) - (advice-add #'helm-projectile-ag :override #'+helm/project-search) - (advice-add #'helm-projectile-grep :override #'+helm/project-search) - - ;; Hide the modeline + ;; Hide the modeline in helm windows as it serves little purpose. (defun +helm--hide-mode-line (&rest _) (with-current-buffer (helm-buffer-get) (unless helm-mode-line-string diff --git a/modules/completion/ivy/README.org b/modules/completion/ivy/README.org index b21b92c61..ea1599519 100644 --- a/modules/completion/ivy/README.org +++ b/modules/completion/ivy/README.org @@ -136,7 +136,7 @@ These keybindings are available while a search is active: | =C-c C-o= | Open a buffer with your search results | | =C-c C-e= | Open a writable buffer of your search results | | =C-SPC= | Preview the current candidate | -| =M-RET= | Open the selected candidate in other-window | +| =C-RET= | Open the selected candidate in other-window | Changes to the resulting wgrep buffer (opened by =C-c C-e=) can be committed with =C-c C-c= and aborted with =C-c C-k= (alternatively =ZZ= and =ZQ=, for evil diff --git a/modules/completion/ivy/config.el b/modules/completion/ivy/config.el index 8688311b6..73276413f 100644 --- a/modules/completion/ivy/config.el +++ b/modules/completion/ivy/config.el @@ -262,7 +262,10 @@ evil-ex-specific constructs, so we disable it solely in evil-ex." (cond ((executable-find doom-projectile-fd-binary) (cons doom-projectile-fd-binary (list "-t" "f" "-E" ".git"))) ((executable-find "rg") - (split-string (format counsel-rg-base-command "--files --no-messages") " " t)) + (append (list "rg" "--files" "--color=never" "--hidden" "--no-messages") + (cl-loop for dir in projectile-globally-ignored-directories + collect "--glob" and collect (concat "!" dir)) + (if IS-WINDOWS (list "--path-separator" "/")))) ((cons find-program args))) (unless (listp args) (user-error "`counsel-file-jump-args' is a list now, please customize accordingly.")) @@ -328,7 +331,9 @@ evil-ex-specific constructs, so we disable it solely in evil-ex." ;; posframe. (dolist (fn '(swiper counsel-rg counsel-grep counsel-git-grep)) (setf (alist-get fn ivy-posframe-display-functions-alist) - #'ivy-display-function-fallback))) + #'ivy-display-function-fallback)) + + (add-hook 'doom-reload-hook #'posframe-delete-all)) (use-package! flx diff --git a/modules/config/default/+emacs-bindings.el b/modules/config/default/+emacs-bindings.el index 7cfdb43dc..fc8b67fe2 100644 --- a/modules/config/default/+emacs-bindings.el +++ b/modules/config/default/+emacs-bindings.el @@ -129,6 +129,12 @@ (cond ((featurep! :completion ivy) #'ivy-bibtex) ((featurep! :completion helm) #'helm-bibtex))) + :desc "Toggle org-clock" "c" #'+org/toggle-clock + :desc "Cancel org-clock" "C" #'org-clock-cancel + :desc "Open deft" "d" #'deft + (:when (featurep! :lang org +noter) + :desc "Org noter" "e" #'org-noter) + :desc "Find file in notes" "f" #'+default/find-in-notes :desc "Browse notes" "F" #'+default/browse-notes :desc "Org store link" "l" #'org-store-link @@ -151,14 +157,14 @@ :desc "Switch to buffer" "b" #'org-roam-switch-to-buffer :desc "Org Roam Capture" "c" #'org-roam-capture :desc "Find file" "f" #'org-roam-find-file - :desc "Show graph" "g" #'org-roam-graph-show + :desc "Show graph" "g" #'org-roam-graph :desc "Insert" "i" #'org-roam-insert :desc "Org Roam" "r" #'org-roam (:prefix ("d" . "by date") - :desc "Arbitrary date" "d" #'org-roam-date - :desc "Today" "t" #'org-roam-today - :desc "Tomorrow" "m" #'org-roam-tomorrow - :desc "Yesterday" "y" #'org-roam-yesterday)))) + :desc "Arbitrary date" "d" #'org-roam-dailies-date + :desc "Today" "t" #'org-roam-dailies-today + :desc "Tomorrow" "m" #'org-roam-dailies-tomorrow + :desc "Yesterday" "y" #'org-roam-dailies-yesterday)))) ;;; o --- open "o" nil ; we need to unbind it first as Org claims this prefix @@ -535,14 +541,4 @@ ;;; treemacs (:when (featurep! :ui treemacs) "" #'+treemacs/toggle - "" #'+treemacs/find-file) - - ;;; yasnippet - (:after yasnippet - :map yas-keymap ; keymap while editing an inserted snippet - "C-e" #'+snippets/goto-end-of-field - "C-a" #'+snippets/goto-start-of-field - "" #'yas-prev-field - "" #'+snippets/delete-to-start-of-field - [backspace] #'+snippets/delete-backward-char - [delete] #'+snippets/delete-forward-char-or-field)) + "" #'+treemacs/find-file)) diff --git a/modules/config/default/+evil-bindings.el b/modules/config/default/+evil-bindings.el index e0fe4744b..52df2ec1b 100644 --- a/modules/config/default/+evil-bindings.el +++ b/modules/config/default/+evil-bindings.el @@ -4,9 +4,12 @@ ;; NOTE SPC u replaces C-u as the universal argument. ;; Minibuffer - (define-key! evil-ex-completion-map + (define-key! :keymaps '(evil-ex-completion-map evil-ex-search-keymap) "C-a" #'evil-beginning-of-line - "C-b" #'evil-backward-char) + "C-b" #'evil-backward-char + "C-f" #'evil-forward-char + "C-j" #'next-complete-history-element + "C-k" #'previous-complete-history-element) (define-key! :keymaps +default-minibuffer-maps [escape] #'abort-recursive-edit @@ -15,16 +18,17 @@ "C-u" #'evil-delete-back-to-indentation "C-v" #'yank "C-w" #'doom/delete-backward-word - "C-z" (λ! (ignore-errors (call-interactively #'undo))) - ;; Scrolling lines - "C-j" #'next-line - "C-k" #'previous-line - "C-S-j" #'scroll-up-command - "C-S-k" #'scroll-down-command) + "C-z" (λ! (ignore-errors (call-interactively #'undo)))) - (define-key! read-expression-map - "C-j" #'next-line-or-history-element - "C-k" #'previous-line-or-history-element)) + (when (featurep! :editor evil +everywhere) + (define-key! :keymaps +default-minibuffer-maps + "C-j" #'next-line + "C-k" #'previous-line + "C-S-j" #'scroll-up-command + "C-S-k" #'scroll-down-command) + (define-key! read-expression-map + "C-j" #'next-line-or-history-element + "C-k" #'previous-line-or-history-element))) ;; @@ -186,9 +190,9 @@ ;;; :ui (map! (:when (featurep! :ui popup) - :n "C-`" #'+popup/toggle - :n "C-~" #'+popup/raise - :g "C-x p" #'+popup/other) + "C-`" #'+popup/toggle + "C-~" #'+popup/raise + "C-x p" #'+popup/other) (:when (featurep! :ui workspaces) :n "C-t" #'+workspace/new @@ -464,11 +468,15 @@ :desc "Toggle org-clock" "c" #'+org/toggle-clock :desc "Cancel org-clock" "C" #'org-clock-cancel :desc "Open deft" "d" #'deft + (:when (featurep! :lang org +noter) + :desc "Org noter" "e" #'org-noter) + :desc "Find file in notes" "f" #'+default/find-in-notes :desc "Browse notes" "F" #'+default/browse-notes :desc "Org store link" "l" #'org-store-link :desc "Tags search" "m" #'org-tags-view :desc "Org capture" "n" #'org-capture + :desc "Goto capture" "N" #'org-capture-goto-target :desc "Active org-clock" "o" #'org-clock-goto :desc "Todo list" "t" #'org-todo-list :desc "Search notes" "s" #'+default/org-notes-search @@ -482,14 +490,14 @@ :desc "Switch to buffer" "b" #'org-roam-switch-to-buffer :desc "Org Roam Capture" "c" #'org-roam-capture :desc "Find file" "f" #'org-roam-find-file - :desc "Show graph" "g" #'org-roam-graph-show + :desc "Show graph" "g" #'org-roam-graph :desc "Insert" "i" #'org-roam-insert :desc "Org Roam" "r" #'org-roam (:prefix ("d" . "by date") - :desc "Arbitrary date" "d" #'org-roam-date - :desc "Today" "t" #'org-roam-today - :desc "Tomorrow" "m" #'org-roam-tomorrow - :desc "Yesterday" "y" #'org-roam-yesterday))) + :desc "Arbitrary date" "d" #'org-roam-dailies-date + :desc "Today" "t" #'org-roam-dailies-today + :desc "Tomorrow" "m" #'org-roam-dailies-tomorrow + :desc "Yesterday" "y" #'org-roam-dailies-yesterday))) (:when (featurep! :lang org +journal) (:prefix ("j" . "journal") diff --git a/modules/config/default/autoload/files.el b/modules/config/default/autoload/files.el index 3c90f6d23..e49e8255f 100644 --- a/modules/config/default/autoload/files.el +++ b/modules/config/default/autoload/files.el @@ -27,11 +27,15 @@ ;;;###autoload (defun +default/browse-notes () "Browse files from `org-directory'." - (interactive) (doom-project-browse org-directory)) + (interactive) + (require 'org) + (doom-project-browse org-directory)) ;;;###autoload (defun +default/find-in-notes () "Find a file under `org-directory', recursively." - (interactive) (doom-project-find-file org-directory)) + (interactive) + (require 'org) + (doom-project-find-file org-directory)) ;;;###autoload (defun +default/find-file-under-here () diff --git a/modules/config/default/config.el b/modules/config/default/config.el index 490ec2a14..8ed0cf535 100644 --- a/modules/config/default/config.el +++ b/modules/config/default/config.el @@ -31,7 +31,10 @@ (after! epa ;; With GPG 2.1+, this forces gpg-agent to use the Emacs minibuffer to prompt ;; for the key passphrase. - (setq epa-pinentry-mode 'loopback) + (set (if EMACS27+ + 'epg-pinentry-mode + 'epa-pinentry-mode) ; DEPRECATED `epa-pinentry-mode' + 'loopback) ;; Default to the first secret key available in your keyring. (setq-default epa-file-encrypt-to diff --git a/modules/editor/evil/+commands.el b/modules/editor/evil/+commands.el index 1c9de22a0..3bf6cf5e5 100644 --- a/modules/editor/evil/+commands.el +++ b/modules/editor/evil/+commands.el @@ -47,9 +47,9 @@ (evil-ex-define-cmd "k[ill]m" #'+evil:kill-matching-buffers) (evil-ex-define-cmd "k[ill]o" #'doom/kill-other-buffers) (evil-ex-define-cmd "k[ill]b" #'doom/kill-buried-buffers) -(evil-ex-define-cmd "l[ast]" #'doom/popup-restore) +(evil-ex-define-cmd "l[ast]" #'+popup/restore) (evil-ex-define-cmd "messages" #'view-echo-area-messages) -(evil-ex-define-cmd "pop[up]" #'doom/popup-this-buffer) +(evil-ex-define-cmd "pop[up]" #'+popup/buffer) ;;; Project navigation (evil-ex-define-cmd "a" #'projectile-find-other-file) @@ -98,4 +98,8 @@ (evil-ex-define-cmd "tabsave" #'+workspace:save) ;;; Org-mode -(evil-ex-define-cmd "cap" #'org-capture) +(evil-ex-define-cmd "cap[ture]" #'org-capture) + +;;; ibuffer +(when (featurep! :emacs ibuffer) + (evil-ex-define-cmd "buffers" #'ibuffer)) diff --git a/modules/editor/evil/README.org b/modules/editor/evil/README.org index 46053eaad..bbb2bd803 100644 --- a/modules/editor/evil/README.org +++ b/modules/editor/evil/README.org @@ -71,6 +71,7 @@ The following vim plugins have been ported to evil: | vim-lion | evil-lion | omap =gl= / =gL= | | vim-seek or vim-sneak | evil-snipe | mmap =s= / =S=, omap =z= / =Z= & =x= / =X= | | vim-surround | evil-embrace and evil-surround | vmap =S=, omap =ys= | +| vim-unimpaired | (provided by Doom) | [[https://github.com/hlissner/doom-emacs/blob/develop/modules/editor/evil/config.el#L413-L460][see the list]] | This module has also ported vim-unimpaired keybinds to Emacs. diff --git a/modules/editor/evil/autoload/advice.el b/modules/editor/evil/autoload/advice.el index 834f40315..e54a1ab90 100644 --- a/modules/editor/evil/autoload/advice.el +++ b/modules/editor/evil/autoload/advice.el @@ -7,7 +7,7 @@ (call-interactively #'doom/escape))) ;;;###autoload -(defun +evil-resolve-vim-path-a (file-name) +(defun +evil-replace-filename-modifiers-a (file-name) "Take a path and resolve any vim-like filename modifiers in it. This adds support for most vim file modifiers, as well as: @@ -15,66 +15,65 @@ support for most vim file modifiers, as well as: See http://vimdoc.sourceforge.net/htmldoc/cmdline.html#filename-modifiers for more information on modifiers." - (let (case-fold-search) + (let ((origin-buffer (current-buffer)) + case-fold-search) (with-temp-buffer - (save-excursion (insert file-name)) - (while (re-search-forward "\\(^\\|[^\\\\]\\)\\(\\([%#]\\)\\(:\\([PphtreS~.]\\|g?s\\)\\)*\\)" nil t) - (catch 'continue - (unless buffer-file-name - (replace-match (match-string 1) t t nil 2) - (throw 'continue t)) - (let ((beg (match-beginning 2)) - (end (match-end 3)) - (path (pcase (match-string 3) - ("%" (file-relative-name buffer-file-name)) - ("#" (and (other-buffer) - (buffer-file-name (other-buffer))))))) - (save-match-data - (goto-char beg) - (while (re-search-forward ":\\([PphtreS~.]\\|g?s\\)" (+ (point) 3) t) - (let* ((modifier (match-string 1)) - (global (string-prefix-p "gs" modifier))) - (when global - (setq modifier (substring modifier 1))) - (setq end (match-end 1) - path - (or (when path - (pcase (substring modifier 0 1) - ("p" (expand-file-name path)) - ("~" (concat "~/" (file-relative-name path "~"))) - ("." (file-relative-name path default-directory)) - ("t" (file-name-nondirectory (directory-file-name path))) - ("r" (file-name-sans-extension path)) - ("e" (file-name-extension path)) - ("S" (shell-quote-argument path)) - ("h" - (let ((parent (file-name-directory (expand-file-name path)))) - (unless (file-equal-p path parent) - (if (file-name-absolute-p path) - (directory-file-name parent) - (file-relative-name parent))))) - ("s" - (if (featurep 'evil) - (when-let (args (evil-delimited-arguments (substring modifier 1) 2)) - (let ((pattern (evil-transform-vim-style-regexp (car args))) - (replace (cadr args))) - (replace-regexp-in-string - (if global pattern (concat "\\(" pattern "\\).*\\'")) - (evil-transform-vim-style-regexp replace) path t t - (unless global 1)))) - path)) - ("P" - (let ((project-root (doom-project-root (file-name-directory (expand-file-name path))))) - (unless project-root - (user-error "Not in a project")) - (abbreviate-file-name project-root))))) - "")) - ;; strip trailing slash, if applicable - (or (string-empty-p path) - (not (equal (substring path -1) "/")) - (setq path (substring path 0 -1)))))) - (replace-match path t t nil 2)))) - (replace-regexp-in-string "\\\\\\([#%]\\)" "\\1" (buffer-string) t)))) + (let ((buffer-file-name (buffer-file-name origin-buffer))) + (save-excursion (insert file-name)) + (while (re-search-forward "\\(^\\|[^\\\\]\\)\\(\\([%#]\\)\\(:\\([PphtreS~.]\\|g?s\\)\\)*\\)" nil t) + (if (null buffer-file-name) + (replace-match (match-string 1) t t nil 2) + (let ((beg (match-beginning 2)) + (end (match-end 3)) + (path (pcase (match-string 3) + ("%" (file-relative-name buffer-file-name default-directory)) + ("#" (and (other-buffer origin-buffer) + (buffer-file-name (other-buffer origin-buffer))))))) + (save-match-data + (goto-char beg) + (while (re-search-forward ":\\([PphtreS~.]\\|g?s\\)" (+ (point) 3) t) + (let* ((modifier (match-string 1)) + (global (string-prefix-p "gs" modifier))) + (when global + (setq modifier (substring modifier 1))) + (setq end (match-end 1) + path + (pcase (and path (substring modifier 0 1)) + (`nil "") + ("p" (expand-file-name path)) + ("~" (concat "~/" (file-relative-name path "~"))) + ("." (file-relative-name path)) + ("t" (file-name-nondirectory (directory-file-name path))) + ("r" (file-name-sans-extension path)) + ("e" (file-name-extension path)) + ("S" (shell-quote-argument path)) + ("h" + (let ((parent (file-name-directory (expand-file-name path)))) + (unless (file-equal-p path parent) + (if (file-name-absolute-p path) + (directory-file-name parent) + (file-relative-name parent))))) + ("s" + (if (featurep 'evil) + (when-let (args (evil-delimited-arguments (substring modifier 1) 2)) + (let ((pattern (evil-transform-vim-style-regexp (car args))) + (replace (cadr args))) + (replace-regexp-in-string + (if global pattern (concat "\\(" pattern "\\).*\\'")) + (evil-transform-vim-style-regexp replace) path t t + (unless global 1)))) + path)) + ("P" + (let ((project-root (doom-project-root (file-name-directory (expand-file-name path))))) + (unless project-root + (user-error "Not in a project")) + (abbreviate-file-name project-root))))) + ;; strip trailing slash, if applicable + (or (string-empty-p path) + (not (equal (substring path -1) "/")) + (setq path (substring path 0 -1)))))) + (replace-match path t t nil 2)))) + (replace-regexp-in-string "\\\\\\([#%]\\)" "\\1" (buffer-string) t))))) (defun +evil--insert-newline (&optional above _noextranewline) (let ((pos (save-excursion (beginning-of-line-text) (point))) diff --git a/modules/editor/evil/autoload/ex.el b/modules/editor/evil/autoload/ex.el index 09b18ed70..bdcb5d6fa 100644 --- a/modules/editor/evil/autoload/ex.el +++ b/modules/editor/evil/autoload/ex.el @@ -108,7 +108,7 @@ g Repeat alignment on all matches in each line" If BANG is non-nil, open compilation output in a comint buffer. If BANG, then run ARGUMENTS as a full command. This command understands vim file -modifiers (like %:p:h). See `+evil-resolve-vim-path-a' for details." +modifiers (like %:p:h). See `+evil-replace-filename-modifiers-a' for details." (interactive "") (let ((compile-command "make")) (+evil:compile (if (stringp arguments) @@ -122,7 +122,7 @@ modifiers (like %:p:h). See `+evil-resolve-vim-path-a' for details." If BANG is non-nil, open compilation output in a comint buffer. This command understands vim file modifiers (like %:p:h). See -`+evil-resolve-vim-path-a' for details." +`+evil-replace-filename-modifiers-a' for details." (interactive "") (compile (evil-ex-replace-special-filenames (format "%s %s" diff --git a/modules/editor/evil/autoload/files.el b/modules/editor/evil/autoload/files.el index ac3daed1b..93de22915 100644 --- a/modules/editor/evil/autoload/files.el +++ b/modules/editor/evil/autoload/files.el @@ -6,8 +6,7 @@ kills the buffer. If FORCE-P, force the deletion (don't ask for confirmation)." :repeat nil (interactive "") - (doom/delete-this-file (or filename (file-truename buffer-file-name)) - force-p)) + (doom/delete-this-file filename force-p)) ;;;###autoload (autoload '+evil:move-this-file "editor/evil/autoload/files" nil t) (evil-define-command +evil:move-this-file (new-path &optional force-p) @@ -30,4 +29,3 @@ overwrite the destination file if it exists, without confirmation." (when (or (not new-path) (string-empty-p new-path)) (user-error "No new path was specified")) (doom/copy-this-file new-path force-p)) - diff --git a/modules/editor/evil/config.el b/modules/editor/evil/config.el index 3528964fd..358e0cb1f 100644 --- a/modules/editor/evil/config.el +++ b/modules/editor/evil/config.el @@ -144,13 +144,22 @@ directives. By default, this only recognizes C directives.") (when (eq major-mode 'fundamental-mode) (hack-local-variables))) + ;; HACK Invoking helpful from evil-ex throws a "No recursive edit is in + ;; progress" error because, between evil-ex and helpful, + ;; `abort-recursive-edit' gets called one time too many. + (defadvice! +evil--fix-helpful-key-in-evil-ex-a (key-sequence) + :before #'helpful-key + (when (evil-ex-p) + (run-at-time 0.1 nil #'helpful-key key-sequence) + (abort-recursive-edit))) + ;; Make ESC (from normal mode) the universal escaper. See `doom-escape-hook'. (advice-add #'evil-force-normal-state :after #'+evil-escape-a) ;; monkey patch `evil-ex-replace-special-filenames' to improve support for ;; file modifiers like %:p:h. This adds support for most of vim's modifiers, ;; and one custom one: %:P (expand to the project root). - (advice-add #'evil-ex-replace-special-filenames :override #'+evil-resolve-vim-path-a) + (advice-add #'evil-ex-replace-special-filenames :override #'+evil-replace-filename-modifiers-a) ;; make `try-expand-dabbrev' (from `hippie-expand') work in minibuffer (add-hook 'minibuffer-inactive-mode-hook #'+evil--fix-dabbrev-in-minibuffer-h) diff --git a/modules/editor/evil/init.el b/modules/editor/evil/init.el index 1674bceb4..439082071 100644 --- a/modules/editor/evil/init.el +++ b/modules/editor/evil/init.el @@ -258,6 +258,9 @@ and complains if a module is loaded too early (during startup)." (+evil-collection-init 'elisp-mode)) (add-transient-hook! 'occur-mode (+evil-collection-init '(occur replace))) + (add-transient-hook! 'minibuffer-setup-hook + (when evil-collection-setup-minibuffer + (+evil-collection-init 'minibuffer))) ;; HACK Do this ourselves because evil-collection break's `eval-after-load' ;; load order by loading their target plugin before applying keys. This diff --git a/modules/editor/evil/test/test-evil.el b/modules/editor/evil/test/test-evil.el index dd77fd0f4..3b77c9cc3 100644 --- a/modules/editor/evil/test/test-evil.el +++ b/modules/editor/evil/test/test-evil.el @@ -9,10 +9,10 @@ (load! "../autoload/evil") (before-each - (fset 'resv #'+evil-resolve-vim-path-a) + (fset 'resv #'+evil-replace-filename-modifiers-a) (spy-on 'doom-project-root :and-call-fake (lambda () project-root))) - ;; `evil-ex-replace-special-filenames' / `+evil-resolve-vim-path-a' + ;; `evil-ex-replace-special-filenames' / `+evil-replace-filename-modifiers-a' (describe "file modifiers" (it "supports basic vim file modifiers" (let ((buffer-file-name "~/.emacs.d/test/modules/feature/test-evil.el") diff --git a/modules/editor/file-templates/templates/org-mode/__doom-readme b/modules/editor/file-templates/templates/org-mode/__doom-readme index 56a1f25a8..695067459 100644 --- a/modules/editor/file-templates/templates/org-mode/__doom-readme +++ b/modules/editor/file-templates/templates/org-mode/__doom-readme @@ -7,7 +7,7 @@ (match-string 2 buffer-file-name)) "")`} #+DATE: `(format (format-time-string "%B %%s, %Y") (string-to-number (format-time-string "%d")))` -#+SINCE: ${2:{replace with next tagged release version}} +#+SINCE: ${2:} #+STARTUP: inlineimages nofold * Table of Contents :TOC_3:noexport: diff --git a/modules/editor/snippets/config.el b/modules/editor/snippets/config.el index cb1c9315d..71218a728 100644 --- a/modules/editor/snippets/config.el +++ b/modules/editor/snippets/config.el @@ -5,7 +5,7 @@ ;; -;; Packages +;;; Packages (use-package! yasnippet :defer-incrementally eldoc easymenu help-mode @@ -20,9 +20,11 @@ ;; Remove default ~/.emacs.d/snippets (defvar yas-snippet-dirs nil) - ;; Ensure `yas-reload-all' is called as late as possible. Other modules could - ;; have additional configuration for yasnippet. For example, file-templates. - (add-transient-hook! 'yas-minor-mode-hook (yas-reload-all)) + (unless (daemonp) + ;; Ensure `yas-reload-all' is called as late as possible. Other modules + ;; could have additional configuration for yasnippet. For example, + ;; file-templates. + (add-transient-hook! 'yas-minor-mode-hook (yas-reload-all))) (add-hook! '(text-mode-hook prog-mode-hook @@ -31,24 +33,28 @@ #'yas-minor-mode-on) :config - (setq yas-verbosity (if doom-debug-mode 3 0) - yas-also-auto-indent-first-line t) - - (add-to-list 'load-path +snippets-dir) - ;; default snippets library, if available - (require 'doom-snippets nil t) - ;; Allow private snippets in DOOMDIR/snippets (add-to-list 'yas-snippet-dirs '+snippets-dir) - ;; In case `+snippets-dir' and `doom-snippets-dir' are the same + ;; Reduce verbosity. 3 is too chatty about initializing yasnippet. 2 is just + ;; right (only shows errors). + (setq yas-verbosity (if doom-debug-mode 3 0)) + ;; Ensure the snippet is properly indented + (setq yas-also-auto-indent-first-line t) + + ;; default snippets library, if available + (add-to-list 'load-path +snippets-dir) + (require 'doom-snippets nil t) + + ;; HACK In case `+snippets-dir' and `doom-snippets-dir' are the same, or + ;; duplicates exist in `yas-snippet-dirs'. (advice-add #'yas-snippet-dirs :filter-return #'delete-dups) ;; Remove GUI dropdown prompt (prefer ivy/helm) (delq! 'yas-dropdown-prompt yas-prompt-functions) ;; Prioritize private snippets in `+snippets-dir' over built-in ones if there ;; are multiple choices. - (add-to-list 'yas-prompt-functions #'+snippets-prompt-private nil #'eq) + (add-to-list 'yas-prompt-functions #'+snippets-prompt-private) ;; Register `def-project-mode!' modes with yasnippet. This enables project ;; specific snippet libraries (e.g. for Laravel, React or Jekyll projects). @@ -61,22 +67,14 @@ ;; tell smartparens overlays not to interfere with yasnippet keybinds (advice-add #'yas-expand :before #'sp-remove-active-pair-overlay)) - ;; Enable `read-only-mode' for built-in snippets (in `doom-local-dir') - (add-hook 'snippet-mode-hook #'+snippets-read-only-maybe-h) - ;; (Evil only) fix off-by-one issue with line-wise visual selections in ;; `yas-insert-snippet', and switches to insert mode afterwards. (advice-add #'yas-insert-snippet :around #'+snippets-expand-on-region-a) - (define-key! snippet-mode-map - "C-c C-k" #'+snippet--abort - "C-c C-e" #'+snippet--edit) + ;; Show keybind hints in snippet header-line (add-hook 'snippet-mode-hook #'+snippets-show-hints-in-header-line-h) - - ;; Replace commands with superior alternatives - (define-key! yas-minor-mode-map - [remap yas-new-snippet] #'+snippets/new - [remap yas-visit-snippet-file] #'+snippets/edit) + ;; Enable `read-only-mode' for built-in snippets (in `doom-local-dir') + (add-hook 'snippet-mode-hook #'+snippets-read-only-maybe-h) (map! :map yas-keymap "C-e" #'+snippets/goto-end-of-field @@ -85,7 +83,14 @@ [M-left] #'+snippets/goto-start-of-field [M-backspace] #'+snippets/delete-to-start-of-field [backspace] #'+snippets/delete-backward-char - [delete] #'+snippets/delete-forward-char-or-field)) + [delete] #'+snippets/delete-forward-char-or-field + ;; Replace commands with superior alternatives + :map yas-minor-mode-map + [remap yas-new-snippet] #'+snippets/new + [remap yas-visit-snippet-file] #'+snippets/edit) + + ;; If in a daemon session, front-load this expensive work: + (if (daemonp) (yas-reload-all))) (use-package! auto-yasnippet diff --git a/modules/editor/snippets/packages.el b/modules/editor/snippets/packages.el index e100d3717..fec5e4d36 100644 --- a/modules/editor/snippets/packages.el +++ b/modules/editor/snippets/packages.el @@ -1,10 +1,10 @@ ;; -*- no-byte-compile: t; -*- ;;; editor/snippets/packages.el -(package! yasnippet :pin "ac03c2f192") +(package! yasnippet :pin "5b1217ab08") (package! auto-yasnippet :pin "db9e0dd433") (package! doom-snippets :recipe (:host github :repo "hlissner/doom-snippets" :files ("*.el" "*")) - :pin "2a0c3cf901") + :pin "feaedeb550") diff --git a/modules/email/mu4e/README.org b/modules/email/mu4e/README.org index d87a9eefd..93f2ab37c 100644 --- a/modules/email/mu4e/README.org +++ b/modules/email/mu4e/README.org @@ -12,13 +12,15 @@ - [[#arch-linux][Arch Linux]] - [[#nixos][NixOS]] - [[#opensuse][openSUSE]] - - [[Debian/Ubuntu]] + - [[#debianubuntu][Debian/Ubuntu]] - [[#features][Features]] - [[#configuration][Configuration]] - [[#offlineimap][offlineimap]] - [[#mbsync][mbsync]] + - [[#mu-and-mu4e][mu and mu4e]] - [[#troubleshooting][Troubleshooting]] - [[#no-such-file-or-directory-mu4e][=No such file or directory, mu4e=]] + - [[#void-function-org-time-add-error-on-gentoo][~(void-function org-time-add)~ error on Gentoo]] * Description This module makes Emacs an email client, using ~mu4e~. @@ -36,13 +38,13 @@ via IMAP) and ~mu~ (to index my mail into a format ~mu4e~ can understand). + ~+gmail~ Enables gmail-specific configuration. ** Plugins -+ [[https://github.com/agpchil/mu4e-maildirs-extension][mu4e-maildirs-extension]] +This module install no plugins. * Prerequisites This module requires: + Either ~mbsync~ (default) or ~offlineimap~ (to sync mail with) -+ ~mu~ (to index your downloaded messages) ++ ~mu~, to index your downloaded messages and to provide the ~mu4e~ package. ** MacOS #+BEGIN_SRC sh @@ -104,20 +106,53 @@ sudo apt-get install maildir-utils # mu * Configuration ** offlineimap -This module uses =mbsync= by default. To change this, change ~+mu4e-backend~: +This module uses =mbsync= by default. To use =offlineimap=, change ~+mu4e-backend~: #+BEGIN_SRC emacs-lisp (setq +mu4e-backend 'offlineimap) #+END_SRC -Then you must set up offlineimap and index your mail: +Next, you need to write a configuration file for =offlineimap=. Mine can be found +[[https://github.com/hlissner/dotfiles/tree/master/shell/mu][in my dotfiles repository]]. It is configured to download mail to ~\~/.mail~. I +use [[https://www.passwordstore.org/][unix pass]] to securely store my login credentials. You can find a *very* +detailed configuration [[https://github.com/OfflineIMAP/offlineimap/blob/master/offlineimap.conf][here]]. -1. Write a ~\~/.offlineimaprc~. Mine can be found [[https://github.com/hlissner/dotfiles/tree/master/shell/mu][in my dotfiles repository]]. It - is configured to download mail to ~\~/.mail~. I use [[https://www.passwordstore.org/][unix pass]] to securely - store my login credentials. You can find a *very* detailed configuration - [[https://github.com/OfflineIMAP/offlineimap/blob/master/offlineimap.conf][here]]. -2. Download your email: ~offlineimap -o~ (may take a while) -3. Index it with mu: ~mu index --maildir ~/.mail~ +Next you can download your email with ~offlineimap -o~. This may take a while, +especially if you have thousands of mails. + +You can now proceed with the [[*mu and mu4e][mu and mu4e]] section. + +** mbsync +The steps needed to set up =mu4e= with =mbsync= are very similar to the ones for +[[*offlineimap][offlineimap]]. + +Start with writing a ~\~/.mbsyncrc~. An example for GMAIL can be found on +[[http://pragmaticemacs.com/emacs/migrating-from-offlineimap-to-mbsync-for-mu4e/][pragmaticemacs.com]]. A non-GMAIL example is available as a gist [[https://gist.github.com/agraul/60977cc497c3aec44e10591f94f49ef0][here]]. The [[http://isync.sourceforge.net/mbsync.html][manual +page]] contains all needed information to set up your own. + +Next you can download your email with ~mbsync --all~. This may take a while, but +should be quicker than =offlineimap= ;). + +You can now proceed with the [[*mu and mu4e][mu and mu4e]] section. + +** mu and mu4e +You should have your email downloaded already. If you have not, you need to set +=offlineimap= or =mbsync= up before you proceed. + +Before you can use =mu4e= or the cli program =mu=, you need to index your email +initially. How to do that differs a little depending on the version of =mu= you +use. You can check your version with ~mu --version~. + +For =mu= *>=1.4* you need to run two commands: +#+BEGIN_SRC sh +mu init --maildir ~/.mail --my-address email@example.com +mu index +#+END_SRC + +=mu= *<1.4* only requires one command: +#+BEGIN_SRC sh +mu index --maildir ~/.mail +#+END_SRC Then configure Emacs to use your email address: @@ -129,13 +164,20 @@ Then configure Emacs to use your email address: (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") + (user-mail-address . "henrik@lissner.net") ;; only needed for mu < 1.4 (mu4e-compose-signature . "---\nHenrik Lissner")) t) #+END_SRC -** TODO mbsync * Troubleshooting ** =No such file or directory, mu4e= You will get =No such file or directory, mu4e= errors if you don't run ~doom sync~ after installing =mu= through your package manager. +** ~(void-function org-time-add)~ error on Gentoo +Gentoo users will see this error because [[https://gitweb.gentoo.org/repo/gentoo.git/tree/net-mail/mu/files/70mu-gentoo.el#n2][the =net-mail/mu= package eagerly loads +=mu4e= (which pulls in =org=) much too early]]; before Emacs reads =~/.emacs.d=. +So early, that it loads the built-in version of org-mode, rather than the newer +version that Doom installs. + +Later versions of the =net-mail/mu= package have [[https://gitweb.gentoo.org/repo/gentoo.git/commit/net-mail/mu?id=770e1fccb119fbce8ba6d16021a3598123f212ff][fixed this issue]], but you may +need to switch to the unstable build of =net-mail/mu= to see it. diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 27d9a10db..f413207df 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -6,7 +6,7 @@ list of cons cells (VARIABLE . VALUE) -- you may want to modify: + `user-full-name' (this or the global `user-full-name' is required) - + `user-mail-address' (required) + + `user-mail-address' (required in mu4e < 1.4) + `smtpmail-smtp-user' (required for sending mail from Emacs) OPTIONAL: @@ -19,8 +19,9 @@ OPTIONAL: DEFAULT-P is a boolean. If non-nil, it marks that email account as the default/fallback account." (after! mu4e - (when-let (address (cdr (assq 'user-mail-address letvars))) - (add-to-list 'mu4e-user-mail-address-list address)) + (when (version< mu4e-mu-version "1.4") + (when-let (address (cdr (assq 'user-mail-address letvars))) + (add-to-list 'mu4e-user-mail-address-list address))) (setq mu4e-contexts (cl-loop for context in mu4e-contexts unless (string= (mu4e-context-name context) label) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 3bdb86efa..54c5efb61 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -14,9 +14,11 @@ :commands mu4e mu4e-compose-new :init (provide 'html2text) ; disable obsolete package - (setq mu4e-maildir "~/.mail" - mu4e-attachment-dir "~/.mail/.attachments" - mu4e-user-mail-address-list nil) + (when (or (not (require 'mu4e-meta nil t)) + (version< mu4e-mu-version "1.4")) + (setq mu4e-maildir "~/.mail" + mu4e-user-mail-address-list nil)) + (setq mu4e-attachment-dir "~/.mail/.attachments") :config (pcase +mu4e-backend (`mbsync @@ -104,13 +106,13 @@ (use-package! org-mu4e :hook (mu4e-compose-mode . org-mu4e-compose-org-mode) :config - (setq org-mu4e-link-query-in-headers-mode nil - org-mu4e-convert-to-html t) + (setq org-mu4e-convert-to-html t) + (when (version< mu4e-mu-version "1.4") + (setq org-mu4e-link-query-in-headers-mode nil)) ;; Only render to html once. If the first send fails for whatever reason, ;; org-mu4e would do so each time you try again. - (add-hook! 'message-send-hook - (setq-local org-mu4e-convert-to-html nil))) + (setq-hook! 'message-send-hook org-mu4e-convert-to-html nil)) ;; diff --git a/modules/input/chinese/config.el b/modules/input/chinese/config.el index 666cfe395..ffa4e2669 100644 --- a/modules/input/chinese/config.el +++ b/modules/input/chinese/config.el @@ -2,9 +2,10 @@ (use-package! pyim :after-call after-find-file pre-command-hook + :init + (setq pyim-dcache-directory (concat doom-cache-dir "pyim/")) :config - (setq pyim-dcache-directory (concat doom-cache-dir "pyim/") - pyim-page-tooltip t + (setq pyim-page-tooltip t default-input-method "pyim")) diff --git a/modules/lang/assembly/autoload.el b/modules/lang/assembly/autoload.el deleted file mode 100644 index 29e8ded24..000000000 --- a/modules/lang/assembly/autoload.el +++ /dev/null @@ -1,4 +0,0 @@ -;;; lang/assembly/autoload.el -*- lexical-binding: t; -*- - -;;;###autoload -(add-to-list 'auto-mode-alist '("\\.hax\\'" . haxor-mode)) diff --git a/modules/lang/assembly/packages.el b/modules/lang/assembly/packages.el deleted file mode 100644 index 78e44be3d..000000000 --- a/modules/lang/assembly/packages.el +++ /dev/null @@ -1,6 +0,0 @@ -;; -*- no-byte-compile: t; -*- -;;; lang/assembly/packages.el - -(package! mips-mode :pin "75152fc78b") -(package! haxor-mode :pin "6fa25a8e6b") -(package! nasm-mode :pin "65ca6546fc") diff --git a/modules/lang/clojure/config.el b/modules/lang/clojure/config.el index 04a92bd2a..7a091a3ae 100644 --- a/modules/lang/clojure/config.el +++ b/modules/lang/clojure/config.el @@ -11,21 +11,22 @@ ;; ;;; Packages -;;;###package clojure-mode -(add-hook 'clojure-mode-hook #'rainbow-delimiters-mode) -(when (featurep! +lsp) - (add-hook! '(clojure-mode-local-vars-hook - clojurec-mode-local-vars-hook - clojurescript-mode-local-vars-hook) - (defun +clojure-disable-lsp-indentation-h () - (setq-local lsp-enable-indentation nil)) - #'lsp!) - (after! lsp-clojure - (dolist (m '(clojure-mode - clojurec-mode - clojurescript-mode - clojurex-mode)) - (add-to-list 'lsp-language-id-configuration (cons m "clojure"))))) +(use-package! clojure-mode + :hook (clojure-mode . rainbow-delimiters-mode) + :config + (when (featurep! +lsp) + (add-hook! '(clojure-mode-local-vars-hook + clojurec-mode-local-vars-hook + clojurescript-mode-local-vars-hook) + (defun +clojure-disable-lsp-indentation-h () + (setq-local lsp-enable-indentation nil)) + #'lsp!) + (after! lsp-clojure + (dolist (m '(clojure-mode + clojurec-mode + clojurescript-mode + clojurex-mode)) + (add-to-list 'lsp-language-id-configuration (cons m "clojure")))))) (use-package! cider @@ -58,13 +59,18 @@ cider-repl-history-quit-action 'delete-and-restore cider-repl-history-highlight-inserted-item t cider-repl-history-size 1000 - cider-repl-pop-to-buffer-on-connect 'display-only cider-repl-result-prefix ";; => " cider-repl-print-length 100 cider-repl-use-clojure-font-lock t cider-repl-use-pretty-printing t cider-repl-wrap-history nil - cider-stacktrace-default-filters '(tooling dup)) + cider-stacktrace-default-filters '(tooling dup) + + ;; Don't focus the CIDER REPL when it starts. Since it can take so long + ;; to start up, you either wait for a minute doing nothing or be + ;; prepared for your cursor to suddenly change buffers without warning. + ;; See https://github.com/clojure-emacs/cider/issues/1872 + cider-repl-pop-to-buffer-on-connect 'display-only) ;; Error messages emitted from CIDER is silently funneled into *nrepl-server* ;; rather than the *cider-repl* buffer. How silly. We might want to see that @@ -90,6 +96,8 @@ "\"" #'cider-jack-in-cljs "c" #'cider-connect-clj "C" #'cider-connect-cljs + "m" #'cider-macroexpand-1 + "M" #'cider-macroexpand-all (:prefix ("e" . "eval") "b" #'cider-eval-buffer "d" #'cider-eval-defun-at-point @@ -114,9 +122,6 @@ "e" #'cider-enlighten-mode "i" #'cider-inspect "r" #'cider-inspect-last-result) - (:prefix ("m" . "macro") - "e" #'cider-macroexpand-1 - "E" #'cider-macroexpand-all) (:prefix ("n" . "namespace") "n" #'cider-browse-ns "N" #'cider-browse-ns-all diff --git a/modules/lang/dart/packages.el b/modules/lang/dart/packages.el index 44d69fa9a..30a0f8be8 100644 --- a/modules/lang/dart/packages.el +++ b/modules/lang/dart/packages.el @@ -4,8 +4,8 @@ (package! dart-mode :pin "04fcd649f1") (when (featurep! +lsp) - (package! lsp-dart :pin "064d47bad3")) + (package! lsp-dart :pin "4cd73b77f4")) (when (featurep! +flutter) - (package! flutter :pin "ec92a4df84") + (package! flutter :pin "293b7225b9") (package! hover :pin "6f9ed1a651")) diff --git a/modules/lang/data/config.el b/modules/lang/data/config.el index e625d4fd0..da0e72344 100644 --- a/modules/lang/data/config.el +++ b/modules/lang/data/config.el @@ -1,9 +1,5 @@ ;;; lang/data/config.el -*- lexical-binding: t; -*- -;; Built in plugins -(add-to-list 'auto-mode-alist '("/sxhkdrc\\'" . conf-mode)) -(add-to-list 'auto-mode-alist '("\\.\\(?:hex\\|nes\\)\\'" . hexl-mode)) - (use-package! nxml-mode :mode "\\.p\\(?:list\\|om\\)\\'" ; plist, pom :mode "\\.xs\\(?:d\\|lt\\)\\'" ; xslt, xsd @@ -16,9 +12,6 @@ (setq-hook! 'nxml-mode-hook tab-width nxml-child-indent)) -;; -;;; Third-party plugins - ;;;###package csv-mode (map! :after csv-mode :localleader @@ -29,25 +22,3 @@ "S" #'csv-sort-numeric-fields "k" #'csv-kill-fields "t" #'csv-transpose) - -(use-package! graphql-mode - :mode "\\.gql\\'" - :config (setq-hook! 'graphql-mode-hook tab-width graphql-indent-level)) - -(use-package! json-mode - :mode "\\.js\\(?:on\\|[hl]int\\(?:rc\\)?\\)\\'" - :config - (set-electric! 'json-mode :chars '(?\n ?: ?{ ?}))) - -(after! jsonnet-mode - (set-electric! 'jsonnet-mode :chars '(?\n ?: ?{ ?}))) - -(after! yaml-mode - (setq-hook! 'yaml-mode-hook tab-width yaml-indent-offset)) - - -;; -;;; Frameworks - -(def-project-mode! +data-vagrant-mode - :files ("Vagrantfile")) diff --git a/modules/lang/data/packages.el b/modules/lang/data/packages.el index 1c338af9e..72a9dae2d 100644 --- a/modules/lang/data/packages.el +++ b/modules/lang/data/packages.el @@ -1,12 +1,4 @@ ;; -*- no-byte-compile: t; -*- ;;; lang/data/packages.el -(package! graphql-mode :pin "7c37aee28b") -(package! json-mode :pin "0e819e519a") -(package! jsonnet-mode :pin "d8b486c837") -(package! yaml-mode :pin "cecf4b106b") (package! csv-mode :pin "635337407c") -(package! dhall-mode :pin "ef4d33debe") -(package! protobuf-mode - :recipe (:host github :repo "emacsmirror/protobuf-mode" :files (:defaults "*")) - :pin "94b7bd7e8b") diff --git a/modules/lang/elm/config.el b/modules/lang/elm/config.el index 71c3dd97c..504adbce8 100644 --- a/modules/lang/elm/config.el +++ b/modules/lang/elm/config.el @@ -1,12 +1,10 @@ ;;; lang/elm/config.el -*- lexical-binding: t; -*- (after! elm-mode - (add-hook 'elm-mode-hook #'rainbow-delimiters-mode) - - (when (featurep! +lsp) - (add-hook 'elm-mode-local-vars-hook #'lsp!)) - - (set-company-backend! 'elm-mode 'company-elm) + (if (featurep! +lsp) + (add-hook 'elm-mode-local-vars-hook #'lsp!) + (set-company-backend! 'elm-mode 'company-elm)) + (set-repl-handler! 'elm-mode #'run-elm-interactive) (set-pretty-symbols! 'elm-mode :null "null" @@ -22,4 +20,4 @@ (use-package! flycheck-elm :when (featurep! :checkers syntax) :after elm-mode - :config (add-to-list 'flycheck-checkers 'elm nil #'eq)) + :config (add-to-list 'flycheck-checkers 'elm)) diff --git a/modules/lang/elm/packages.el b/modules/lang/elm/packages.el index 6485cbe2f..220ae8bef 100644 --- a/modules/lang/elm/packages.el +++ b/modules/lang/elm/packages.el @@ -1,6 +1,6 @@ ;; -*- no-byte-compile: t; -*- ;;; lang/elm/packages.el -(package! elm-mode :pin "dd868e55ff") +(package! elm-mode :pin "7782be0814") (when (featurep! :checkers syntax) - (package! flycheck-elm :pin "debd0af563")) + (package! flycheck-elm :pin "1b60050efd")) diff --git a/modules/lang/emacs-lisp/packages.el b/modules/lang/emacs-lisp/packages.el index 38adeaf2f..a72ea6124 100644 --- a/modules/lang/emacs-lisp/packages.el +++ b/modules/lang/emacs-lisp/packages.el @@ -4,12 +4,14 @@ (package! elisp-mode :built-in t) (package! highlight-quoted :pin "2410347815") + +;; Tools (package! macrostep :pin "424e3734a1") (package! overseer :pin "02d49f582e") (package! elisp-def :pin "368b04da68") -(package! elisp-demos :pin "0d74766f0c") - +(package! elisp-demos :pin "57dd4ae3e4") (when (featurep! :checkers syntax) (package! flycheck-cask :pin "3457ae553c")) -(package! buttercup :pin "b360e35017") +;; Libraries +(package! buttercup :pin "a91f282025") diff --git a/modules/lang/go/README.org b/modules/lang/go/README.org index 04ea402fa..f16d71788 100644 --- a/modules/lang/go/README.org +++ b/modules/lang/go/README.org @@ -15,7 +15,8 @@ - [[#troubleshooting][Troubleshooting]] * Description -This module adds [[https://golang.org][Go]] support. +This module adds [[https://golang.org][Go]] support, with optional (but recommended) LSP support via +[[https://github.com/golang/tools/blob/master/gopls/README.md][gopls]]. + Code completion (~gocode~) + Documentation lookup (~godoc~) @@ -30,7 +31,8 @@ This module adds [[https://golang.org][Go]] support. + Code checking (~flycheck-golangci-lint~) ** Module Flags -+ =+lsp= Enables integration for the gopls LSP server. ++ =+lsp= Enables integration for the gopls LSP server. It is highly recommended + you use this, as the non-LSP experience is deprecated (and poor). ** Plugins + [[https://github.com/dominikh/go-mode.el][go-mode]] @@ -38,7 +40,7 @@ This module adds [[https://golang.org][Go]] support. + [[https://github.com/dominikh/go-mode.el][go-guru]] + [[https://github.com/manute/gorepl-mode][gorepl-mode]] + [[https://github.com/brantou/emacs-go-tag][go-tag]] -+ [[https://github.com/mdempsky/gocode][company-go]]* ++ [[https://github.com/mdempsky/gocode][company-go]]* =DEPRECATED= + [[https://github.com/s-kostyaev/go-gen-test][go-gen-test]] + [[https://github.com/weijiangan/flycheck-golangci-lint][flycheck-golangci-lint]] (if =:checkers syntax= is enabled) diff --git a/modules/lang/go/packages.el b/modules/lang/go/packages.el index 88961221b..fe58f0329 100644 --- a/modules/lang/go/packages.el +++ b/modules/lang/go/packages.el @@ -2,14 +2,14 @@ ;;; lang/go/packages.el (package! go-eldoc :pin "cbbd2ea1e9") -(package! go-guru :pin "85a20dac6c") -(package! go-mode :pin "85a20dac6c") +(package! go-guru :pin "10d6ab43d9") +(package! go-mode :pin "10d6ab43d9") (package! gorepl-mode :pin "6a73bf352e") (package! go-tag :pin "59b243f2fa") (package! go-gen-test :pin "44c202ac97") (when (featurep! :completion company) - (package! company-go :pin "939b4a677f")) + (package! company-go :pin "4acdcbdea7")) (when (featurep! :checkers syntax) (package! flycheck-golangci-lint :pin "8e446c6831")) diff --git a/modules/lang/java/config.el b/modules/lang/java/config.el index 4b04f3dff..5e6dee5fd 100644 --- a/modules/lang/java/config.el +++ b/modules/lang/java/config.el @@ -22,7 +22,7 @@ If the depth is 2, the first two directories are removed: net.lissner.game.") ;; -;; java-mode +;;; java-mode (add-hook 'java-mode-hook #'rainbow-delimiters-mode) @@ -31,7 +31,7 @@ If the depth is 2, the first two directories are removed: net.lissner.game.") ;; -;; Common packages +;;; Common packages (use-package! android-mode :commands android-mode diff --git a/modules/lang/javascript/README.org b/modules/lang/javascript/README.org index 2d45742fa..7edd05fc5 100644 --- a/modules/lang/javascript/README.org +++ b/modules/lang/javascript/README.org @@ -37,7 +37,6 @@ This module adds JavaScript and TypeScript support. + [[https://github.com/mooz/js2-mode][js2-mode]] + [[https://github.com/felipeochoa/rjsx-mode][rjsx-mode]] + [[https://github.com/emacs-typescript/typescript.el][typescript-mode]] -+ [[https://github.com/aaronjensen/eslintd-fix][eslintd-fix]] + [[https://github.com/magnars/js2-refactor.el][js2-refactor]] + [[https://github.com/mojochao/npm-mode][npm-mode]] + [[https://github.com/abicky/nodejs-repl.el][nodejs-repl]] diff --git a/modules/lang/javascript/autoload.el b/modules/lang/javascript/autoload.el index a570be4ff..d4633f6b6 100644 --- a/modules/lang/javascript/autoload.el +++ b/modules/lang/javascript/autoload.el @@ -83,18 +83,6 @@ Run this for any buffer you want to skewer." ;; ;; Hooks -;;;###autoload -(defun +javascript-add-node-modules-path-h () - "Add current project's `node_modules/.bin` to `exec-path', so js tools -prioritize project-local packages over global ones." - (make-local-variable 'exec-path) - (cl-pushnew (expand-file-name "node_modules/.bin/" - (or (locate-dominating-file - (or (buffer-file-name) default-directory) - "node_modules") - (doom-project-root))) - exec-path :test #'string=)) - ;;;###autoload (defun +javascript-cleanup-tide-processes-h () "Clean up dangling tsserver processes if there are no more buffers with diff --git a/modules/lang/javascript/config.el b/modules/lang/javascript/config.el index c2fddb09b..479116ec7 100644 --- a/modules/lang/javascript/config.el +++ b/modules/lang/javascript/config.el @@ -133,7 +133,9 @@ ;; ;;; Tools -(add-hook! '(js-mode-hook typescript-mode-hook web-mode-hook) +(add-hook! '(js2-mode-local-vars-hook + typescript-mode-local-vars-hook + web-mode-local-vars-hook) (defun +javascript-init-lsp-or-tide-maybe-h () "Start `lsp' or `tide' in the current buffer. @@ -177,9 +179,11 @@ to tide." (setq-default company-backends (delq 'company-tide (default-value 'company-backends)))) (set-company-backend! 'tide-mode 'company-tide) ;; navigation - (set-lookup-handlers! 'tide-mode - :definition '(tide-jump-to-definition :async t) - :references '(tide-references :async t)) + (set-lookup-handlers! 'tide-mode :async t + :definition #'tide-jump-to-definition + :references #'tide-references + :documentation #'tide-documentation-at-point) + (set-popup-rule! "^\\*tide-documentation" :quit t) ;; resolve to `doom-project-root' if `tide-project-root' fails (advice-add #'tide-project-root :override #'+javascript-tide-project-root-a) ;; cleanup tsserver when no tide buffers are left @@ -192,8 +196,6 @@ to tide." ;; `tide-mode-hook' is too early, so... (advice-add #'tide-setup :after #'eldoc-mode) - (define-key tide-mode-map [remap +lookup/documentation] #'tide-documentation-at-point) - (map! :localleader :map tide-mode-map "R" #'tide-restart-server @@ -239,13 +241,6 @@ to tide." (js2r-add-keybindings-with-prefix (format "%s r" doom-localleader-key))))) -(use-package! eslintd-fix - :commands eslintd-fix - :config - (setq-hook! 'eslintd-fix-mode-hook - flycheck-javascript-eslint-executable eslintd-fix-executable)) - - ;;;###package skewer-mode (map! :localleader (:after js2-mode @@ -292,10 +287,11 @@ to tide." web-mode markdown-mode js-mode + json-mode typescript-mode solidity-mode) :when (locate-dominating-file default-directory "package.json") - :add-hooks '(+javascript-add-node-modules-path-h npm-mode)) + :add-hooks '(add-node-modules-path npm-mode)) (def-project-mode! +javascript-gulp-mode :when (locate-dominating-file default-directory "gulpfile.js")) diff --git a/modules/lang/javascript/packages.el b/modules/lang/javascript/packages.el index 5c3f1f9ad..483ef6f47 100644 --- a/modules/lang/javascript/packages.el +++ b/modules/lang/javascript/packages.el @@ -8,9 +8,9 @@ (package! typescript-mode :pin "102587e458") ;; Tools -(package! eslintd-fix :pin "0c431141be") (package! js2-refactor :pin "d4c40b5fc8") (package! npm-mode :pin "3ee7c0bad5") +(package! add-node-modules-path :pin "f31e69ccb6") ;; Eval (package! nodejs-repl :pin "6fad7d764f") diff --git a/modules/lang/json/README.org b/modules/lang/json/README.org new file mode 100644 index 000000000..6106c7ff1 --- /dev/null +++ b/modules/lang/json/README.org @@ -0,0 +1,40 @@ +#+TITLE: lang/json +#+DATE: April 23, 2020 +#+SINCE: v3.0.0 +#+STARTUP: inlineimages nofold + +* Table of Contents :TOC_3:noexport: +- [[#description][Description]] + - [[#maintainers][Maintainers]] + - [[#module-flags][Module Flags]] + - [[#plugins][Plugins]] +- [[#prerequisites][Prerequisites]] +- [[#features][Features]] +- [[#configuration][Configuration]] +- [[#troubleshooting][Troubleshooting]] + +* Description +This module provides JSON support. + +** Maintainers +This module has no dedicated maintainers. + +** Module Flags ++ =+lsp= Enable integration with LSP servers, if one is available. Requires the + =:tools lsp= module to be enabled. + +** Plugins ++ [[https://github.com/joshwnj/json-mode][json-mode]] ++ [[https://github.com/Sterlingg/json-snatcher][json-snatcher]] + +* Prerequisites +This module has no prereqisites. + +* TODO Features +# An in-depth list of features, how to use them, and their dependencies. + +* TODO Configuration +# How to configure this module, including common problems and how to address them. + +* TODO Troubleshooting +# Common issues and their solution, or places to look for help. diff --git a/modules/lang/json/config.el b/modules/lang/json/config.el new file mode 100644 index 000000000..62db538af --- /dev/null +++ b/modules/lang/json/config.el @@ -0,0 +1,14 @@ +;;; lang/json/config.el -*- lexical-binding: t; -*- + +(use-package! json-mode + :mode "\\.js\\(?:on\\|[hl]int\\(?:rc\\)?\\)\\'" + :init + (when (featurep! +lsp) + (add-hook 'json-mode-local-vars-hook #'lsp!)) + :config + (set-electric! 'json-mode :chars '(?\n ?: ?{ ?})) + + (map! :after json-mode + :map json-mode-map + :localleader + "s" #'jsons-print-path)) diff --git a/modules/lang/json/packages.el b/modules/lang/json/packages.el new file mode 100644 index 000000000..69d84fb8a --- /dev/null +++ b/modules/lang/json/packages.el @@ -0,0 +1,5 @@ +;; -*- no-byte-compile: t; -*- +;;; lang/json/packages.el + +(package! json-mode :pin "0e819e519a") +(package! json-snatcher :pin "c4cecc0a50") diff --git a/modules/lang/julia/autoload.el b/modules/lang/julia/autoload.el index 5d0d16641..d25f60b58 100644 --- a/modules/lang/julia/autoload.el +++ b/modules/lang/julia/autoload.el @@ -10,7 +10,8 @@ "Run an inferior instance of `julia' inside Emacs." (interactive) (if (require 'julia-repl nil t) - (julia-repl) + (prog1 (julia-repl) + (julia-repl-use-emacsclient)) (let ((buffer (get-buffer-create "*Julia*"))) (unless (comint-check-proc "*Julia*") (apply #'make-comint-in-buffer "Julia" "*Julia*" julia-program julia-arguments)) diff --git a/modules/lang/latex/README.org b/modules/lang/latex/README.org index a70d76989..1baa4a33c 100644 --- a/modules/lang/latex/README.org +++ b/modules/lang/latex/README.org @@ -33,6 +33,8 @@ Provide a helping hand when working with LaTeX documents. ** Module Flags + =+latexmk= Use LatexMk instead of LaTeX to compile documents. + =+cdlatex= Enable [[https://github.com/cdominik/cdlatex][cdlatex]] for fast math insertion. ++ =+lsp= Start LSP automatically in `tex-mode-hook`. This requires the =:tools + lsp= module. Supported servers are `digestif` and `TexLab`. + =+fold= Use TeX-fold (from auctex) to fold LaTeX macros to unicode, and make folding hook-based and less manual. diff --git a/modules/lang/latex/config.el b/modules/lang/latex/config.el index 8d8f4e16b..31227ae65 100644 --- a/modules/lang/latex/config.el +++ b/modules/lang/latex/config.el @@ -70,7 +70,12 @@ If no viewers are found, `latex-preview-pane' is used.") (sp-local-pair modes open nil :actions :rem)) ;; And tweak these so that users can decide whether they want use latex ;; quotes or not, via `+latex-enable-plain-double-quotes' - (sp-local-pair modes "``" nil :unless '(:add sp-in-math-p))))) + (sp-local-pair modes "``" nil :unless '(:add sp-in-math-p)))) + ;; Hook lsp if enabled + (when (featurep! +lsp) + (add-hook! '(tex-mode-local-vars-hook + latex-mode-local-vars-hook) + #'lsp!))) (use-package! tex-fold @@ -209,6 +214,7 @@ is mostly for \\section etc." (add-to-list '+latex--company-backends #'company-auctex-environments nil #'eq) (add-to-list '+latex--company-backends #'company-auctex-macros nil #'eq)) + (use-package! company-math :when (featurep! :completion company) :defer t diff --git a/modules/lang/markdown/config.el b/modules/lang/markdown/config.el index ddce13f34..07003b237 100644 --- a/modules/lang/markdown/config.el +++ b/modules/lang/markdown/config.el @@ -70,6 +70,7 @@ capture, the end position, and the output buffer.") (map! :map markdown-mode-map :localleader + "'" #'markdown-edit-code-block "o" #'markdown-open "p" #'markdown-preview "e" #'markdown-export diff --git a/modules/lang/org/README.org b/modules/lang/org/README.org index 12a554e88..abd177491 100644 --- a/modules/lang/org/README.org +++ b/modules/lang/org/README.org @@ -18,6 +18,7 @@ - [[#built-in-custom-link-types][Built-in custom link types]] - [[#configuration][Configuration]] - [[#changing-org-directory][Changing ~org-directory~]] + - [[#changing-org-noter-notes-search-path][Changing ~org-noter-notes-search-path~]] * Description This module adds org-mode support to Doom Emacs, along with a number of @@ -63,6 +64,8 @@ https://www.mfoot.com/blog/2015/11/22/literate-emacs-configuration-with-org-mode + =+ipython= (**DEPRECATED**) Enables ipython integration for babel. + =+journal= Enables [[https://github.com/bastibe/org-journal][org-journal]] integration. + =+jupyter= Enables Jupyter integration for babel. ++ =+noter= Enables org-noter integration. Keeps notes in sync with a document. + Requires [[https://github.com/politza/pdf-tools][pdf-tools]] (=:tools pdf=) or [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Document-View.html][DocView]] or [[https://github.com/wasamasa/nov.el][nov.el]] to be enabled. + =+pandoc= Enables pandoc integration into the Org exporter. + =+pomodoro= Enables a pomodoro timer for clocking time on tasks. + =+present= Enables integration with reveal.js, beamer and org-tree-slide, so @@ -121,6 +124,9 @@ https://www.mfoot.com/blog/2015/11/22/literate-emacs-configuration-with-org-mode + =+roam= + [[https://github.com/jethrokuan/org-roam][org-roam]] + [[https://github.com/jethrokuan/company-org-roam][company-org-roam]] ++ =+noter= + + [[https://github.com/weirdNox/org-noter][org-noter]] + ** Hacks + The window is recentered when following links. @@ -223,3 +229,10 @@ To modify ~org-directory~ it must be set /before/ =org= has loaded: ;; ~/.doom.d/config.el (setq org-directory "~/new/org/location/") #+END_SRC +** Changing ~org-noter-notes-search-path~ +To modify ~org-noter-notes-search-path~ set: + +#+BEGIN_SRC emacs-lisp +;; ~/.doom.d/config.el +(setq org-noter-notes-search-path '("~/notes/path/")) +#+END_SRC diff --git a/modules/lang/org/autoload/contrib-dragndrop.el b/modules/lang/org/autoload/contrib-dragndrop.el index 1adc86278..618790cee 100644 --- a/modules/lang/org/autoload/contrib-dragndrop.el +++ b/modules/lang/org/autoload/contrib-dragndrop.el @@ -10,13 +10,3 @@ (rassq-delete-all '+org-dragndrop-download-dnd-fn (copy-alist dnd-protocol-alist)))) (dnd-handle-one-url nil action uri)))) - -;;;###autoload -(defun +org-dragndrop-image-fn (protocol link _description) - "Return the image associated with the current attachment." - (let ((file (expand-file-name link org-attach-id-dir))) - (when (and (file-exists-p file) (image-type-from-file-name file)) - (with-temp-buffer - (insert-file-contents file) - (goto-char (point-min)) - (buffer-substring-no-properties (point) (point-max)))))) diff --git a/modules/lang/org/autoload/org-attach.el b/modules/lang/org/autoload/org-attach.el index fa41685b2..dbe88739b 100644 --- a/modules/lang/org/autoload/org-attach.el +++ b/modules/lang/org/autoload/org-attach.el @@ -42,7 +42,7 @@ PATH (a string) can be an url, a local file path, or a base64 encoded datauri." (unless (eq major-mode 'org-mode) (user-error "Not in an org buffer")) (require 'org-download) - (condition-case ex + (condition-case-unless-debug e (let ((raw-uri (url-unhex-string path))) (cond ((string-match-p "^data:image/png;base64," path) (org-download-dnd-base64 path nil)) @@ -56,4 +56,4 @@ PATH (a string) can be an url, a local file path, or a base64 encoded datauri." ;; insert the link (org-download-insert-link raw-uri new-path))))) (error - (user-error "Failed to attach file: %s" (error-message-string ex))))) + (user-error "Failed to attach file: %s" (error-message-string e))))) diff --git a/modules/lang/org/autoload/org-link.el b/modules/lang/org/autoload/org-link.el index bc4317183..59d6c477b 100644 --- a/modules/lang/org/autoload/org-link.el +++ b/modules/lang/org/autoload/org-link.el @@ -1,43 +1,72 @@ ;;; lang/org/autoload/org-link.el -*- lexical-binding: t; -*- -(defun +org--relpath (path root) +(defun +org--relative-path (path root) (if (and buffer-file-name (file-in-directory-p buffer-file-name root)) (file-relative-name path) path)) -;;;###autoload -(defun +org-def-link (key dir) - (org-link-set-parameters - key - :complete (lambda () (+org--relpath (+org-link-read-file key dir) dir)) - :follow (lambda (link) (find-file (expand-file-name link dir))) - :face (lambda (link) - (if (file-exists-p (expand-file-name link dir)) - 'org-link - 'error)))) +(defun +org--read-link-path (key dir &optional fn) + (let ((file (funcall (or fn #'read-file-name) (format "%s: " (capitalize key)) dir))) + (format "%s:%s" key (file-relative-name file dir)))) ;;;###autoload -(defun +org-link-read-file (key dir) - (let ((file (read-file-name (format "%s: " (capitalize key)) dir))) - (format "%s:%s" - key - (file-relative-name file dir)))) +(defun +org-define-basic-link (key dir-var &rest plist) + "Define a link with some basic completion & fontification. + +KEY is the name of the link type. DIR-VAR is the directory variable to resolve +links relative to. PLIST is passed to `org-link-set-parameters' verbatim. + +Links defined with this will be rendered in the `error' face if the file doesn't +exist, and `org-link' otherwise." + (declare (indent 2)) + (let ((requires (plist-get plist :requires)) + (dir-fn (if (functionp dir-var) + dir-var + (lambda () (symbol-value dir-var))))) + (apply #'org-link-set-parameters + key + :complete (lambda () + (if requires (mapc #'require (doom-enlist requires))) + (+org--relative-path (+org--read-link-path key (funcall dir-fn)) + (funcall dir-fn))) + :follow (lambda (link) + (org-link-open-as-file (expand-file-name link (funcall dir-fn)) nil)) + :face (lambda (link) + (if (file-exists-p (expand-file-name link (funcall dir-fn))) + 'org-link + 'error)) + (doom-plist-delete plist :requires)))) + + +;; +;;; Image data functions (for custom inline images) ;;;###autoload -(defun +org-link-read-directory (key dir) - (let ((file (read-directory-name (format "%s: " (capitalize key)) dir))) - (format "%s:%s" - key - (file-relative-name file dir)))) +(defun +org-image-file-data-fn (protocol link _description) + "Intepret LINK as an image file path and return its data." + (setq + link (expand-file-name + link + (pcase protocol + ("download" (or org-download-image-dir org-attach-id-dir default-directory)) + ("attachment" org-attach-id-dir) + (_ default-directory)))) + (when (and (file-exists-p link) + (image-type-from-file-name link)) + (with-temp-buffer + (set-buffer-multibyte nil) + (setq buffer-file-coding-system 'binary) + (insert-file-contents-literally link) + (buffer-substring-no-properties (point-min) (point-max))))) ;;;###autoload -(defun +org-inline-data-image (_protocol link _description) +(defun +org-inline-image-data-fn (_protocol link _description) "Interpret LINK as base64-encoded image data." (base64-decode-string link)) ;;;###autoload -(defun +org-image-link (protocol link _description) - "Interpret LINK as base64-encoded image data." +(defun +org-http-image-data-fn (protocol link _description) + "Interpret LINK as an URL to an image file." (when (image-type-from-file-name link) (if-let* ((buf (url-retrieve-synchronously (concat protocol ":" link)))) (with-current-buffer buf diff --git a/modules/lang/org/config.el b/modules/lang/org/config.el index c2c8a2b72..4a2b58faa 100644 --- a/modules/lang/org/config.el +++ b/modules/lang/org/config.el @@ -65,6 +65,12 @@ Is relative to `org-directory', unless it is absolute. Is used in Doom's default ;; ;;; `org-load' hooks +(defun +org-init-org-directory-h () + (unless org-directory + (setq org-directory "~/org")) + (setq org-id-locations-file (expand-file-name ".orgids" org-directory))) + + (defun +org-init-agenda-h () (unless org-agenda-files (setq org-agenda-files (list org-directory))) @@ -141,9 +147,10 @@ This forces it to read the background before rendering." (setq org-todo-keywords '((sequence "TODO(t)" ; A task that needs doing & is ready to do - "PROJ(p)" ; An ongoing project that cannot be completed in one step + "PROJ(p)" ; A project, which usually contains other tasks "STRT(s)" ; A task that is in progress - "WAIT(w)" ; Something is holding up this task; or it is paused + "WAIT(w)" ; Something external is holding up this task + "HOLD(h)" ; This task is paused/on hold because of me "|" "DONE(d)" ; Task successfully completed "KILL(k)") ; Task was cancelled, aborted or is no longer applicable @@ -158,14 +165,20 @@ This forces it to read the background before rendering." ("STRT" . +org-todo-active) ("[?]" . +org-todo-onhold) ("WAIT" . +org-todo-onhold) + ("HOLD" . +org-todo-onhold) ("PROJ" . +org-todo-project))) - (defadvice! +org-display-link-in-eldoc-a (orig-fn &rest args) + (after! org-eldoc + ;; HACK Fix #2972: infinite recursion when eldoc kicks in in an 'org' src + ;; block. + ;; TODO Should be reported upstream! + (puthash "org" "ignore" org-eldoc-local-functions-cache)) + + (defadvice! +org-display-link-in-eldoc-a (&rest args) "Display full link in minibuffer when cursor/mouse is over it." - :around #'org-eldoc-documentation-function - (or (when-let (link (org-element-property :raw-link (org-element-context))) - (format "Link: %s" link)) - (apply orig-fn args))) + :before-until #'org-eldoc-documentation-function + (when-let (link (org-element-property :raw-link (org-element-context))) + (format "Link: %s" link))) ;; Automatic indent detection in org files is meaningless (add-to-list 'doom-detect-indentation-excluded-modes 'org-mode) @@ -338,7 +351,7 @@ relative to `org-directory', unless it is an absolute path." (defadvice! +org--prevent-save-prompts-when-refiling-a (&rest _) "Fix #462: when refiling from org-capture, Emacs prompts to kill the underlying, modified buffer. This fixes that." - :after 'org-refile + :after #'org-refile (when (bound-and-true-p org-capture-is-refiling) (org-save-all-org-buffers))) @@ -364,14 +377,15 @@ underlying, modified buffer. This fixes that." (defun +org-init-attachments-h () "Sets up org's attachment system." + (setq org-attach-store-link-p t ; store link after attaching files + org-attach-use-inheritance t) ; inherit properties from parent nodes + ;; Centralized attachments directory - (setq org-attach-id-dir (doom-path org-directory org-attach-id-dir) - ;; Store a link to attachments when they are attached - org-attach-store-link-p t - ;; Inherit attachment properties from parent nodes - org-attach-use-inheritance t) - (after! projectile - (add-to-list 'projectile-globally-ignored-directories org-attach-id-dir))) + (after! org-attach + (unless org-attach-id-dir + (setq org-attach-id-dir (expand-file-name ".attach/" org-directory))) + (after! projectile + (add-to-list 'projectile-globally-ignored-directories org-attach-id-dir)))) (defun +org-init-custom-links-h () @@ -395,15 +409,15 @@ underlying, modified buffer. This fixes that." '("wolfram" . "https://wolframalpha.com/input/?i=%s") '("doom-repo" . "https://github.com/hlissner/doom-emacs/%s")) - (+org-def-link "org" org-directory) - (+org-def-link "doom" doom-emacs-dir) - (+org-def-link "doom-docs" doom-docs-dir) - (+org-def-link "doom-modules" doom-modules-dir) + (+org-define-basic-link "org" 'org-directory) + (+org-define-basic-link "doom" 'doom-emacs-dir) + (+org-define-basic-link "doom-docs" 'doom-docs-dir) + (+org-define-basic-link "doom-modules" 'doom-modules-dir) ;; Allow inline image previews of http(s)? urls or data uris - (org-link-set-parameters "http" :image-data-fun #'+org-image-link) - (org-link-set-parameters "https" :image-data-fun #'+org-image-link) - (org-link-set-parameters "img" :image-data-fun #'+org-inline-data-image) + (org-link-set-parameters "http" :image-data-fun #'+org-http-image-data-fn) + (org-link-set-parameters "https" :image-data-fun #'+org-http-image-data-fn) + (org-link-set-parameters "img" :image-data-fun #'+org-inline-image-data-fn) ;; Add support for youtube links + previews (require 'org-yt nil t)) @@ -456,9 +470,9 @@ underlying, modified buffer. This fixes that." (defun +org-init-hacks-h () "Getting org to behave." - ;; Don't open separate windows + ;; Open file links in current window, rather than new ones (setf (alist-get 'file org-link-frame-setup) #'find-file) - ;; Open directory links in Emacs + ;; Open directory links in dired (add-to-list 'org-file-apps '(directory . emacs)) ;; When you create a sparse tree and `org-indent-mode' is enabled, the @@ -566,6 +580,9 @@ between the two." "C-c C-S-l" #'+org/remove-link "C-c C-i" #'org-toggle-inline-images ;; textmate-esque newline insertion + "C-RET" #'+org/insert-item-below + "C-S-RET" #'+org/insert-item-above + "C-M-RET" #'org-insert-subheading [C-return] #'+org/insert-item-below [C-S-return] #'+org/insert-item-above [C-M-return] #'org-insert-subheading @@ -578,7 +595,10 @@ between the two." [remap doom/forward-to-last-non-comment-or-eol] #'org-end-of-line :localleader + "#" #'org-update-statistics-cookies "'" #'org-edit-special + "*" #'org-ctrl-c-star + "+" #'org-ctrl-c-minus "," #'org-switchb "." #'org-goto (:when (featurep! :completion ivy) @@ -588,7 +608,6 @@ between the two." "." #'helm-org-in-buffer-headings "/" #'helm-org-agenda-files-headings) "A" #'org-archive-subtree - "d" #'org-deadline "e" #'org-export-dispatch "f" #'org-footnote-new "h" #'org-toggle-heading @@ -598,7 +617,6 @@ between the two." "o" #'org-set-property "p" #'org-priority "q" #'org-set-tags-command - "s" #'org-schedule "t" #'org-todo "T" #'org-todo-list (:prefix ("a" . "attachments") @@ -621,24 +639,38 @@ between the two." (:prefix ("b" . "tables") "-" #'org-table-insert-hline "a" #'org-table-align + "b" #'org-table-blank-field "c" #'org-table-create-or-convert-from-region + "dc" #'org-table-delete-column + "dr" #'org-table-kill-row "e" #'org-table-edit-field + "f" #'org-table-edit-formulas "h" #'org-table-field-info + "s" #'org-table-sort-lines + "r" #'org-table-recalculate + "R" #'org-table-recalculate-buffer-tables (:when (featurep! +gnuplot) "p" #'org-plot/gnuplot)) (:prefix ("c" . "clock") - "c" #'org-clock-in - "C" #'org-clock-out + "c" #'org-clock-cancel "d" #'org-clock-mark-default-task "e" #'org-clock-modify-effort-estimate "E" #'org-set-effort - "l" #'org-clock-in-last "g" #'org-clock-goto "G" (λ! (org-clock-goto 'select)) - "r" #'org-clock-report - "x" #'org-clock-cancel + "i" #'org-clock-in + "I" #'org-clock-in-last + "o" #'org-clock-out + "r" #'org-resolve-clocks + "R" #'org-clock-report + "t" #'org-evaluate-time-range "=" #'org-clock-timestamps-up "-" #'org-clock-timestamps-down) + (:prefix ("d" . "date/deadline") + "d" #'org-deadline + "s" #'org-schedule + "t" #'org-time-stamp + "T" #'org-time-stamp-inactive) (:prefix ("g" . "goto") "g" #'org-goto (:when (featurep! :completion ivy) @@ -655,12 +687,13 @@ between the two." "x" #'org-capture-goto-last-stored) (:prefix ("l" . "links") "c" #'org-cliplink + "d" #'+org/remove-link + "i" #'org-id-store-link "l" #'org-insert-link "L" #'org-insert-all-links "s" #'org-store-link "S" #'org-insert-last-stored-link - "i" #'org-id-store-link - "d" #'+org/remove-link) + "t" #'org-toggle-link-display) (:prefix ("r" . "refile") "." #'+org/refile-to-current-file "c" #'+org/refile-to-running-clock @@ -778,7 +811,7 @@ compelling reason, so..." (use-package! org-crypt ; built-in - :commands org-encrypt-entries + :commands org-encrypt-entries org-encrypt-entry org-decrypt-entries org-decrypt-entry :hook (org-reveal-start . org-decrypt-entry) :config (add-hook! 'org-mode-hook @@ -811,40 +844,18 @@ compelling reason, so..." :commands org-pdftools-export :init (after! org - (add-hook 'org-store-link-functions #'org-pdftools-store-link) - - ;; HACK `org-pdftools' hard-codes "pdftools:" for its links. We want to use - ;; a generic link so that the backend doesn't matter. These hacks are - ;; in place so that the old pdf(view|tools) links still work, but that - ;; org-pdftools will only generate pdf: links. - (org-link-set-parameters "pdf" + (org-link-set-parameters (or (bound-and-true-p org-pdftools-link-prefix) "pdf") :follow #'org-pdftools-open :complete #'org-pdftools-complete-link :store #'org-pdftools-store-link :export #'org-pdftools-export) - (add-hook! 'org-open-link-functions - (defun +org-open-old-pdf-links-fn (link) + (defun +org-open-legacy-pdf-links-fn (link) + "Open pdftools:* and pdfviews:* links as if they were pdf:* links." (let ((regexp "^pdf\\(?:tools\\|view\\):")) (when (string-match-p regexp link) (org-pdftools-open (replace-regexp-in-string regexp "" link)) - t)))) - - ;; TODO Perhaps PR a variable for changing the link upstream? - (defadvice! +org--use-generic-link-a (link) - :filter-return '(org-pdftools-complete-link - org-pdftools-get-link) - (replace-regexp-in-string "^pdftools:" "pdf:" link)) - - (defadvice! +org--store-generic-link-a (orig-fn &rest args) - :around #'org-pdftools-store-link - (cl-letf* ((old-store-props (symbol-function #'org-link-store-props)) - ((symbol-function #'org-link-store-props) - (lambda (&rest plist) - (plist-put! plist :type "pdf") - (plist-put! plist :link (+org--use-generic-link-a (plist-get plist :link))) - (apply old-store-props plist)))) - (apply orig-fn args))))) + t)))))) (use-package! evil-org @@ -935,10 +946,12 @@ compelling reason, so..." org-list org-pcomplete org-src org-footnote org-macro ob org org-agenda org-capture :preface - ;; Change org defaults (should be set before org loads) - (setq org-directory "~/org/" - org-attach-id-dir ".attach/" - org-publish-timestamp-directory (concat doom-cache-dir "org-timestamps/") + ;; Set these to nil now so we can detect user changes to them later (and fall + ;; back on defaults otherwise) + (defvar org-directory nil) + (defvar org-attach-id-dir nil) + + (setq org-publish-timestamp-directory (concat doom-cache-dir "org-timestamps/") org-preview-latex-image-directory (concat doom-cache-dir "org-latex/")) ;; Make most of the default modules opt-in, because I sincerely doubt most @@ -965,6 +978,7 @@ compelling reason, so..." (if (featurep! +pomodoro) (load! "contrib/pomodoro")) (if (featurep! +present) (load! "contrib/present")) (if (featurep! +roam) (load! "contrib/roam")) + (if (featurep! +noter) (load! "contrib/noter")) ;; Add our general hooks after the submodules, so that any hooks the ;; submodules add run after them, and can overwrite any defaults if necessary. @@ -979,6 +993,7 @@ compelling reason, so..." #'+org-unfold-to-2nd-level-or-point-h) (add-hook! 'org-load-hook + #'+org-init-org-directory-h #'+org-init-appearance-h #'+org-init-agenda-h #'+org-init-attachments-h @@ -1012,7 +1027,6 @@ compelling reason, so..." ;; Global ID state means we can have ID links anywhere. This is required for ;; `org-brain', however. (setq org-id-track-globally t - org-id-locations-file (expand-file-name ".orgids" org-directory) org-id-locations-file-relative t) ;; HACK `org-id' doesn't check if `org-id-locations-file' exists or is diff --git a/modules/lang/org/contrib/dragndrop.el b/modules/lang/org/contrib/dragndrop.el index e845332aa..8d7b54699 100644 --- a/modules/lang/org/contrib/dragndrop.el +++ b/modules/lang/org/contrib/dragndrop.el @@ -16,61 +16,52 @@ (after! org ;; A shorter link to attachments - (+org-def-link "download" org-attach-id-dir) - (org-link-set-parameters "download" :image-data-fun #'+org-dragndrop-image-fn)) + (+org-define-basic-link "download" (lambda () (or org-download-image-dir org-attach-id-dir ".")) + :image-data-fun #'+org-image-file-data-fn + :requires 'org-download)) :config - (setq org-download-image-dir org-attach-id-dir - org-download-link-format "[[download:%s]]\n" - org-download-method 'attach - org-download-heading-lvl nil + (unless org-download-image-dir + (setq org-download-image-dir org-attach-id-dir)) + (setq org-download-method 'attach org-download-timestamp "_%Y%m%d_%H%M%S" org-download-screenshot-method (cond (IS-MAC "screencapture -i %s") (IS-LINUX (cond ((executable-find "maim") "maim -s %s") ((executable-find "scrot") "scrot -s %s") - ((executable-find "gnome-screenshot") "gnome-screenshot -a -f %s"))))) + ((executable-find "gnome-screenshot") "gnome-screenshot -a -f %s")))) - ;; Handle non-image files a little differently. Images should be inserted - ;; as-is, as image previews. Other files, like pdfs or zips, should be linked - ;; to, with an icon indicating the type of file. - (defadvice! +org--dragndrop-insert-link-a (_link filename) - "Produces and inserts a link to FILENAME into the document. + org-download-heading-lvl nil + org-download-link-format "[[download:%s]]\n" + org-download-annotate-function (lambda (_link) "") + org-download-link-format-function + (lambda (filename) + (if (eq org-download-method 'attach) + (format "[[attachment:%s]]\n" + (org-link-escape + (file-relative-name filename (org-attach-dir)))) + ;; Handle non-image files a little differently. Images should be + ;; inserted as normal with previews. Other files, like pdfs or zips, + ;; should be linked to, with an icon indicating the type of file. + (format (concat (unless (image-type-from-file-name filename) + (concat (+org-attach-icon-for filename) + " ")) + org-download-link-format) + (org-link-escape + (funcall org-download-abbreviate-filename-function filename))))) + org-download-abbreviate-filename-function + (lambda (path) + (if (file-in-directory-p path org-download-image-dir) + (file-relative-name path org-download-image-dir) + path))) -If FILENAME is an image, produce an attach:%s path, otherwise use file:%s (with -an file icon produced by `+org-attach-icon-for')." - :override #'org-download-insert-link - (if (looking-back "^[ \t]+" (line-beginning-position)) - (delete-region (match-beginning 0) (match-end 0)) - (newline)) - (cond ((image-type-from-file-name filename) - (insert - (concat - (if (= org-download-image-html-width 0) "" - (format "#+attr_html: :width %dpx\n" org-download-image-html-width)) - (if (= org-download-image-latex-width 0) "" - (format "#+attr_latex: :width %dcm\n" org-download-image-latex-width)) - (if (= org-download-image-org-width 0) "" - (format "#+attr_org: :width %dpx\n" org-download-image-org-width)) - (format org-download-link-format - (cond ((file-in-directory-p filename org-attach-id-dir) - (file-relative-name filename org-attach-id-dir)) - ((file-in-directory-p filename org-directory) - (file-relative-name filename org-directory)) - (filename))))) - (org-display-inline-images)) - ((insert - (format "%s [[./%s][%s]] " - (+org-attach-icon-for filename) - (file-relative-name filename (file-name-directory buffer-file-name)) - (file-name-nondirectory (directory-file-name filename))))))) - - (advice-add #'org-download--dir-2 :override #'ignore) - (defadvice! +org--dragndrop-download-fullname-a (path) - "Write PATH relative to current file." - :filter-return #'org-download--fullname - (let ((dir (or (if buffer-file-name (file-name-directory buffer-file-name)) - default-directory))) - (if (file-in-directory-p dir org-directory) - (file-relative-name path dir) - path)))) + (defadvice! +org--dragndrop-then-display-inline-images-a (_link filename) + :after #'org-download-insert-link + (when (image-type-from-file-name filename) + (save-excursion + (org-display-inline-images + t t + (progn (org-back-to-heading t) (point)) + (progn (org-end-of-subtree t t) + (when (and (org-at-heading-p) (not (eobp))) (backward-char 1)) + (point))))))) diff --git a/modules/lang/org/contrib/journal.el b/modules/lang/org/contrib/journal.el index 11ffacd3c..b2b551e16 100644 --- a/modules/lang/org/contrib/journal.el +++ b/modules/lang/org/contrib/journal.el @@ -29,6 +29,8 @@ (defun +org-journal-mode-maybe () "Activate `org-journal-mode', maybe." (and (eq major-mode 'org-mode) + (stringp buffer-file-name) + (stringp org-journal-file-pattern) (string-match-p org-journal-file-pattern buffer-file-name) (let ((org-mode-hook (remq '+org-journal-mode-maybe org-mode-hook))) (org-journal-mode)))) diff --git a/modules/lang/org/contrib/noter.el b/modules/lang/org/contrib/noter.el new file mode 100644 index 000000000..5702e1e0a --- /dev/null +++ b/modules/lang/org/contrib/noter.el @@ -0,0 +1,14 @@ +;;; lang/org/contrib/noter.el -*- lexical-binding: t; -*- +;;;###if (featurep! +noter) + +(use-package! org-noter + :defer t + :preface + ;; Allow the user to preempt this and set the document search path + ;; If not set then use `org-directory' + (defvar org-noter-notes-search-path nil) + :config + (setq org-noter-auto-save-last-location t + org-noter-separate-notes-from-heading t) + (unless org-noter-notes-search-path + (setq org-noter-notes-search-path org-directory))) diff --git a/modules/lang/org/contrib/roam.el b/modules/lang/org/contrib/roam.el index eea56ec8b..064f342d1 100644 --- a/modules/lang/org/contrib/roam.el +++ b/modules/lang/org/contrib/roam.el @@ -1,18 +1,25 @@ ;;; lang/org/contrib/roam.el -*- lexical-binding: t; -*- ;;;###if (featurep! +roam) +(defvar +org-roam-open-buffer-on-find-file t + "If non-nil, open the org-roam buffer when opening an org roam file.") + + +;; +;;; Packages + (use-package! org-roam :hook (org-load . org-roam-mode) :hook (org-roam-backlinks-mode . turn-on-visual-line-mode) :commands (org-roam-buffer-toggle-display - org-roam-date org-roam-find-file - org-roam-graph-show + org-roam-graph org-roam-insert org-roam-switch-to-buffer - org-roam-today - org-roam-tomorrow - org-roam-yesterday) + org-roam-dailies-date + org-roam-dailies-today + org-roam-dailies-tomorrow + org-roam-dailies-yesterday) :preface ;; Set this to nil so we can later detect whether the user has set a custom ;; directory for it, and default to `org-directory' if they haven't. @@ -24,30 +31,54 @@ :prefix ("m" . "org-roam") "b" #'org-roam-switch-to-buffer "f" #'org-roam-find-file - "g" #'org-roam-graph-show + "g" #'org-roam-graph "i" #'org-roam-insert "m" #'org-roam (:prefix ("d" . "by date") - :desc "Arbitrary date" "d" #'org-roam-date - :desc "Today" "t" #'org-roam-today - :desc "Tomorrow" "m" #'org-roam-tomorrow - :desc "Yesterday" "y" #'org-roam-yesterday)) + :desc "Arbitrary date" "d" #'org-roam-dailies-date + :desc "Today" "t" #'org-roam-dailies-today + :desc "Tomorrow" "m" #'org-roam-dailies-tomorrow + :desc "Yesterday" "y" #'org-roam-dailies-yesterday)) :config - (setq org-roam-directory (expand-file-name (or org-roam-directory "") + (setq org-roam-directory (expand-file-name (or org-roam-directory "roam") org-directory) org-roam-verbose nil ; https://youtu.be/fn4jIlFwuLU + org-roam-buffer-no-delete-other-windows t ; make org-roam buffer sticky org-roam-completion-system (cond ((featurep! :completion helm) 'helm) ((featurep! :completion ivy) 'ivy) ((featurep! :completion ido) 'ido) - ('default))) + ('default)) + org-roam-completion-fuzzy-match + (or (featurep! :completion helm +fuzzy) + (featurep! :completion ivy +fuzzy))) - ;; HACK Hide the mode line in the org-roam buffer, since it serves no purpose. - ;; This makes it easier to distinguish among other org buffers. - (defadvice! +org--hide-mode-line-a (&rest _) - :after #'org-roam-buffer--get-create - (with-current-buffer org-roam-buffer - (hide-mode-line-mode +1)))) + ;; HACK On first invocation, `org-roam-db-build-cache' builds the cache with a + ;; list of unresolved file paths. If those are symlinks, you will later + ;; end up with duplicate entries in your roam DB (e.g. after + ;; `org-roam-capture'ing to an existing file). + ;; REVIEW When jethrokuan/org-roam#518 is merged + (defadvice! +org-roam-resolve-symlinks-a (args) + :filter-args #'org-roam--list-files + (setcar args (file-truename (car args))) + args) + + ;; Normally, the org-roam buffer doesn't open until you explicitly call + ;; `org-roam'. If `+org-roam-open-buffer-on-find-file' is non-nil, the + ;; org-roam buffer will be opened for you when you use `org-roam-find-file' + ;; (but not `find-file', to limit the scope of this behavior). + (add-hook! 'find-file-hook + (defun +org-roam-open-buffer-maybe-h () + (and +org-roam-open-buffer-on-find-file + (memq 'org-roam-buffer--update-maybe post-command-hook) + (not (window-parameter nil 'window-side)) ; don't proc for popups + (not (eq 'visible (org-roam-buffer--visibility))) + (with-current-buffer (window-buffer) + (org-roam-buffer--get-create))))) + + ;; Hide the mode line in the org-roam buffer, since it serves no purpose. This + ;; makes it easier to distinguish among other org buffers. + (add-hook 'org-roam-buffer-prepare-hook #'hide-mode-line-mode)) ;; Since the org module lazy loads org-protocol (waits until an org URL is diff --git a/modules/lang/org/packages.el b/modules/lang/org/packages.el index f63159d6a..07fc7a7cf 100644 --- a/modules/lang/org/packages.el +++ b/modules/lang/org/packages.el @@ -27,14 +27,14 @@ :recipe (:host github :repo "emacs-straight/org-mode" :files ("*.el" "lisp/*.el" "contrib/lisp/*.el")) - :pin "9994e8ee89") + :pin "31068373dc") ;; ...And prevent other packages from pulling org; org-plus-contrib satisfies ;; the dependency already: https://github.com/raxod502/straight.el/issues/352 (package! org :recipe (:local-repo nil)) (package! avy) (package! htmlize :pin "86f22f211e") -(package! org-superstar :pin "4897c333a8") +(package! org-superstar :pin "09ddc28383") (package! org-yt :recipe (:host github :repo "TobiasZawada/org-yt") :pin "40cc1ac76d") @@ -45,13 +45,13 @@ (when (featurep! :editor evil +everywhere) (package! evil-org :recipe (:host github :repo "hlissner/evil-org-mode") - :pin "4d44e9bbdc")) + :pin "9cf661af8f")) (when (featurep! :tools pdf) - (package! org-pdftools :pin "4156b677fc")) + (package! org-pdftools :pin "8cc15bb801")) (when (featurep! :tools magit) - (package! orgit :pin "0242088fb2")) + (package! orgit :pin "e147f05577")) (when (featurep! +brain) - (package! org-brain :pin "3630eb88a3")) + (package! org-brain :pin "7ffbf6816a")) (when (featurep! +dragndrop) (package! org-download :pin "46417e2bd3")) (when (featurep! +gnuplot) @@ -60,9 +60,11 @@ (when (featurep! +ipython) ; DEPRECATED (package! ob-ipython :pin "7147455230")) (when (featurep! +jupyter) - (package! jupyter :pin "62ad054001")) + (package! jupyter :pin "785edbbff6")) (when (featurep! +journal) - (package! org-journal :pin "3fdb5b3036")) + (package! org-journal :pin "8bf06b28d6")) +(when (featurep! +noter) + (package! org-noter :pin "9ead81d42d")) (when (featurep! +pomodoro) (package! org-pomodoro :pin "aa07c11318")) (when (featurep! +present) @@ -72,7 +74,7 @@ (package! org-tree-slide :pin "7bf09a02bd") (package! org-re-reveal :pin "61549f4c00")) (when (featurep! +roam) - (package! org-roam :pin "e33c144298") + (package! org-roam :pin "963692f353") (when (featurep! :completion company) (package! company-org-roam :pin "0913d86f16"))) @@ -103,6 +105,6 @@ (when (featurep! +hugo) (package! ox-hugo :recipe (:host github :repo "kaushalmodi/ox-hugo" :nonrecursive t) - :pin "b6f4142de2")) + :pin "5106b430a1")) (when (featurep! :lang rst) (package! ox-rst :pin "9158bfd180")) diff --git a/modules/lang/python/README.org b/modules/lang/python/README.org index 228ae963e..ebb303ac2 100644 --- a/modules/lang/python/README.org +++ b/modules/lang/python/README.org @@ -25,6 +25,8 @@ Adds Python support to Doom Emacs. + ~+lsp~ Language Server Protocol support + ~+pyenv~ Python virtual environment support via [[https://github.com/pyenv/pyenv][pyenv]] + ~+conda~ Python virtual environment support via [[https://conda.io/en/latest/][Conda]] ++ ~+poetry~ Python packaging, dependency management, and virtual environment + support via [[https://python-poetry.org/][Poetry]] + ~+cython~ Cython files support via [[https://github.com/cython/cython/blob/master/Tools/cython-mode.el][Cython-mode]] ** Plugins @@ -41,6 +43,8 @@ Adds Python support to Doom Emacs. + [[https://github.com/necaris/conda.el][conda]]* + ~+pyenv~ + [[https://github.com/pythonic-emacs/pyenv-mode][pyenv]]* ++ ~+poetry~ + + [[https://github.com/galaunay/poetry.el][poetry]]* + ~+lsp~ and ~:tools lsp~ + [[https://github.com/emacs-lsp/lsp-mode][lsp]] + [[https://github.com/emacs-lsp/lsp-python-ms][lsp-python-ms]]* @@ -67,6 +71,7 @@ This module has no direct prerequisites. Here are some of its soft dependencies. + Python virtual environments install instructions at: + [[https://github.com/pyenv/pyenv][pyenv]] + [[https://conda.io/en/latest/][Conda]] + + [[https://python-poetry.org/][Poetry]] + ~pipenv~ requires [[https://pipenv.readthedocs.io/en/latest/][pipenv]] diff --git a/modules/lang/python/config.el b/modules/lang/python/config.el index 63a833029..8b3073e38 100644 --- a/modules/lang/python/config.el +++ b/modules/lang/python/config.el @@ -280,6 +280,11 @@ called.") 'append)) +(use-package! poetry + :when (featurep! +poetry) + :after python) + + (use-package! lsp-python-ms :when (featurep! +lsp) :after lsp-clients diff --git a/modules/lang/python/doctor.el b/modules/lang/python/doctor.el index e4979e5ea..588d3fb7a 100644 --- a/modules/lang/python/doctor.el +++ b/modules/lang/python/doctor.el @@ -20,6 +20,10 @@ (unless (executable-find "conda") (warn! "Couldn't find conda in your PATH"))) +(when (featurep! +poetry) + (if (not (executable-find "poetry")) + (warn! "Couldn't find poetry in your PATH"))) + (when (featurep! +cython) (unless (executable-find "cython") (warn! "Couldn't find cython. cython-mode will not work."))) diff --git a/modules/lang/python/packages.el b/modules/lang/python/packages.el index ee838e6fd..4788487d6 100644 --- a/modules/lang/python/packages.el +++ b/modules/lang/python/packages.el @@ -24,6 +24,8 @@ (package! pyenv-mode :pin "aec6f2aa28")) (when (featurep! +conda) (package! conda :pin "335474e409")) +(when (featurep! +poetry) + (package! poetry :pin "6dcc9d22ca")) ;; Testing frameworks (package! nose :pin "f852829751") diff --git a/modules/lang/racket/config.el b/modules/lang/racket/config.el index f3727842b..c297b076c 100644 --- a/modules/lang/racket/config.el +++ b/modules/lang/racket/config.el @@ -13,8 +13,8 @@ :config (set-repl-handler! 'racket-mode #'+racket/open-repl) (set-lookup-handlers! 'racket-mode - :definition #'racket-visit-definition - :documentation #'racket-describe) + :definition #'racket-xp-visit-definition + :documentation #'racket-xp-describe) (set-docsets! 'racket-mode "Racket") (set-pretty-symbols! 'racket-mode :lambda "lambda" diff --git a/modules/lang/racket/packages.el b/modules/lang/racket/packages.el index 4288f361a..341191184 100644 --- a/modules/lang/racket/packages.el +++ b/modules/lang/racket/packages.el @@ -1,4 +1,4 @@ ;; -*- no-byte-compile: t; -*- ;;; lang/racket/packages.el -(package! racket-mode :pin "bd4c8cf3ce") +(package! racket-mode :pin "202cc1b784") diff --git a/modules/lang/scheme/autoload.el b/modules/lang/scheme/autoload.el index 91729cb0b..464129d81 100644 --- a/modules/lang/scheme/autoload.el +++ b/modules/lang/scheme/autoload.el @@ -1,5 +1,50 @@ ;;; lang/scheme/autoload.el -*- lexical-binding: t; -*- +(defvar calculate-lisp-indent-last-sexp) + +;; Adapted from https://github.com/alezost/emacs-config/blob/master/utils/al-scheme.el#L76-L123 +;;;###autoload +(defun +scheme-scheme-indent-function-a (indent-point state) + "Advice to replace `scheme-indent-function'. + +This function is the same as `scheme-indent-function' except it indents property +lists properly and names starting with 'default'." + (let ((normal-indent (current-column))) + (goto-char (1+ (elt state 1))) + (parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t) + (if (and (elt state 2) + ;; NOTE looking-at -> looking-at-p + (not (looking-at-p "\\sw\\|\\s_"))) + (unless (> (save-excursion (forward-line 1) (point)) + calculate-lisp-indent-last-sexp) + (goto-char calculate-lisp-indent-last-sexp) + (beginning-of-line) + (parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t)) + (backward-prefix-chars) + (current-column) + (let* ((function (buffer-substring + (point) (progn (forward-sexp 1) (point)))) + (method (or (get (intern-soft function) 'scheme-indent-function) + (get (intern-soft function) 'scheme-indent-hook)))) + (cond ((or (eq method 'defun) + (and (null method) + (> (length function) 3) + ;; NOTE string-match -> string-match-p + ;; NOTE The original regexp is "\\`def" but it will mess + ;; indentation with such names as 'default-...'. + (string-match-p "\\`define" function))) + (lisp-indent-defform state indent-point)) + ;; NOTE Added this clause to handle alignment of keyword symbols + ((and (null method) + (> (length function) 1) + (string-match-p "\\`:" function)) + (let ((lisp-body-indent 1)) + (lisp-indent-defform state indent-point))) + ((integerp method) + (lisp-indent-specform method state indent-point normal-indent)) + (method + (funcall method state indent-point normal-indent))))))) + ;;;###autoload (defun +scheme/open-repl (&optional arg) "Open the Scheme REPL." diff --git a/modules/lang/scheme/config.el b/modules/lang/scheme/config.el index 67e5bfd6a..995868f96 100644 --- a/modules/lang/scheme/config.el +++ b/modules/lang/scheme/config.el @@ -1,17 +1,20 @@ ;;; lang/scheme/config.el -*- lexical-binding: t; -*- -;;;###package scheme -(add-hook 'scheme-mode-hook #'rainbow-delimiters-mode) +(use-package! scheme + :hook (scheme-mode . rainbow-delimiters-mode) + :config (advice-add #'scheme-indent-function :override #'+scheme-scheme-indent-function-a)) (use-package! geiser - :defer t + :hook (scheme-mode . geiser-mode) :init - (setq geiser-active-implementations '(guile chicken mit chibi chez)) + (setq geiser-active-implementations '(guile chicken mit chibi chez) + geiser-mode-start-repl-p t + geiser-smart-tab-p t) (unless (featurep! :lang racket) (push 'racket geiser-active-implementations)) - (after! scheme ; built-in - (set-repl-handler! 'scheme-mode '+scheme/open-repl) + (after! scheme ; built-in + (set-repl-handler! 'scheme-mode #'+scheme/open-repl) (set-eval-handler! 'scheme-mode #'geiser-eval-region) (set-lookup-handlers! 'scheme-mode :definition #'geiser-edit-symbol-at-point @@ -22,24 +25,32 @@ ( "\\* [A-Za-z0-9_-]+ REPL \\*" :quit nil))) (map! :localleader :map scheme-mode-map - "'" #'geiser-mode-switch-to-repl - "s" #'geiser-set-scheme - + "'" #'geiser-mode-switch-to-repl + "\"" #'geiser-connect + "[" #'geiser-squarify + "\\" #'geiser-insert-lambda + "s" #'geiser-set-scheme (:prefix ("e" . "eval") "b" #'geiser-eval-buffer "B" #'geiser-eval-buffer-and-go - "e" #'geiser-eval-definition - "E" #'geiser-eval-definition-and-go + "e" #'geiser-eval-last-sexp + "d" #'geiser-eval-definition + "D" #'geiser-eval-definition-and-go "r" #'geiser-eval-region "R" #'geiser-eval-region-and-go) - (:prefix ("h" . "help") - "d" 'geiser-autodoc) - ;; TODO add more help keybindings - + "d" #'geiser-autodoc + "<" #'geiser-xref-callers + ">" #'geiser-xref-callees + "i" #'geiser-doc-look-up-manual) + (:prefix ("m" . "macro") + "r" #'geiser-expand-region + "d" #'geiser-expand-definition + "e" #'geiser-expand-last-sexp) (:prefix ("r" . "repl") "b" #'geiser-switch-to-repl "q" #'geiser-repl-exit + "l" #'geiser-load-current-buffer "r" #'geiser-restart-repl "R" #'geiser-reload "c" #'geiser-repl-clear-buffer))) diff --git a/modules/lang/web/+html.el b/modules/lang/web/+html.el index 345521889..150b5a655 100644 --- a/modules/lang/web/+html.el +++ b/modules/lang/web/+html.el @@ -12,7 +12,7 @@ :mode "\\.svelte\\'" :mode "\\.vue\\'" :mode "\\.twig\\'" - :mode "\\.jinja\\'" + :mode "\\.jinja2?\\'" :mode "wp-content/themes/.+/.+\\.php\\'" :mode "templates/.+\\.php\\'" ;; REVIEW We associate TSX files with `web-mode' because `typescript-mode' diff --git a/modules/lang/web/config.el b/modules/lang/web/config.el index ea094a792..a1dccab9b 100644 --- a/modules/lang/web/config.el +++ b/modules/lang/web/config.el @@ -14,8 +14,8 @@ (setq-hook! 'rjsx-mode-hook emmet-expand-jsx-className? t) (map! :map emmet-mode-keymap :v [tab] #'emmet-wrap-with-markup - :i [tab] #'+web/indent-or-yas-or-emmet-expand - :i "M-E" #'emmet-expand-line)) + [tab] #'+web/indent-or-yas-or-emmet-expand + "M-E" #'emmet-expand-line)) ;; diff --git a/modules/lang/yaml/README.org b/modules/lang/yaml/README.org new file mode 100644 index 000000000..f036f5a24 --- /dev/null +++ b/modules/lang/yaml/README.org @@ -0,0 +1,38 @@ +#+TITLE: lang/yaml +#+DATE: April 23, 2020 +#+SINCE: v3.0.0 +#+STARTUP: inlineimages nofold + +* Table of Contents :TOC_3:noexport: +- [[#description][Description]] + - [[#maintainers][Maintainers]] + - [[#module-flags][Module Flags]] + - [[#plugins][Plugins]] +- [[#prerequisites][Prerequisites]] +- [[#features][Features]] +- [[#configuration][Configuration]] +- [[#troubleshooting][Troubleshooting]] + +* Description +This module provides support for the [[https://yaml.org/][YAML file format]]. + +** Maintainers +This module has no dedicated maintainers. + +** Module Flags ++ =+lsp= Enables integration with LSP servers. Requires the =:tools lsp= module to be enabled. + +** Plugins ++ [[https://github.com/yoshiki/yaml-mode][yaml-mode]] + +* Prerequisites +This module has no prereqisites. + +* TODO Features +# An in-depth list of features, how to use them, and their dependencies. + +* TODO Configuration +# How to configure this module, including common problems and how to address them. + +* TODO Troubleshooting +# Common issues and their solution, or places to look for help. diff --git a/modules/lang/yaml/config.el b/modules/lang/yaml/config.el new file mode 100644 index 000000000..f9f081b57 --- /dev/null +++ b/modules/lang/yaml/config.el @@ -0,0 +1,9 @@ +;;; lang/yaml/config.el -*- lexical-binding: t; -*- + +(use-package! yaml-mode + :mode "Procfile\\'" + :init + (when (featurep! +lsp) + (add-hook 'yaml-mode-local-vars-hook #'lsp!)) + :config + (setq-hook! 'yaml-mode-hook tab-width yaml-indent-offset)) diff --git a/modules/lang/yaml/packages.el b/modules/lang/yaml/packages.el new file mode 100644 index 000000000..6e0f161f3 --- /dev/null +++ b/modules/lang/yaml/packages.el @@ -0,0 +1,4 @@ +;; -*- no-byte-compile: t; -*- +;;; lang/yaml/packages.el + +(package! yaml-mode :pin "cecf4b106b") diff --git a/modules/term/eshell/autoload/evil.el b/modules/term/eshell/autoload/evil.el index a3326e322..04e45d377 100644 --- a/modules/term/eshell/autoload/evil.el +++ b/modules/term/eshell/autoload/evil.el @@ -6,7 +6,7 @@ "TODO" (interactive "") (let ((buffer (+eshell-last-buffer)) - (command (+evil-resolve-vim-path-a command))) + (command (+evil-replace-filename-modifiers-a command))) (cond (buffer (select-window (get-buffer-window buffer)) (+eshell-run-command command buffer)) diff --git a/modules/term/eshell/config.el b/modules/term/eshell/config.el index 0b923faff..51afe2b15 100644 --- a/modules/term/eshell/config.el +++ b/modules/term/eshell/config.el @@ -48,7 +48,7 @@ You should use `set-eshell-alias!' to change this.") ;; -;; Packages +;;; Packages (after! eshell ; built-in (setq eshell-banner-message diff --git a/modules/term/vterm/README.org b/modules/term/vterm/README.org index 2eab1af61..019fc5882 100644 --- a/modules/term/vterm/README.org +++ b/modules/term/vterm/README.org @@ -88,6 +88,13 @@ There are several ways to manually install the module: 1. You can use =M-x vterm-module-compile= to let emacs automatically compile and install the module. + Modify ~vterm-module-cmake-args~ to pass arguments to the cmake build script. + e.g. To use a local build of libvterm instead of the included one. + + #+BEGIN_SRC elisp + (setq vterm-module-cmake-args "-DUSE_SYSTEM_LIBVTERM=yes") + #+END_SRC + *WARNING*: Emacs will hang during the compilation. It may take a while. 2. You can compile and install the module yourself. Go to the vterm installation diff --git a/modules/term/vterm/config.el b/modules/term/vterm/config.el index 18938206c..e21b7a60a 100644 --- a/modules/term/vterm/config.el +++ b/modules/term/vterm/config.el @@ -2,25 +2,26 @@ (use-package! vterm :when (bound-and-true-p module-file-suffix) - :commands (vterm vterm-mode) - :preface (setq vterm-install t) + :commands vterm vterm-mode + :preface (setq vterm-install t) ; compile the package when you load vterm + :hook (vterm-mode . doom-mark-buffer-as-real-h) + :hook (vterm-mode . hide-mode-line-mode) ; modeline serves no purpose in vterm :config (set-popup-rule! "^vterm" :size 0.25 :vslot -4 :select t :quit nil :ttl 0) + ;; Once vterm is dead, the vterm buffer is useless. Why keep it around? We can + ;; spawn another if want one. + (setq vterm-kill-buffer-on-exit t) + (setq-hook! 'vterm-mode-hook - ;; Don't prompt about processes when killing vterm + ;; Don't prompt about dying processes when killing vterm confirm-kill-processes nil ;; Prevent premature horizontal scrolling hscroll-margin 0) - (setq vterm-kill-buffer-on-exit t) - + ;; Restore the point's location when leaving and re-entering insert mode. (when (featurep! :editor evil) (add-hook! 'vterm-mode-hook (defun +vterm-init-remember-point-h () (add-hook 'evil-insert-state-exit-hook #'+vterm-remember-insert-point-h nil t) - (add-hook 'evil-insert-state-entry-hook #'+vterm-goto-insert-point-h nil t)))) - - (add-hook 'vterm-mode-hook #'doom-mark-buffer-as-real-h) - ;; Modeline serves no purpose in vterm - (add-hook 'vterm-mode-hook #'hide-mode-line-mode)) + (add-hook 'evil-insert-state-entry-hook #'+vterm-goto-insert-point-h nil t))))) diff --git a/modules/term/vterm/packages.el b/modules/term/vterm/packages.el index 3c0e59afa..de92a1673 100644 --- a/modules/term/vterm/packages.el +++ b/modules/term/vterm/packages.el @@ -3,4 +3,4 @@ (package! vterm :built-in 'prefer - :pin "996c535b9c") + :pin "aa512b8351") diff --git a/modules/tools/debugger/config.el b/modules/tools/debugger/config.el index 4ceb75c96..f86585fdf 100644 --- a/modules/tools/debugger/config.el +++ b/modules/tools/debugger/config.el @@ -25,36 +25,6 @@ gdb-many-windows t) -(use-package! dap-mode - :when (featurep! :tools lsp) - :after lsp-mode - :preface - (add-hook 'dap-mode-hook #'dap-ui-mode) ; use a hook so users can remove it - (setq dap-breakpoints-file (concat doom-etc-dir "dap-breakpoints") - dap-utils-extension-path (concat doom-etc-dir "dap-extension/")) - :config - (dap-mode 1) - (dolist (module '(((:lang . cc) ccls dap-lldb dap-gdb-lldb) - ((:lang . elixir) elixir-mode dap-elixir) - ((:lang . go) go-mode dap-go) - ((:lang . java) lsp-java dap-java) - ((:lang . php) php-mode dap-php) - ((:lang . python) python dap-python) - ((:lang . ruby) ruby-mode dap-ruby) - ((:lang . rust) rust-mode dap-lldb))) - (when (doom-module-p (caar module) (cdar module) '+lsp) - (with-eval-after-load (nth 1 module) - (mapc #'require (cddr module))))) - - (when (featurep! :lang javascript +lsp) - (with-eval-after-load 'js2-mode - (require 'dap-node) - (require 'dap-chrome) - (require 'dap-firefox) - (when IS-WINDOWS - (require 'dap-edge))))) - - (use-package! realgud :defer t :init @@ -116,3 +86,41 @@ (if cmd-buf (switch-to-buffer cmd-buf)) (message "Error running command: %s" (mapconcat #'identity cmd-args " ")))) cmd-buf))) + + +(use-package! dap-mode + :when (featurep! +lsp) + :hook (dap-mode . dap-tooltip-mode) + :after lsp-mode + :demand t + :preface + (setq dap-breakpoints-file (concat doom-etc-dir "dap-breakpoints") + dap-utils-extension-path (concat doom-etc-dir "dap-extension/")) + :config + (dolist (module '(((:lang . cc) ccls dap-lldb dap-gdb-lldb) + ((:lang . elixir) elixir-mode dap-elixir) + ((:lang . go) go-mode dap-go) + ((:lang . java) lsp-java dap-java) + ((:lang . php) php-mode dap-php) + ((:lang . python) python dap-python) + ((:lang . ruby) ruby-mode dap-ruby) + ((:lang . rust) rust-mode dap-lldb))) + (when (doom-module-p (caar module) (cdar module) '+lsp) + (with-eval-after-load (nth 1 module) + (mapc #'require (cddr module))))) + + (when (featurep! :lang javascript +lsp) + (with-eval-after-load 'js2-mode + (require 'dap-node) + (require 'dap-chrome) + (require 'dap-firefox) + (when IS-WINDOWS + (require 'dap-edge)))) + + (dap-mode 1)) + + +(use-package! dap-ui-mode + :when (featurep! +lsp) + :hook (dap-mode . dap-ui-mode) + :hook (dap-ui-mode . dap-ui-controls-mode)) diff --git a/modules/tools/debugger/packages.el b/modules/tools/debugger/packages.el index 139f8006b..9321e25fb 100644 --- a/modules/tools/debugger/packages.el +++ b/modules/tools/debugger/packages.el @@ -1,9 +1,10 @@ ;; -*- no-byte-compile: t; -*- ;;; tools/debugger/packages.el -(when (package! realgud :pin "94f2835933") +(when (package! realgud :pin "b854e040e0") (when (featurep! :lang javascript) (package! realgud-trepan-ni :pin "6e9cac5e80"))) -(when (featurep! :tools lsp) - (package! dap-mode :pin "e2086fc9fb")) +(when (featurep! +lsp) + (package! dap-mode :pin "0b9c8f28ad") + (package! posframe :pin "e62e584268")) diff --git a/modules/tools/ein/packages.el b/modules/tools/ein/packages.el index 811588307..0e53a4f1d 100644 --- a/modules/tools/ein/packages.el +++ b/modules/tools/ein/packages.el @@ -1,4 +1,4 @@ ;; -*- no-byte-compile: t; -*- ;;; tools/ein/packages.el -(package! ein :pin "c0147f63c7") +(package! ein :pin "1322d8c7f8") diff --git a/modules/tools/lookup/README.org b/modules/tools/lookup/README.org index b69d6b25e..5c51aeb78 100644 --- a/modules/tools/lookup/README.org +++ b/modules/tools/lookup/README.org @@ -25,13 +25,14 @@ - [[#commands][Commands]] * Description -Integrates with code navigation and documentation tools to help you quickly look -up definitions, references and documentation. +This module adds code navigation and documentation lookup tools to help you +quickly look up definitions, references, documentation, dictionary definitions +or synonyms. + Jump-to-definition and find-references implementations that just work. + Powerful xref integration for languages that support it. -+ Documentation lookup for a variety of online sources (like devdocs.io, - stackoverflow or youtube). ++ Search online providers like devdocs.io, stackoverflow, google, duckduckgo or + youtube (duckduckgo and google have live suggestions). + Integration with Dash.app docsets. + Support for online (and offline) dictionaries and thesauruses. @@ -43,14 +44,27 @@ up definitions, references and documentation. ** Plugins + [[https://github.com/jacktasia/dumb-jump][dumb-jump]] + [[https://github.com/alexmurray/ivy-xref][ivy-xref]] or [[https://github.com/brotzeit/helm-xref][helm-xref]] -+ [[https://github.com/nathankot/counsel-dash][counsel-dash]] or [[https://github.com/areina/helm-dash][helm-dash]] ++ [[https://github.com/tkf/emacs-request][request]] ++ =+docsets= + + [[https://github.com/dash-docs-el/dash-docs][dash-docs]] + + [[https://github.com/nathankot/counsel-dash][counsel-dash]] or [[https://github.com/areina/helm-dash][helm-dash]] ++ =+dictionary= + + if macOS + + [[https://github.com/xuchunyang/osx-dictionary.el][osx-dictionary]]* (on macOS) + + else + + [[https://github.com/abo-abo/define-word][define-word]] + + [[https://github.com/maxchaos/emacs-powerthesaurus][powerthesaurus]] + + =+offline= + + [[https://github.com/gromnitsky/wordnut][wordnut]] + + [[https://github.com/hpdeifel/synosaurus][synosaurus]] * Prerequisites This module has several soft dependencies: + ~ripgrep~ as a last-resort fallback for jump-to-definition/find-references. -+ ~sqlite3~ for Dash docset support. -+ ~wordnet~ for offline dictionary and thesaurus support. ++ ~sqlite3~ for Dash docset support (if you have =+docsets= enabled) ++ ~wordnet~ for offline dictionary and thesaurus support (if you have + =+dictionary +offline= enabled). ** MacOS #+BEGIN_SRC sh diff --git a/modules/tools/lookup/config.el b/modules/tools/lookup/config.el index 35179e360..6381956a2 100644 --- a/modules/tools/lookup/config.el +++ b/modules/tools/lookup/config.el @@ -104,6 +104,7 @@ Dictionary.app behind the scenes to get definitions.") :commands dumb-jump-result-follow :config (setq dumb-jump-default-project doom-emacs-dir + dumb-jump-prefer-searcher 'rg dumb-jump-aggressive nil dumb-jump-selector (cond ((featurep! :completion ivy) 'ivy) @@ -136,12 +137,17 @@ Dictionary.app behind the scenes to get definitions.") (use-package! ivy-xref :when (featurep! :completion ivy) :config - (setq xref-show-xrefs-function #'ivy-xref-show-xrefs) - (set-popup-rule! "^\\*xref\\*$" :ignore t)) + (set-popup-rule! "^\\*xref\\*$" :ignore t) + ;; xref initialization is different in Emacs 27 - there are two different + ;; variables which can be set rather than just one + (when EMACS27+ + (setq xref-show-definitions-function #'ivy-xref-show-defs)) + ;; Necessary in Emacs <27. In Emacs 27 it will affect all xref-based + ;; commands other than xref-find-definitions too (eg project-find-regexp) + (setq xref-show-xrefs-function #'ivy-xref-show-xrefs)) (use-package! helm-xref - :when (featurep! :completion helm) - :config (setq xref-show-xrefs-function (if EMACS27+ #'helm-xref-show-xrefs-27 #'helm-xref-show-xrefs)))) + :when (featurep! :completion helm))) ;; @@ -172,11 +178,10 @@ See https://github.com/magit/ghub/issues/81" (let ((gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3")) (funcall orig-fn url))) - (use-package! helm-dash - :when (featurep! :completion helm)) - - (use-package! counsel-dash - :when (featurep! :completion ivy))) + (cond ((featurep! :completion helm) + (require 'helm-dash nil t)) + ((featurep! :completion ivy) + (require 'counsel-dash nil t)))) ;; diff --git a/modules/tools/lookup/packages.el b/modules/tools/lookup/packages.el index 7b7ecf701..0206f4c1f 100644 --- a/modules/tools/lookup/packages.el +++ b/modules/tools/lookup/packages.el @@ -8,7 +8,7 @@ (package! helm)) ;; -(package! dumb-jump :pin "e8e9b0c2d1") +(package! dumb-jump :pin "d760aa880f") (when (featurep! :completion ivy) (package! ivy-xref :pin "3d4c35fe2b")) (when (featurep! :completion helm) @@ -27,8 +27,13 @@ (when (featurep! +dictionary) (if IS-MAC (package! osx-dictionary :pin "1b79ff64c7") - (package! define-word :pin "d8c76d503b") - (package! powerthesaurus :pin "81a262ec0c") + (package! define-word :pin "08c71b1ff4") + ;; HACK Fix #2945: the main package is broken (see + ;; SavchenkoValeriy/emacs-powerthesaurus). We use this fork until it is + ;; merged. + (package! powerthesaurus + :recipe (:host github :repo "maxchaos/emacs-powerthesaurus" :branch "pt-api-change") + :pin "81a262ec0c") (when (featurep! +offline) (package! wordnut :pin "feac531404") (package! synosaurus :pin "14d34fc92a")))) diff --git a/modules/tools/lsp/config.el b/modules/tools/lsp/config.el index 888c9c6fe..3c4aabfaf 100644 --- a/modules/tools/lsp/config.el +++ b/modules/tools/lsp/config.el @@ -213,6 +213,39 @@ auto-killed (which is a potentially expensive process)." :references 'lsp-ui-peek-find-references))) +(use-package! company-lsp + :defer t + :config + (setq company-lsp-cache-candidates 'auto) + ;; HACK Fix tigersoldier/company-lsp#128 causing company-lsp results to + ;; display candidates that are unrelated to the prefix. Source: + ;; emacs-lsp/lsp-python-ms#79 + (add-to-list 'company-lsp-filter-candidates '(mspyls . t)) + (defadvice! +company---fix-lsp-caching-on-competion-a (response prefix) + :override #'company-lsp--on-completion + (let* ((incomplete (and (hash-table-p response) (gethash "isIncomplete" response))) + (items (cond ((hash-table-p response) (gethash "items" response)) + ((sequencep response) response))) + (candidates (mapcar (lambda (item) + (company-lsp--make-candidate item prefix)) + (lsp--sort-completions items))) + (server-id (lsp--client-server-id (lsp--workspace-client lsp--cur-workspace))) + (should-filter (or + ;; CHANGE BEGIN + (eq company-lsp-cache-candidates t) + ;; CHANGE END + (and (null company-lsp-cache-candidates) + (company-lsp--get-config company-lsp-filter-candidates server-id))))) + (when (null company-lsp--completion-cache) + (add-hook 'company-completion-cancelled-hook #'company-lsp--cleanup-cache nil t) + (add-hook 'company-completion-finished-hook #'company-lsp--cleanup-cache nil t)) + (when (eq company-lsp-cache-candidates 'auto) + (company-lsp--cache-put prefix (company-lsp--cache-item-new candidates incomplete))) + (if should-filter + (company-lsp--filter-candidates candidates prefix) + candidates)))) + + (use-package! helm-lsp :when (featurep! :completion helm) :commands helm-lsp-workspace-symbol helm-lsp-global-workspace-symbol) diff --git a/modules/tools/lsp/packages.el b/modules/tools/lsp/packages.el index ef113251a..29c0649a0 100644 --- a/modules/tools/lsp/packages.el +++ b/modules/tools/lsp/packages.el @@ -1,11 +1,11 @@ ;; -*- no-byte-compile: t; -*- ;;; tools/lsp/packages.el -(package! lsp-mode :pin "6671128422") +(package! lsp-mode :pin "4898d35ace") (package! lsp-ui :pin "242dfe859c") (when (featurep! :completion company) (package! company-lsp :pin "f921ffa0cd")) (when (featurep! :completion ivy) - (package! lsp-ivy :pin "a6b7841e08")) + (package! lsp-ivy :pin "81e81ced99")) (when (featurep! :completion helm) - (package! helm-lsp :pin "46a72f5af1")) + (package! helm-lsp :pin "db243993ea")) diff --git a/modules/tools/magit/README.org b/modules/tools/magit/README.org new file mode 100644 index 000000000..2be927280 --- /dev/null +++ b/modules/tools/magit/README.org @@ -0,0 +1,60 @@ +#+TITLE: tools/magit +#+DATE: March 14, 2018 +#+SINCE: v2.0.0 +#+STARTUP: inlineimages nofold + +* Table of Contents :TOC_3:noexport: +- [[#description][Description]] + - [[#maintainers][Maintainers]] + - [[#module-flags][Module Flags]] + - [[#plugins][Plugins]] + - [[#hacks][Hacks]] +- [[#prerequisites][Prerequisites]] +- [[#features][Features]] +- [[#configuration][Configuration]] +- [[#troubleshooting][Troubleshooting]] + +* Description +This module provides Magit, an interface to the Git version control system. + +If you are new to Magit, see the [[https://github.com/magit/magit#getting-started][Getting Started]] section of its project readme. + +** Maintainers +This module has no dedicated maintainers. + +** Module Flags ++ =+forge= Enable Forge; a porcelain for managing issues and PRs from within + Emacs. Will take a while on first run to build emacsql-sqlite. + +** Plugins ++ [[https://github.com/magit/magit][magit]] ++ [[https://github.com/magit/forge][forge]]* (=+forge=) ++ [[https://github.com/jtatarik/magit-gitflow][magit-gitflow]] ++ [[https://github.com/alphapapa/magit-todos][magit-todos]] ++ [[https://github.com/charignon/github-review][github-review]] ++ [[https://github.com/emacs-evil/evil-magit][evil-magit]]* (=:editor evil +everywhere=) + +** Hacks ++ =forge= was modified to defer compilation of emacsql-sqlite until you try to + use forge, rather than when magit first loads (which could be as soon as + startup). ++ =magit= has been modified to recognize + =$XDG_CACHE_HOME/git/credential/socket=. ++ =magit= has been modified to invalidate the projectile cache when you check + out a new branch or commit. ++ =magit= has been modified to revert repo buffers (e.g. after changing + branches) when you later switch to them, rather than all at once. + +* Prerequisites +This module requires ~git~. + +Forge will require [[https://magit.vc/manual/forge/Token-Creation.html#Token-Creation][a Github API token]] the first time you run =forge-pull=. + +* TODO Features +# An in-depth list of features, how to use them, and their dependencies. + +* TODO Configuration +# How to configure this module, including common problems and how to address them. + +* TODO Troubleshooting +# Common issues and their solution, or places to look for help. diff --git a/modules/tools/magit/config.el b/modules/tools/magit/config.el index 9bb3d8767..ce2c785f2 100644 --- a/modules/tools/magit/config.el +++ b/modules/tools/magit/config.el @@ -1,8 +1,5 @@ ;;; tools/magit/config.el -*- lexical-binding: t; -*- -;; -;;; Packages - (use-package! magit :commands magit-file-delete :defer-incrementally (dash f s with-editor git-commit package eieio lv transient) @@ -92,11 +89,12 @@ (use-package! forge + :when (featurep! +forge) ;; We defer loading even further because forge's dependencies will try to ;; compile emacsql, which is a slow and blocking operation. :after-call magit-status :commands forge-create-pullreq forge-create-issue - :init + :preface (setq forge-database-file (concat doom-etc-dir "forge/forge-database.sqlite")) :config ;; All forge list modes are derived from `forge-topic-list-mode' @@ -123,8 +121,8 @@ ensure it is built when we actually use Forge." (message (concat "Failed to build emacsql; forge may not work correctly.\n" "See *Compile-Log* buffer for details")) ;; HACK Due to changes upstream, forge doesn't initialize completely if - ;; it doesn't find `emacsql-sqlite-executable', so we have to do it - ;; manually after installing it. + ;; it doesn't find `emacsql-sqlite-executable', so we have to do it + ;; manually after installing it. (setq forge--sqlite-available-p t) (magit-add-section-hook 'magit-status-sections-hook 'forge-insert-pullreqs nil t) (magit-add-section-hook 'magit-status-sections-hook 'forge-insert-issues nil t) @@ -164,7 +162,7 @@ ensure it is built when we actually use Forge." (setq evil-magit-state 'normal evil-magit-use-z-for-folds t) :config - (unmap! magit-mode-map + (undefine-key! magit-mode-map ;; Replaced by z1, z2, z3, etc "M-1" "M-2" "M-3" "M-4" "1" "2" "3" "4" diff --git a/modules/tools/magit/packages.el b/modules/tools/magit/packages.el index de80bc93d..97ac695ce 100644 --- a/modules/tools/magit/packages.el +++ b/modules/tools/magit/packages.el @@ -1,8 +1,9 @@ ;; -*- no-byte-compile: t; -*- ;;; tools/magit/packages.el -(when (package! magit :pin "0f1234e785") - (package! forge :pin "2e2d26cf42") +(when (package! magit :pin "8de6ecf5c5") + (when (featurep! +forge) + (package! forge :pin "e2da80660a")) (package! magit-gitflow :pin "cc41b561ec") (package! magit-todos :pin "a0e5d1f3c7") (package! github-review :pin "50c6bcc7cf") diff --git a/modules/tools/pdf/config.el b/modules/tools/pdf/config.el index a5047ec41..99956fdea 100644 --- a/modules/tools/pdf/config.el +++ b/modules/tools/pdf/config.el @@ -1,6 +1,6 @@ ;;; tools/pdf/config.el -*- lexical-binding: t; -*- -(use-package! pdf-tools +(use-package! pdf-view :mode ("\\.[pP][dD][fF]\\'" . pdf-view-mode) :magic ("%PDF" . pdf-view-mode) :init @@ -20,9 +20,10 @@ :config (map! :map pdf-view-mode-map :gn "q" #'kill-current-buffer) - (setq-default pdf-view-display-size 'fit-page - pdf-view-use-scaling t - pdf-view-use-imagemagick nil) + (setq-default pdf-view-display-size 'fit-page) + ;; Enable hiDPI support, but at the cost of memory! See politza/pdf-tools#51 + (setq pdf-view-use-scaling t + pdf-view-use-imagemagick nil) ;; Add retina support for MacOS users (when IS-MAC @@ -52,6 +53,7 @@ (setq-hook! 'pdf-view-mode-hook evil-normal-state-cursor (list nil)) ;; Install epdfinfo binary if needed, blocking until it is finished + (require 'pdf-tools) (unless (file-executable-p pdf-info-epdfinfo-program) (let ((wconf (current-window-configuration))) (pdf-tools-install) diff --git a/modules/tools/tmux/autoload/tmux.el b/modules/tools/tmux/autoload/tmux.el index 63f51156e..46e066318 100644 --- a/modules/tools/tmux/autoload/tmux.el +++ b/modules/tools/tmux/autoload/tmux.el @@ -104,7 +104,7 @@ but do not execute them." (if-let* ((lines (+tmux (format "list-windows %s -F '#{window_id};#{session_id};#{window_active};#{window_name};#{window_activity_flag}'" (if session - (concat "-t " (car session)) + (concat "-t " (shell-quote-argument (car session))) "-a"))))) (cl-loop for line in (split-string lines "\n" t) collect (let ((window (split-string line ";"))) @@ -122,7 +122,7 @@ but do not execute them." (if sess-or-win (concat (if (string-prefix-p "$" (car sess-or-win)) "-s ") "-t " - (car sess-or-win)) + (shell-quote-argument (car sess-or-win))) "-a"))))) (cl-loop for line in (split-string lines "\n" t) collect (let ((pane (split-string line ";"))) diff --git a/modules/ui/doom/config.el b/modules/ui/doom/config.el index 5b2d0688d..adbb35714 100644 --- a/modules/ui/doom/config.el +++ b/modules/ui/doom/config.el @@ -24,27 +24,31 @@ (use-package! solaire-mode :when (or (daemonp) (display-graphic-p)) - :defer t - :init - (add-hook! 'doom-load-theme-hook :append - (defun +doom-solaire-mode-swap-bg-maybe-h () - (when (string-prefix-p "doom-" (symbol-name doom-theme)) - (require 'solaire-mode) - (solaire-mode-swap-bg)))) + :hook (doom-load-theme . solaire-global-mode) :config - ;; fringe can become unstyled when deleting or focusing frames - (add-hook 'focus-in-hook #'solaire-mode-reset) - ;; Prevent color glitches when reloading either DOOM or loading a new theme - (add-hook! '(doom-load-theme-hook doom-reload-hook) :append - #'solaire-mode-reset) + (when (daemonp) + (add-hook! 'doom-switch-frame-hook + (defun +doom-disable-solaire-mode-maybe-h () + (if (display-graphic-p) + (unless solaire-global-mode + (solaire-global-mode +1)) + (when solaire-global-mode + (solaire-global-mode -1)))))) + + (add-hook! 'solaire-global-mode-hook + (defun +doom-solaire-swap-bg-faces-maybe-h () + (and solaire-global-mode + (string-prefix-p "doom-" (symbol-name doom-theme)) + (solaire-mode-swap-bg)))) + ;; org-capture takes an org buffer and narrows it. The result is erroneously ;; considered an unreal buffer, so solaire-mode must be restored. (add-hook 'org-capture-mode-hook #'turn-on-solaire-mode) - ;; On Emacs 26+, when point is on the last line and solaire-mode is remapping - ;; the hl-line face, hl-line's highlight bleeds into the rest of the window - ;; after eob. On Emacs 27 this no longer happens. (unless EMACS27+ + ;; On Emacs <=26, when point is on the last line and solaire-mode is + ;; remapping the hl-line face, hl-line's highlight bleeds into the rest of + ;; the window after eob. On Emacs 27 this no longer happens. (defun +doom--line-range-fn () (let ((bol (line-beginning-position)) (eol (line-end-position)) @@ -57,21 +61,27 @@ (= eol pmax)) eol) ((line-beginning-position 2)))))) - (setq hl-line-range-function #'+doom--line-range-fn)) + (setq hl-line-range-function #'+doom--line-range-fn) - ;; Because fringes can't be given a buffer-local face, they can look odd, so - ;; we remove them in the minibuffer and which-key popups (they serve no - ;; purpose there anyway). - (add-hook! 'solaire-mode-hook - (defun +doom-disable-fringes-in-minibuffer-h (&rest _) - (set-window-fringes (minibuffer-window) 0 0 nil))) + ;; HACK The fringe cannot have a buffer-local remapping on Emacs <= 26, so + ;; we jump through hoops to reset it (globally) whenever it is likely + ;; that the fringe will have lost its background color. + + ;; Prevent color glitches when reloading either DOOM or loading a new theme + (add-hook! '(doom-load-theme-hook doom-reload-hook) :append + #'solaire-mode-reset) - (defadvice! +doom--no-fringes-in-which-key-buffer-a (&rest _) - :after 'which-key--show-buffer-side-window - (+doom-disable-fringes-in-minibuffer-h) - (set-window-fringes (get-buffer-window which-key--buffer) 0 0 nil)) + ;; fringe can become unstyled when deleting or focusing frames + (add-hook 'focus-in-hook #'solaire-mode-reset) - (add-hook! '(minibuffer-setup-hook window-configuration-change-hook) - #'+doom-disable-fringes-in-minibuffer-h) - - (solaire-global-mode +1)) + ;; A global fringe color means the minibuffer (with its fringes) will always + ;; stand out, so we remove them (in which-key popups too). + (add-hook! 'solaire-mode-hook + (defun +doom-disable-fringes-in-minibuffer-h (&rest _) + (set-window-fringes (minibuffer-window) 0 0 nil))) + (defadvice! +doom--no-fringes-in-which-key-buffer-a (&rest _) + :after 'which-key--show-buffer-side-window + (+doom-disable-fringes-in-minibuffer-h) + (set-window-fringes (get-buffer-window which-key--buffer) 0 0 nil)) + (add-hook! '(minibuffer-setup-hook window-configuration-change-hook) + #'+doom-disable-fringes-in-minibuffer-h))) diff --git a/modules/ui/doom/packages.el b/modules/ui/doom/packages.el index 0893eebed..46e44fbbc 100644 --- a/modules/ui/doom/packages.el +++ b/modules/ui/doom/packages.el @@ -2,4 +2,4 @@ ;;; ui/doom/packages.el (package! doom-themes :pin "8d5ddbbb72") -(package! solaire-mode :pin "4ac324ccb0") +(package! solaire-mode :pin "adc8c0c60d") diff --git a/modules/ui/fill-column/packages.el b/modules/ui/fill-column/packages.el index dcc6e381e..24adf3078 100644 --- a/modules/ui/fill-column/packages.el +++ b/modules/ui/fill-column/packages.el @@ -1,4 +1,4 @@ ;; -*- no-byte-compile: t; -*- ;;; ui/fill-column/packages.el -(package! hl-fill-column :pin "612441e697") +(package! hl-fill-column :pin "43cb3c35a9") diff --git a/modules/ui/indent-guides/packages.el b/modules/ui/indent-guides/packages.el index 3bf737416..3a6856a27 100644 --- a/modules/ui/indent-guides/packages.el +++ b/modules/ui/indent-guides/packages.el @@ -1,4 +1,4 @@ ;; -*- no-byte-compile: t; -*- ;;; ui/indent-guides/packages.el -(package! highlight-indent-guides :pin "0b10f38c54") +(package! highlight-indent-guides :pin "1b12c7b440") diff --git a/modules/ui/modeline/autoload.el b/modules/ui/modeline/autoload.el index 58ecd562b..437390db3 100644 --- a/modules/ui/modeline/autoload.el +++ b/modules/ui/modeline/autoload.el @@ -1,15 +1,5 @@ ;;; ui/modeline/autoload/modeline.el -*- lexical-binding: t; -*- -;;;###autodef -(defalias 'def-modeline-format! #'doom-modeline-def-modeline) - -;;;###autodef -(defalias 'def-modeline-segment! #'doom-modeline-def-segment) - -;;;###autodef -(defalias 'set-modeline! #'doom-modeline-set-modeline) - - (defvar +modeline--old-bar-height nil) ;;;###autoload (defun +modeline-resize-for-font-h () @@ -31,14 +21,16 @@ Meant for `doom-change-font-size-hook'." "Update version strings in all buffers." (dolist (window (window-list)) (with-selected-window window - (doom-modeline-update-env) + (when (fboundp 'doom-modeline-update-env) + (doom-modeline-update-env)) (force-mode-line-update)))) ;;;###autoload (defun +modeline-clear-env-in-all-windows-h (&rest _) "Blank out version strings in all buffers." - (dolist (buffer (buffer-list)) - (with-current-buffer buffer - (setq doom-modeline-env--version - (bound-and-true-p doom-modeline-load-string)))) + (unless (featurep! +light) + (dolist (buffer (buffer-list)) + (with-current-buffer buffer + (setq doom-modeline-env--version + (bound-and-true-p doom-modeline-load-string))))) (force-mode-line-update t)) diff --git a/modules/ui/modeline/packages.el b/modules/ui/modeline/packages.el index a17eabc0a..f9427d43e 100644 --- a/modules/ui/modeline/packages.el +++ b/modules/ui/modeline/packages.el @@ -2,7 +2,7 @@ ;;; ui/modeline/packages.el (unless (featurep! +light) - (package! doom-modeline :pin "b44955841a")) + (package! doom-modeline :pin "c177959bbf")) (package! anzu :pin "3e34fb3df5") (when (featurep! :editor evil) (package! evil-anzu :pin "9bca6ca14d")) diff --git a/modules/ui/nav-flash/config.el b/modules/ui/nav-flash/config.el index ddede5f03..5bfdd2747 100644 --- a/modules/ui/nav-flash/config.el +++ b/modules/ui/nav-flash/config.el @@ -5,6 +5,10 @@ org-find-file org-find-file-at-mouse) "A list of commands that should not trigger nav-flash.") + +;; +;;; Packages + (use-package! nav-flash :defer t :init @@ -30,4 +34,8 @@ (advice-add #'evil-window-bottom :after #'+nav-flash-blink-cursor-a) ;; Bound to `ga' for evil users - (advice-add #'what-cursor-position :after #'+nav-flash-blink-cursor-a)) + (advice-add #'what-cursor-position :after #'+nav-flash-blink-cursor-a) + + :config + (when (fboundp 'set-face-extend) + (set-face-extend 'nav-flash-face t))) diff --git a/modules/ui/treemacs/packages.el b/modules/ui/treemacs/packages.el index a5278feae..a1e1ead7e 100644 --- a/modules/ui/treemacs/packages.el +++ b/modules/ui/treemacs/packages.el @@ -1,7 +1,8 @@ ;; -*- no-byte-compile: t; -*- ;;; ui/treemacs/packages.el -(package! treemacs :pin "1b82dacc57") +(package! treemacs :pin "ee1b523b28") +;; These packages have no :pin because they're in the same repo (when (featurep! :editor evil +everywhere) (package! treemacs-evil)) (package! treemacs-projectile) diff --git a/modules/ui/zen/config.el b/modules/ui/zen/config.el index 0f02441a2..8d9fc576d 100644 --- a/modules/ui/zen/config.el +++ b/modules/ui/zen/config.el @@ -48,6 +48,7 @@ 'org-todo-keyword-kill 'org-todo-keyword-outd 'org-todo + 'org-done 'org-indent 'font-lock-comment-face 'line-number