merge: pull request #6369 from elken/feature/editor-format-refactor

This commit is contained in:
Henrik Lissner 2023-09-14 01:19:01 +02:00 committed by GitHub
commit a234d8e9c0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
89 changed files with 526 additions and 728 deletions

View file

@ -3,44 +3,37 @@
#+created: July 26, 2020 #+created: July 26, 2020
#+since: 21.12.0 #+since: 21.12.0
#+begin_quote
🔨 This module has been scheduled for a rewrite. Its documentation will remain
incomplete and edge cases left unpatched in the meantime. A preview of this
rewrite can be found [[https://github.com/hlissner/doom-emacs-private/tree/master/modules/editor/format][in my private config]].
#+end_quote
* Description :unfold: * Description :unfold:
This module integrates code formatters into Emacs. Here are some of the Code style is something that's hotly debated since the beginning of time.
formatters that it currently supports:
#+begin_quote Tabs or spaces?
asmfmt, black, brittany, cabal-fmt, clang-format, cmake-format, dartfmt, dfmt, 2-width or 4-width indentation?
dhall format, dockfmt, elm-format, emacs, fish_indent, fprettify, gleam format,
gofmt, iStyle, jsonnetfmt, ktlint, latexindent, ledger-mode, lua-fmt, mix Which is right? Doom doesn't care, but we will try and make it easy for you to
format, nixfmt, node-cljfmt, ocp-indent, perltidy, prettier, purty, rufo, format code within the safety of Emacs.
rustfmt, scalafmt, script shfmt, snakefmt, sqlformat, styler, swiftformat, tidy
#+end_quote At present, the module wraps [[https://github.com/radian-software/apheleia/][apheleia]], which includes some more detail on the
internals of the package; but the long and short of it is on-save your code will
be formatted and returned to the buffer using
[[https://tools.ietf.org/doc/tcllib/html/rcs.html#section4][RCS patching]].
** Maintainers ** Maintainers
/This module has no dedicated maintainers./ [[doom-contrib-maintainer:][Become a maintainer?]] - [[doom-user:][@elken]]
[[doom-contrib-maintainer:][Become a maintainer?]]
** Module flags ** Module flags
- +onsave :: - +onsave ::
Enable reformatting of a buffer when it is saved. See Enable reformatting of a buffer when it is saved. See
[[var:+format-on-save-enabled-modes]] to control what major modes to (or not to) [[var:+format-on-save-disabled-modes]] to control what major modes to (or not to)
format on save. format on save.
** Packages ** Packages
- [[doom-package:format-all]] - [[doom-package:apheleia]]
** Hacks ** Hacks
- format-all has been heavily modified to suit Doom's goals for this module: As of writing this, apheleia doesn't /yet/ support regions or similar kinds of
- Reformatted text is applied to the buffer by RCS patch, as to reduce its buffers, so there are a couple of hacks to attempt to rectify this.
affect on cursor position.
- Adds partial formatting, i.e. you can now reformat a subset of the buffer.
- Adds the ability to use any arbitrary formatter on the current buffer if you
pass the universal argument to [[fn:+format/buffer]] or [[fn:+format/region]] (i.e.
removes the major-mode lock on formatters).
** TODO Changelog ** TODO Changelog
# This section will be machine generated. Don't edit it by hand. # This section will be machine generated. Don't edit it by hand.
@ -51,98 +44,64 @@ rustfmt, scalafmt, script shfmt, snakefmt, sqlformat, styler, swiftformat, tidy
This module has no direct requirements, but each language will need one of their This module has no direct requirements, but each language will need one of their
supported formatter programs in order for this to work. In their absence, supported formatter programs in order for this to work. In their absence,
[[doom-package:format-all]] will fail silently. [[doom-package:apheleia]] will fail silently.
Supported formatters: To see if a particular mode has a configured formatter, check for the mode in
- Angular/Vue (prettier) [[var:apheleia-mode-alist]] which corresponds to the list of formatters defined in
- Assembly (asmfmt) [[var:apheleia-formatters]]
- Bazel Starlark (buildifier)
- BibTeX (emacs)
- C/C++/Objective-C (clang-format)
- Cabal (cabal-fmt)
- Clojure/ClojureScript (node-cljfmt)
- CMake (cmake-format)
- Crystal (crystal tool format)
- CSS/Less/SCSS (prettier)
- D (dfmt)
- Dart (dartfmt)
- Dhall (dhall format)
- Dockerfile (dockfmt)
- Elixir (mix format)
- Elm (elm-format)
- Emacs Lisp (emacs)
- Fish Shell (fish_indent)
- Fortran 90 (fprettify)
- Gleam (gleam format)
- Go (gofmt)
- GraphQL (prettier)
- Haskell (brittany)
- HTML/XHTML/XML (tidy)
- Java (clang-format)
- JavaScript/JSON/JSX (prettier)
- Jsonnet (jsonnetfmt)
- Kotlin (ktlint)
- LaTeX (latexindent)
- Ledger (ledger-mode)
- Lua (lua-fmt)
- Markdown (prettier)
- Nix (nixfmt)
- OCaml (ocp-indent)
- Perl (perltidy)
- PHP (prettier plugin-php)
- Protocol Buffers (clang-format)
- PureScript (purty)
- Python (black)
- R (styler)
- Ruby (rufo)
- Rust (rustfmt)
- Scala (scalafmt)
- Shell script (shfmt)
- Snakemake (snakefmt)
- Solidity (prettier-plugin-solidity)
- SQL (sqlformat)
- Swift (swiftformat)
- Terraform (terraform fmt)
- TOML (prettier-plugin-toml)
- TypeScript/TSX (prettier)
- Verilog (iStyle)
- YAML (prettier)
* TODO Usage * Usage
#+begin_quote ** With +onsave
🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]] When this flag is enabled, you shouldn't need to do anything other than write
#+end_quote code and save it.
* TODO Configuration ** Without +onsave
#+begin_quote Without the flag, formatting will only occur when either =apheleia-format-buffer=
🔨 /This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]] or =+format/buffer= is called.
#+end_quote
** Automatic reformatting when saving buffers * Configuration
There are two ways to achieve this. Either through the =+onsave= flag, or by
adding ~format-all-mode~ to the hook of each major mode you want this behavior Detailed configuration can be found [[https://github.com/radian-software/apheleia/#user-guide][upstream]], but for most purposes here we
enabled in. provide a simple macro that looks like the below:
If you choose the former, what modes it applies to can be changed by modifying
~+format-on-save-enabled-modes~, which contains a list of major modes. If the
first item in the list is the symbol ~not~, the list is negated. This is its
default value:
#+begin_src emacs-lisp #+begin_src emacs-lisp
(setq +format-on-save-enabled-modes (set-formatter! 'unique-name '("command" "line" "here") :modes '(name-of-major-mode))
'(not emacs-lisp-mode ; elisp's mechanisms are good enough
sql-mode ; sqlformat is currently broken
tex-mode ; latexindent is broken
latex-mode))
#+end_src #+end_src
If you want to format code when you save a buffer, but want more granular There are a few bonus symbols that apheleia uses (for example =npx= will be
control over which major modes this behavior is enabled in, there is an replaced by a correct path to npx) which are all documented in the link above.
alternative. Make sure [[doom-module:+onsave]] is disabled before you try this:
** Disabling formatters
*** Permanently
To permanently disable a particular formatter with no provided alternative
#+begin_src emacs-lisp #+begin_src emacs-lisp
(add-hook 'python-mode-hook #'format-all-mode) (setq apheleia-formatters (delq (assoc 'csharpier apheleia-formatters) apheleia-formatters))
(add-hook 'js2-mode-hook #'format-all-mode)
#+end_src #+end_src
*** Per-buffer
If you want to save without formatting, this is done by first passing the
universal argument thus; =SPC u SPC f s= for evil users, =C-u C-x C-s= for non-evil
users.
If you want to save more than a handful of time, you can set
[[var:apheleia-inhibit]] to disable even if =apheleia-global-mode= is on.
*** Onsave only
This behaviour is controlled via [[var:+format-on-save-disabled-modes]] thus;
#+begin_src emacs-lisp
(setq +format-on-save-disabled-modes
'(emacs-lisp-mode ; elisp's mechanisms are good enough
sql-mode ; sqlformat is currently broken
tex-mode ; latexindent is broken
latex-mode))
#+end_src
In this case, =emacs-lisp-mode=, =sql-mode=, =tex-mode= and =latex-mode= will not be
formatted on save, but can still be formatted by manually invoking the commands
=apheleia-format-buffer= or =+format/buffer=.
** Disabling the LSP formatter ** Disabling the LSP formatter
If you are in a buffer with ~lsp-mode~ enabled and a server that supports If you are in a buffer with ~lsp-mode~ enabled and a server that supports
=textDocument/formatting=, it will be used instead of [[doom-package:format-all]]'s formatter. =textDocument/formatting=, it will be used instead of [[doom-package:format-all]]'s formatter.
@ -151,25 +110,31 @@ If you are in a buffer with ~lsp-mode~ enabled and a server that supports
+ To disable this behavior in one mode: ~(setq-hook! 'python-mode-hook + To disable this behavior in one mode: ~(setq-hook! 'python-mode-hook
+format-with-lsp nil)~ +format-with-lsp nil)~
** TODO Defining your own formatters ** Selecting a specific formatter for a particular buffer
See the ~set-formatter!~ function.
** TODO Selecting a specific formatter for a particular buffer
Set the buffer-local variable ~+format-with~ to the name of the formatter to Set the buffer-local variable ~+format-with~ to the name of the formatter to
use. e.g. use. e.g.
#+begin_src emacs-lisp #+begin_src emacs-lisp
;; Overrides `apheleia-mode-alist`
(setq-hook! 'python-mode-hook +format-with 'html-tidy) (setq-hook! 'python-mode-hook +format-with 'html-tidy)
;; Or set it to `:none' to disable formatting ;; Or set it to `nil' to fallback to `apheleia-mode-alist`
(setq-hook! 'python-mode-hook +format-with :none) (setq-hook! 'python-mode-hook +format-with nil)
#+end_src #+end_src
Formatters are referred to by the name they were defined with. They can be Formatters are referred to by the name they were defined with. They can be
looked up in the ~format-all-mode-table~ hash table or in format-all's [[https://github.com/lassik/emacs-format-all-the-code/blob/master/format-all.el#L512][source looked up in the ~apheleia-mode-alist~ hash table.
code]].
* Troubleshooting * Troubleshooting
/There are no known problems with this module./ [[doom-report:][Report one?]] There are a few fail-safes apheleia has to prevent accidental code wipe,
included silently failing if the command errors or doesn't exist.
Check that the command you've specified runs fine in a terminal first before
reporting this as an issue.
If any errors are reported from the command, run =apheleia-goto-error= to jump to
the error buffer and handle any problems raised there.
Any issues specific to apheleia should most often be reported upstream [[https://github.com/radian-software/apheleia/issues][here]].
* Frequently asked questions * Frequently asked questions
/This module has no FAQs yet./ [[doom-suggest-faq:][Ask one?]] /This module has no FAQs yet./ [[doom-suggest-faq:][Ask one?]]

View file

@ -1,276 +1,85 @@
;;; editor/format/autoload.el -*- lexical-binding: t; -*- ;;; editor/format/autoload.el -*- lexical-binding: t; -*-
(defvar +format-region-p nil
"Is non-nil if currently reformatting a selected region, rather than the whole
buffer.")
;;;###autoload
(autoload 'format-all--probe "format-all")
(defun +format--delete-whole-line (&optional arg)
"Delete the current line without putting it in the `kill-ring'.
Derived from function `kill-whole-line'. ARG is defined as for that
function.
Stolen shamelessly from go-mode"
(setq arg (or arg 1))
(if (and (> arg 0)
(eobp)
(save-excursion (forward-visible-line 0) (eobp)))
(signal 'end-of-buffer nil))
(if (and (< arg 0)
(bobp)
(save-excursion (end-of-visible-line) (bobp)))
(signal 'beginning-of-buffer nil))
(cond ((zerop arg)
(delete-region (progn (forward-visible-line 0) (point))
(progn (end-of-visible-line) (point))))
((< arg 0)
(delete-region (progn (end-of-visible-line) (point))
(progn (forward-visible-line (1+ arg))
(unless (bobp)
(backward-char))
(point))))
((delete-region (progn (forward-visible-line 0) (point))
(progn (forward-visible-line arg) (point))))))
;;;###autoload
(defun +format--apply-rcs-patch (patch-buffer)
"Apply an RCS-formatted diff from PATCH-BUFFER to the current buffer.
Stolen shamelessly from go-mode"
(let ((target-buffer (current-buffer))
;; Relative offset between buffer line numbers and line numbers
;; in patch.
;;
;; Line numbers in the patch are based on the source file, so
;; we have to keep an offset when making changes to the
;; buffer.
;;
;; Appending lines decrements the offset (possibly making it
;; negative), deleting lines increments it. This order
;; simplifies the forward-line invocations.
(line-offset 0)
(column (current-column)))
(save-excursion
(with-current-buffer patch-buffer
(goto-char (point-min))
(while (not (eobp))
(unless (looking-at "^\\([ad]\\)\\([0-9]+\\) \\([0-9]+\\)")
(error "Invalid rcs patch or internal error in +format--apply-rcs-patch"))
(forward-line)
(let ((action (match-string 1))
(from (string-to-number (match-string 2)))
(len (string-to-number (match-string 3))))
(cond
((equal action "a")
(let ((start (point)))
(forward-line len)
(let ((text (buffer-substring start (point))))
(with-current-buffer target-buffer
(cl-decf line-offset len)
(goto-char (point-min))
(forward-line (- from len line-offset))
(insert text)))))
((equal action "d")
(with-current-buffer target-buffer
(goto-char (point-min))
(forward-line (1- (- from line-offset)))
(cl-incf line-offset len)
(+format--delete-whole-line len)))
((error "Invalid rcs patch or internal error in +format--apply-rcs-patch")))))))
(move-to-column column)))
(defun +format--current-indentation () (defun +format--current-indentation ()
(save-excursion (save-excursion
(goto-char (point-min)) (goto-char (point-min))
(skip-chars-forward " \t\n") (skip-chars-forward " \t\n")
(current-indentation))) (current-indentation)))
(defun +format-region (start end &optional callback)
;; "Format from START to END with `apheleia'."
;; Public library (when-let* ((command (apheleia--get-formatter-command
(if current-prefix-arg
(defun +format-completing-read () 'prompt
"TODO" 'interactive)))
(require 'format-all) (cur-buffer (current-buffer))
(let* ((fmtlist (mapcar #'symbol-name (hash-table-keys format-all--format-table))) (formatted-buffer (get-buffer-create " *apheleia-formatted*"))
(fmt (completing-read "Formatter: " fmtlist))) (indent 0))
(if fmt (intern fmt)))) (with-current-buffer formatted-buffer
(erase-buffer)
;;;###autoload (unless IS-WINDOWS
(defun +format-probe-a (fn) (setq-local coding-system-for-read 'utf-8)
"Use `+format-with' instead, if it is set. (setq-local coding-system-for-write 'utf-8))
Prompts for a formatter if universal arg is set." ;; Ensure this temp buffer seems as much like the origin buffer as
(cond ((or buffer-read-only (eq +format-with :none)) ;; possible, in case the formatter is an elisp function, like `gofmt'.
(list nil nil)) (cl-loop for (var . val)
(current-prefix-arg in (cl-remove-if-not #'listp (buffer-local-variables origin-buffer))
(list (or (+format-completing-read) ;; Making enable-multibyte-characters buffer-local causes an
(user-error "Aborted")) ;; error.
t)) unless (eq var 'enable-multibyte-characters)
(+format-with ;; Using setq-local would quote var.
(list +format-with t)) do (set (make-local-variable var) val))
((and +format-with-lsp ;;
(bound-and-true-p lsp-managed-mode) (insert-buffer-substring-no-properties cur-buffer start end)
(lsp-feature? "textDocument/formatting")) ;; Since we're piping a region of text to the formatter, remove any
(list 'lsp nil)) ;; leading indentation to make it look like a file.
((and +format-with-lsp (setq indent (+format--current-indentation))
(bound-and-true-p eglot--managed-mode) (when (> indent 0)
(eglot--server-capable :documentFormattingProvider)) (indent-rigidly (point-min) (point-max) (- indent)))
(list 'eglot nil)) ;;
((funcall fn)))) (apheleia-format-buffer
command
;;;###autoload (lambda ()
(defun +format-buffer-a (formatter mode-result) (with-current-buffer formatted-buffer
"Advice that extends `format-all-buffer--with' to: (when (> indent 0)
;; restore indentation without affecting new
1. Enable partial/region reformatting, while preserving leading indentation, ;; indentation
2. Applies changes via RCS patch, line by line, to protect buffer markers and (indent-rigidly (point-min) (point-max)
reduce cursor movement or window scrolling. (max 0 (- indent (+format--current-indentation))))))
(with-current-buffer cur-buffer
See `+format/buffer' for the interactive version of this function, and (delete-region start end)
`+format-buffer-h' to use as a `before-save-hook' hook." (insert-buffer-substring-no-properties formatted-buffer)
(cond (when callback (funcall callback))
((eq formatter 'lsp) (kill-buffer formatted-buffer)))))))
(call-interactively
(if +format-region-p #'lsp-format-region #'lsp-format-buffer)))
((eq formatter 'eglot)
(call-interactively
(if +format-region-p #'eglot-format #'eglot-format-buffer)))
((let ((f-function (gethash formatter format-all--format-table))
(executable (format-all--formatter-executable formatter))
(indent 0)
(old-line-number (line-number-at-pos))
(old-column (current-column)))
(pcase-let*
((`(,output ,errput)
;; To reliably format regions, rather than the whole buffer, and
;; `format-all' (and various formatting functions, like `gofmt') widen
;; the buffer, we must copy the region first.
(let ((output (buffer-substring-no-properties (point-min) (point-max)))
(origin-buffer (or (buffer-base-buffer) (current-buffer)))
;; Fixes #5133: some packages (like lsp-mode) can do a bunch
;; of complicated stuff in these hooks. Better to not have to
;; deal with any of them at all.
write-file-functions
before-save-hook
after-save-hook
kill-buffer-query-functions
kill-buffer-hook)
(with-temp-buffer
(with-silent-modifications
(insert output)
;; Ensure this temp buffer seems as much like the origin
;; buffer as possible, in case the formatter is an elisp
;; function, like `gofmt'.
(cl-loop for (var . val)
in (cl-remove-if-not #'listp (buffer-local-variables origin-buffer))
;; Making enable-multibyte-characters buffer-local
;; causes an error.
unless (eq var 'enable-multibyte-characters)
;; Fixes #5133: don't deal with complicated hook
;; functionality! This isn't a real buffer anyway.
unless (string-match-p (symbol-name var) "-\\(hook\\|functions\\)$")
;; Using setq-local would quote var.
do (set (make-local-variable var) val))
;; Since we're piping a region of text to the formatter, remove
;; any leading indentation to make it look like a file.
(setq indent (+format--current-indentation))
(when (> indent 0)
(indent-rigidly (point-min) (point-max) (- indent)))
(funcall f-function executable mode-result)))))
(`,status
(cond ((null output) :error)
((eq output t) :already-formatted)
(t :reformatted))))
(unwind-protect
(when (eq status :reformatted)
(let ((tmpfile (make-temp-file "doom-format"))
(patchbuf (get-buffer-create " *doom format patch*"))
(coding-system-for-read coding-system-for-read)
(coding-system-for-write coding-system-for-write))
(unless IS-WINDOWS
(setq coding-system-for-read 'utf-8
coding-system-for-write 'utf-8))
(unwind-protect
(progn
(with-current-buffer patchbuf
(erase-buffer))
(with-temp-file tmpfile
(erase-buffer)
(insert output)
(when (> indent 0)
;; restore indentation without affecting new
;; indentation
(indent-rigidly (point-min) (point-max)
(max 0 (- indent (+format--current-indentation))))))
(if (zerop (call-process-region (point-min) (point-max) "diff" nil patchbuf nil "-n" "-" tmpfile))
(setq status :already-formatted)
(+format--apply-rcs-patch patchbuf)
(list output errput)))
(kill-buffer patchbuf)
(delete-file tmpfile))))
(format-all--show-or-hide-errors errput)
(goto-char (point-min))
(forward-line (1- old-line-number))
(let ((line-length (- (point-at-eol) (point-at-bol))))
(goto-char (+ (point) (min old-column line-length))))
(run-hook-with-args 'format-all-after-format-functions formatter status)
(message (pcase status
(:error "Formatting error")
(:already-formatted "Already formatted")
(:reformatted (format "Reformatted with %s" formatter))))))))))
;; ;;
;;; Commands ;;; Commands
(defun +format--org-region (beg end)
"Reformat the region within BEG and END.
If nil, BEG and/or END will default to the boundaries of the src block at point."
(let ((element (org-element-at-point)))
(save-excursion
(let* ((block-beg (save-excursion
(goto-char (org-babel-where-is-src-block-head element))
(line-beginning-position 2)))
(block-end (save-excursion
(goto-char (org-element-property :end element))
(skip-chars-backward " \t\n")
(line-beginning-position)))
(beg (if beg (max beg block-beg) block-beg))
(end (if end (min end block-end) block-end))
(lang (org-element-property :language element))
(major-mode (org-src-get-lang-mode lang)))
(if (eq major-mode 'org-mode)
(user-error "Cannot reformat an org src block in org-mode")
(+format/region beg end))))))
(defun +format--buffer ()
(if (and (eq major-mode 'org-mode)
(org-in-src-block-p t))
(+format--org-region (point-min) (point-max))
(if (called-interactively-p 'any)
(format-all-buffer)
(ignore-errors (format-all-buffer)))))
;;;###autoload ;;;###autoload
(defun +format/buffer () (defun +format/buffer (&optional arg)
"Reformat the current buffer using LSP or `format-all-buffer'." "Reformat the current buffer using LSP or `format-all-buffer'."
(interactive) (interactive "P")
(+format--buffer)) (call-interactively
(if (and +format-with-lsp
(bound-and-true-p lsp-mode)
(lsp-feature? "textDocument/formatting"))
#'lsp-format-buffer
#'apheleia-format-buffer)))
;;;###autoload ;;;###autoload
(defun +format/region (beg end) (defun +format/region (beg end &optional arg)
"Runs the active formatter on the lines within BEG and END. "Runs the active formatter on the lines within BEG and END.
WARNING: this may not work everywhere. It will throw errors if the region WARNING: this may not work everywhere. It will throw errors if the region
contains a syntax error in isolation. It is mostly useful for formatting contains a syntax error in isolation. It is mostly useful for formatting
snippets or single lines." snippets or single lines."
(interactive "rP") (interactive "rP")
(let ((+format-region-p t)) (if (and +format-with-lsp
(save-restriction (bound-and-true-p lsp-mode)
(narrow-to-region beg end) (lsp-feature? "textDocument/rangeFormatting"))
(+format--buffer)))) (call-interactively #'lsp-format-region)
(+format-region beg end)))
;;;###autoload ;;;###autoload
(defun +format/region-or-buffer () (defun +format/region-or-buffer ()
@ -281,13 +90,3 @@ is selected)."
(if (doom-region-active-p) (if (doom-region-active-p)
#'+format/region #'+format/region
#'+format/buffer))) #'+format/buffer)))
;;
;; Hooks
;;;###autoload
(defalias '+format-buffer-h #'+format/buffer
"Format the source code in the current buffer with minimal feedback.
Meant for `before-save-hook'.")

View file

@ -1,97 +1,10 @@
;;; editor/format/autoload/settings.el -*- lexical-binding: t; -*- ;;; editor/format/autoload/settings.el -*- lexical-binding: t; -*-
;; This must be redefined here because `format-all' only makes it available at
;; compile time.
(defconst +format-system-type
(cl-case system-type
(windows-nt 'windows)
(cygwin 'windows)
(darwin 'macos)
(gnu/linux 'linux)
(berkeley-unix
(save-match-data
(let ((case-fold-search t))
(cond ((string-match "freebsd" system-configuration) 'freebsd)
((string-match "openbsd" system-configuration) 'openbsd)
((string-match "netbsd" system-configuration) 'netbsd))))))
"Current operating system according to the format-all package.")
(defun +format--resolve-system (choices)
"Get first choice matching `format-all-system-type' from CHOICES."
(cl-loop for choice in choices
if (atom choice) return choice
else if (eql +format-system-type (car choice))
return (cadr choice)))
(defun +format--make-command (formatter &rest _)
`(format-all--buffer-thunk
(lambda (input)
(with-silent-modifications
(setq buffer-file-name ,(buffer-file-name (buffer-base-buffer))
default-directory ,default-directory)
(delay-mode-hooks (funcall ',major-mode))
(insert input)
(condition-case e
(progn
(doom-log "formatter (commandp) %s" #',formatter)
(call-interactively #',formatter)
(list nil ""))
(error (list t (error-message-string e))))))))
(defun +format--make-function (formatter &rest _)
`(progn
(doom-log "formatter (functionp) %s" #',formatter)
(format-all--buffer-thunk #',formatter)))
(defun +format--make-shell-command (command ok-statuses error-regexp)
(+format--make-shell-command-list (split-string command " " t)
ok-statuses error-regexp))
(defun +format--make-shell-command-list (command-list ok-statuses error-regexp)
`(let (args)
(dolist (arg ',command-list)
(cond ((stringp arg)
(push arg args))
((listp arg)
(catch 'skip
(let (subargs this)
(while (setq this (pop arg))
(cond ((not (stringp (car arg)))
(let ((val (eval (pop arg) t)))
(unless val (throw 'skip nil))
(push (format this val) subargs)))
((stringp this)
(push this subargs))))
(setq args (append subargs args)))))))
(doom-log "formatter (arglist) %s" args)
(if ,(and (or ok-statuses error-regexp) t)
(apply #'format-all--buffer-hard
',ok-statuses ,error-regexp nil
(reverse args))
(apply #'format-all--buffer-easy (reverse args)))))
(cl-defun +format--set (name &key function modes unset)
(declare (indent defun))
(when (and unset (not (gethash name format-all--format-table)))
(error "'%s' formatter does not exist to be unset" name))
(puthash name function format-all--format-table)
(dolist (mode (ensure-list modes))
(cl-destructuring-bind (m &optional probe)
(ensure-list mode)
(if unset
(puthash m (assq-delete-all name (gethash key format-all-mode-table))
format-all-mode-table)
(format-all--pushhash
m (cons name (if probe `(lambda () ,probe)))
format-all--mode-table)))))
;;;###autodef ;;;###autodef
(cl-defun set-formatter! (cl-defun set-formatter! (name args &key modes)
(name formatter &key modes filter ok-statuses error-regexp)
"Define (or modify) a formatter named NAME. "Define (or modify) a formatter named NAME.
Supported keywords: :modes :filter :ok-statuses :error-regexp Supported keywords: :modes :filter
NAME is a symbol that identifies this formatter. NAME is a symbol that identifies this formatter.
@ -99,7 +12,7 @@ FORMATTER can be a symbol referring to another formatter, a function, string or
nested list. nested list.
If a function, it should be a formatter function that If a function, it should be a formatter function that
`format-all--buffer-thunk' will accept. `apheleia--run-formatter-function' will accept.
If a string, it is assumed to be a shell command that the buffer's text will If a string, it is assumed to be a shell command that the buffer's text will
be piped to (through stdin). be piped to (through stdin).
If a list, it should represent a shell command as a list of arguments. Each If a list, it should represent a shell command as a list of arguments. Each
@ -107,6 +20,9 @@ nested list.
string and ARG is both a predicate and argument for STRING. If ARG is nil, string and ARG is both a predicate and argument for STRING. If ARG is nil,
STRING will be omitted from the vector. STRING will be omitted from the vector.
For more information on how to structure the list to be
compatible, see `apheleia--run-formatter-function'.
MODES is a major mode, a list thereof, or a list of two-element sublists with MODES is a major mode, a list thereof, or a list of two-element sublists with
the structure: (MAJOR-MODE FORM). FORM is evaluated when the buffer is formatted the structure: (MAJOR-MODE FORM). FORM is evaluated when the buffer is formatted
and its return value serves two purposes: and its return value serves two purposes:
@ -116,27 +32,12 @@ and its return value serves two purposes:
2. It's return value is made available to FORMATTER if it is a function or 2. It's return value is made available to FORMATTER if it is a function or
list of shell arguments via the `mode-result' variable. list of shell arguments via the `mode-result' variable.
FILTER is a function that takes three arguments: the formatted output, any error
output and the position of the first change. This function must return these
three after making whatever changes you like to them. This might be useful if
the output contains ANSI color codes that need to be stripped out (as is the
case with elm-format).
OK-STATUSES and ERROR-REGEXP are ignored if FORMATTER is not a shell command.
OK-STATUSES is a list of integer exit codes that should be treated as success
codes. However, if ERROR-REGEXP is given, and the program's stderr contains that
regexp, then the formatting is considered failed even if the exit status is in
OK-STATUSES.
Basic examples: Basic examples:
(set-formatter! 'asmfmt \"asmfmt\" :modes '(asm-mode nasm-mode)) (set-formatter! 'asmfmt \"asmfmt\" :modes '(asm-mode nasm-mode))
(set-formatter! 'black \"black -q -\") (set-formatter! 'black \"black -q -\")
(set-formatter! 'html-tidy \"tidy -q -indent\" :modes '(html-mode web-mode)) (set-formatter! 'html-tidy \"tidy -q -indent\" :modes '(html-mode web-mode))
Advanced examples: Advanced examples:
(set-formatter! (set-formatter!
'clang-format 'clang-format
'(\"clang-format\" '(\"clang-format\"
@ -154,9 +55,7 @@ Advanced examples:
:modes :modes
'(html-mode '(html-mode
(web-mode (and (equal \"none\" web-mode-engine) (web-mode (and (equal \"none\" web-mode-engine)
(car (member web-mode-content-type '(\"xml\" \"html\")))))) (car (member web-mode-content-type '(\"xml\" \"html\")))))))
:ok-statuses '(0 1)
:executable \"tidy\")
(set-formatter! 'html-tidy ; overwrite predefined html-tidy formatter (set-formatter! 'html-tidy ; overwrite predefined html-tidy formatter
'(\"tidy\" \"-q\" \"-indent\" '(\"tidy\" \"-q\" \"-indent\"
@ -165,39 +64,25 @@ Advanced examples:
\"--show-body-only\" \"auto\" \"--show-body-only\" \"auto\"
(\"--indent-spaces\" \"%d\" tab-width) (\"--indent-spaces\" \"%d\" tab-width)
(\"--indent-with-tabs\" \"%s\" (if indent-tabs-mode \"yes\" \"no\")) (\"--indent-with-tabs\" \"%s\" (if indent-tabs-mode \"yes\" \"no\"))
(\"-xml\" (memq major-mode '(nxml-mode xml-mode)))) (\"-xml\" (memq major-mode '(nxml-mode xml-mode)))))
:ok-statuses '(0 1)))
(set-formatter! 'elm-format (set-formatter! 'elm-format
\"elm-format --yes --stdin\" \"elm-format --yes --stdin\")
:filter "
(lambda (output errput first-diff)
(list output
(format-all--remove-ansi-color errput)
first-diff)))"
(declare (indent defun)) (declare (indent defun))
(cl-check-type name symbol) (cl-check-type name symbol)
(after! format-all (after! apheleia-core
(if (null formatter) (if (null args)
(+format--set name (progn
:unset t (setq apheleia-formatters
:modes modes) (assq-delete-all name apheleia-formatters))
(let ((fn (funcall (cond ((stringp formatter) (while (rassoc name apheleia-mode-alist)
#'+format--make-shell-command) (setq apheleia-mode-alist
((listp formatter) (assq-delete-all (car (rassoc name apheleia-mode-alist)) apheleia-mode-alist))))
#'+format--make-shell-command-list) (let ((formatter (cond
((and (commandp formatter) ((listp args) `(,@args))
(not (stringp formatter))) (t args))))
#'+format--make-command) (setf (alist-get name apheleia-formatters) formatter))
((functionp formatter) (when modes
#'+format--make-function)) (dolist (mode modes)
formatter (setf (alist-get mode apheleia-mode-alist) name))))))
ok-statuses
error-regexp)))
(cl-check-type filter (or function null))
(+format--set name
:function
`(lambda (executable mode-result)
,(if filter `(apply #',filter ,fn) fn))
:modes modes)
name))))

View file

@ -1,18 +1,15 @@
;;; editor/format/config.el -*- lexical-binding: t; -*- ;;; editor/format/config.el -*- lexical-binding: t; -*-
(defvar +format-on-save-enabled-modes (defvar +format-on-save-disabled-modes
'(not emacs-lisp-mode ; elisp's mechanisms are good enough '(sql-mode ; sqlformat is currently broken
sql-mode ; sqlformat is currently broken tex-mode ; latexindent is broken
tex-mode ; latexindent is broken latex-mode
latex-mode org-msg-edit-mode) ; doesn't need a formatter
org-msg-edit-mode) ; doesn't need a formatter
"A list of major modes in which to reformat the buffer upon saving. "A list of major modes in which to reformat the buffer upon saving.
If this list begins with `not', then it negates the list. If this list begins with `not', then it negates the list.
If it is `t', it is enabled in all modes. If it is `t', it is enabled in all modes.
If nil, it is disabled in all modes, the same as if the +onsave flag wasn't If nil, it is disabled in all modes, the same as if the +onsave flag wasn't
used at all. used at all.
Irrelevant if you do not have the +onsave flag enabled for this module.") Irrelevant if you do not have the +onsave flag enabled for this module.")
(defvar +format-preserve-indentation t (defvar +format-preserve-indentation t
@ -21,69 +18,54 @@ buffer. This is particularly useful for partials.
Indentation is always preserved when formatting regions.") Indentation is always preserved when formatting regions.")
(defvar-local +format-with nil
"Set this to explicitly use a certain formatter for the current buffer.")
(defvar +format-with-lsp t (defvar +format-with-lsp t
"If non-nil, format with LSP formatter if it's available. "If non-nil, format with LSP formatter if it's available.
This can be set buffer-locally with `setq-hook!' to disable LSP formatting in This can be set buffer-locally with `setq-hook!' to disable LSP formatting in
select buffers.") select buffers.")
(defvaralias '+format-with 'apheleia-formatter
"Set this to explicitly use a certain formatter for the current buffer.")
;; ;;
;;; Bootstrap ;;; Bootstrap
(add-to-list 'doom-debug-variables 'format-all-debug) (when (modulep! +onsave)
(add-hook 'doom-first-file-hook #'apheleia-global-mode))
(defun +format-enable-on-save-maybe-h () (defun +format-inhibit-maybe-h ()
"Enable formatting on save in certain major modes. "Enable formatting on save in certain major modes.
This is controlled by `+format-on-save-disabled-modes'."
(or (eq major-mode 'fundamental-mode)
(string-empty-p (string-trim (buffer-name)))
(not (null (memq major-mode +format-on-save-disabled-modes)))))
This is controlled by `+format-on-save-enabled-modes'."
(or (cond ((eq major-mode 'fundamental-mode))
((string-prefix-p " " (buffer-name)))
((and (booleanp +format-on-save-enabled-modes)
(not +format-on-save-enabled-modes)))
((and (listp +format-on-save-enabled-modes)
(if (eq (car +format-on-save-enabled-modes) 'not)
(memq major-mode (cdr +format-on-save-enabled-modes))
(not (memq major-mode +format-on-save-enabled-modes)))))
((not (require 'format-all nil t))))
(format-all-mode +1)))
(when (modulep! +onsave) (when (modulep! +onsave)
(add-hook 'after-change-major-mode-hook #'+format-enable-on-save-maybe-h)) (after! apheleia-core
(add-to-list 'apheleia-inhibit-functions #'+format-inhibit-maybe-h)))
;; ;;
;;; Hacks ;;; Hacks
;; Allow a specific formatter to be used by setting `+format-with', either (defadvice! +format--inhibit-reformat-on-prefix-arg-a (orig-fn &optional arg)
;; buffer-locally or let-bound. "Make it so \\[save-buffer] with prefix arg inhibits reformatting."
(advice-add #'format-all--probe :around #'+format-probe-a) :around #'save-buffer
(let ((apheleia-mode (and apheleia-mode (member arg '(nil 1)))))
(funcall orig-fn)))
;; Doom uses a modded `format-all-buffer', which (add-hook!
;; 1. Enables partial reformatting (while preserving leading indentation), 'apheleia-post-format-hook
;; 2. Applies changes via RCS patch, line by line, to protect buffer markers ;; HACK `web-mode' doesn't update syntax highlighting after arbitrary buffer
;; and avoid any jarring cursor+window scrolling. ;; modifications, so we must trigger refontification manually.
(advice-add #'format-all-buffer--with :override #'+format-buffer-a) (defun +format--fix-web-mode-fontification-h ()
(when (eq major-mode 'web-mode)
(setq web-mode-fontification-off nil)
(when (and web-mode-scan-beg web-mode-scan-end global-font-lock-mode)
(save-excursion
(font-lock-fontify-region web-mode-scan-beg web-mode-scan-end)))))
;; format-all-mode "helpfully" raises an error when it doesn't know how to (defun +format--refresh-git-gutter-h ()
;; format a buffer. (when (fboundp '+vc-gutter-update-h)
(add-to-list 'debug-ignored-errors "^Don't know how to format ") (+vc-gutter-init-maybe-h))))
;; Don't pop up imposing warnings about missing formatters, but still log it in
;; to *Messages*.
(defadvice! +format--all-buffer-from-hook-a (fn &rest args)
:around #'format-all-buffer--from-hook
(letf! (defun format-all-buffer--with (formatter mode-result)
(when (or (eq formatter 'lsp)
(eq formatter 'eglot)
(condition-case-unless-debug e
(format-all--formatter-executable formatter)
(error
(message "Warning: cannot reformat buffer because %S isn't installed"
(gethash formatter format-all--executable-table))
nil)))
(funcall format-all-buffer--with formatter mode-result)))
(apply fn args)))

View file

@ -1,4 +1,4 @@
;; -*- no-byte-compile: t; -*- ;; -*- no-byte-compile: t; -*-
;;; editor/format/packages.el ;;; editor/format/packages.el
(package! format-all :pin "47d862d40a088ca089c92cd393c6dca4628f87d3") (package! apheleia :pin "c222927f7086d407dad01b2609ff68768e9adddb")

View file

@ -1,103 +0,0 @@
;; -*- no-byte-compile: t; -*-
;;; editor/format/test/test-format.el
(load! "../autoload/settings")
(load! "../autoload/format")
(require! :editor format)
(require 'format-all)
;;
(describe "editor/format"
:var (format-all--format-table
format-all--mode-table)
(before-each
(setq format-all--format-table (make-hash-table)
format-all--mode-table (make-hash-table)))
(describe "set-formatter!"
(before-each
(set-formatter! 'test (lambda () (interactive))))
(it "defines a formatter"
(set-formatter! 'new (lambda () (interactive)))
(expect (gethash 'new format-all--mode-table) :to-equal nil)
(expect (functionp (gethash 'new format-all--format-table))))
(it "defines a formatter with modes"
(set-formatter! 'new (lambda () (interactive))
:modes '(a-mode (b-mode "x")))
(expect (gethash 'a-mode format-all--mode-table)
:to-equal '((new)))
(expect (gethash 'b-mode format-all--mode-table)
:to-equal '((new . (lambda () "x")))))
(it "replaces a pre-existing formatter"
(let ((old-fn (gethash 'test format-all--format-table)))
(set-formatter! 'test "echo")
(expect (gethash 'test format-all--format-table) :not :to-equal old-fn)))
(it "unsets a pre-existing formatter"
(set-formatter! 'test nil)
(expect (gethash 'test format-all--format-table) :to-be nil))
(it "errors when unsetting non-existent formatter"
(expect (set-formatter! 'doesnt-exist nil) :to-throw)))
;; TODO
(xdescribe "hooks"
(describe "format|enable-on-save-maybe")
(describe "format|enable-on-save"))
;; TODO
(xdescribe "formatting"
(before-each
(set-formatter! 'command
(lambda ()
(interactive)
(let ((first-line (car (split-string (buffer-string) "\n"))))
(erase-buffer)
(insert first-line)))
:modes '(text-mode))
(set-formatter! 'faulty-command
(lambda ()
(interactive)
(error "This is a test"))
:modes '(text-mode))
(set-formatter! 'function
(lambda (input)
(insert (car (split-string input "\n")))
(list nil nil))
:modes '(text-mode))
(set-formatter! 'shellcmd "head -n 1"
:modes '(text-mode))
(set-formatter! 'cmdlist '("head" "-n" "1")
:modes '(text-mode)))
(describe "with an interactive command"
(it "formats a buffer" )
(it "formats a region" )
(it "no-ops if no change" )
(it "doesn't modify the buffer in case of errors" )
(it "preserves indentation" ))
(describe "with a function"
(it "formats a buffer" )
(it "formats a region" )
(it "no-ops if no change" )
(it "doesn't modify the buffer in case of errors" )
(it "preserves indentation" ))
(describe "with a shell command")
(describe "with a shell command list"
(it "formats a buffer" )
(it "formats a region" )
(it "no-ops if no change" )
(it "doesn't modify the buffer in case of errors" )
(it "preserves indentation" )
(it "interpolates non-strings into format strings" )
(it "conditionally appends sublisted options" ))))

View file

@ -34,6 +34,7 @@ you [[https://plaintextaccounting.org/][manage your money in plain text]].
This module requires: This module requires:
- [[https://github.com/beancount/beancount][beancount]], for generating reports - [[https://github.com/beancount/beancount][beancount]], for generating reports
- [[https://beancount.github.io/fava/][fava]], for a web interface for your ledgers - [[https://beancount.github.io/fava/][fava]], for a web interface for your ledgers
- [[doom-executable:bean-format]], if [[doom-module::editor format]]
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote

View file

@ -133,6 +133,11 @@ rdm &
rc -J $PROJECT_ROOT # loads PROJECT_ROOT's compile_commands.json rc -J $PROJECT_ROOT # loads PROJECT_ROOT's compile_commands.json
#+end_src #+end_src
** =:editor format=
The formatter used is [[doom-executable:clang-format]] which should be installed alongside =clang=.
For more info, see [[doom-module::editor format]].
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote
🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]] 🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]

View file

@ -48,6 +48,17 @@ This is ignored by ccls.")
(set-docsets! 'c-mode "C") (set-docsets! 'c-mode "C")
(set-docsets! 'c++-mode "C++" "Boost") (set-docsets! 'c++-mode "C++" "Boost")
(set-electric! '(c-mode c++-mode objc-mode java-mode) :chars '(?\n ?\} ?\{)) (set-electric! '(c-mode c++-mode objc-mode java-mode) :chars '(?\n ?\} ?\{))
(set-formatter!
'clang-format
'("clang-format"
"-assume-filename"
(or (buffer-file-name)
(cdr (assoc major-mode
'((c-mode . ".c")
(c++-mode . ".cpp")
(cuda-mode . ".cu")
(protobuf-mode . ".proto"))))))
:modes '(c-mode c++-mode protobuf-mode cuda-mode))
(set-rotate-patterns! 'c++-mode (set-rotate-patterns! 'c++-mode
:symbols '(("public" "protected" "private") :symbols '(("public" "protected" "private")
("class" "struct"))) ("class" "struct")))

View file

@ -26,3 +26,7 @@
;; glslangValidator ;; glslangValidator
(unless (executable-find "glslangValidator") (unless (executable-find "glslangValidator")
(warn! "Couldn't find glslangValidator. GLSL code completion is disabled"))) (warn! "Couldn't find glslangValidator. GLSL code completion is disabled")))
(when (modulep! :editor format)
(unless (executable-find "clang-format")
(warn! "Couldn't find clang-format. Formatting will be disabled.")))

View file

@ -47,6 +47,7 @@ This module requires:
- [[https://clojure-lsp.github.io/clojure-lsp/][clojure-lsp]], for LSP support (if [[doom-module:+lsp]]) - [[https://clojure-lsp.github.io/clojure-lsp/][clojure-lsp]], for LSP support (if [[doom-module:+lsp]])
- [[https://github.com/babashka/neil][neil]] for the ability to add packages to your Clojure project from Emacs - [[https://github.com/babashka/neil][neil]] for the ability to add packages to your Clojure project from Emacs
- [[https://github.com/borkdude/jet][jet]] for jet integration - [[https://github.com/borkdude/jet][jet]] for jet integration
- [[https://github.com/weavejester/cljfmt][cljfmt]], for formatting code (if [[doom-module::editor format]])
* Usage * Usage

View file

@ -16,6 +16,8 @@
(use-package! clojure-mode (use-package! clojure-mode
:hook (clojure-mode . rainbow-delimiters-mode) :hook (clojure-mode . rainbow-delimiters-mode)
:config :config
(set-formatter! 'cljfmt '("cljfmt" "fix" "-") :modes '(clojure-mode clojurec-mode clojurescript-mode))
(when (modulep! +lsp) (when (modulep! +lsp)
(add-hook! '(clojure-mode-local-vars-hook (add-hook! '(clojure-mode-local-vars-hook
clojurec-mode-local-vars-hook clojurec-mode-local-vars-hook

View file

@ -5,3 +5,7 @@
(not (modulep! +lsp))) (not (modulep! +lsp)))
(unless (executable-find "clj-kondo") (unless (executable-find "clj-kondo")
(warn! "Couldn't find clj-kondo. flycheck-clj-kondo will not work."))) (warn! "Couldn't find clj-kondo. flycheck-clj-kondo will not work.")))
(when (modulep! :editor format)
(unless (executable-find "cljfmt")
(warn! "Couldn't find cljfmt. Formatting will be disabled.")))

View file

@ -59,6 +59,12 @@ This module also enables the evaluation of =lisp= source blocks in Org Mode.
However, you will need a running Sly session for this to work. ~M-x sly~ starts However, you will need a running Sly session for this to work. ~M-x sly~ starts
such a session if you didn't have one open already. such a session if you didn't have one open already.
** formatter
By enabling [[doom-module::editor format]], [[fn:apheleia-indent-lisp-buffer]] will be
used to format the current buffer.
Enable [[doom-module::editor format +onsave]] to format the buffer on save.
* TODO Configuration * TODO Configuration
#+begin_quote #+begin_quote
🔨 /This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]] 🔨 /This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]]

View file

@ -26,10 +26,14 @@
(after! lisp-mode (after! lisp-mode
(set-repl-handler! 'lisp-mode #'+lisp/open-repl) (set-repl-handler! 'lisp-mode #'+lisp/open-repl)
(set-eval-handler! 'lisp-mode #'sly-eval-region) (set-eval-handler! 'lisp-mode #'sly-eval-region)
(set-formatter! 'lisp-indent #'apheleia--indent-lisp-buffer :modes '(lisp-mode))
(set-lookup-handlers! 'lisp-mode (set-lookup-handlers! 'lisp-mode
:definition #'sly-edit-definition :definition #'sly-edit-definition
:documentation #'sly-describe-symbol)) :documentation #'sly-describe-symbol))
;; This needs to be appended so it fires later than `sly-editing-mode'
(add-hook 'lisp-mode-local-vars-hook #'sly-lisp-indent-compatibility-mode 'append)
;; HACK Ensures that sly's contrib modules are loaded as soon as possible, but ;; HACK Ensures that sly's contrib modules are loaded as soon as possible, but
;; also as late as possible, so users have an opportunity to override ;; also as late as possible, so users have an opportunity to override
;; `sly-contrib' in an `after!' block. ;; `sly-contrib' in an `after!' block.

View file

@ -48,6 +48,12 @@ This module requires:
🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]] 🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]
#+end_quote #+end_quote
** formatter
By enabling [[doom-module::editor format]], [[doom-package:apheleia]] will be
used to format the current buffer.
Enable [[doom-module::editor format +onsave]] to format the buffer on save.
* TODO Configuration * TODO Configuration
#+begin_quote #+begin_quote
🔨 This module has no configuration documentation yet. [[doom-contrib-module:][Write some?]] 🔨 This module has no configuration documentation yet. [[doom-contrib-module:][Write some?]]

View file

@ -1,6 +1,8 @@
;;; lang/crystal/config.el -*- lexical-binding: t; -*- ;;; lang/crystal/config.el -*- lexical-binding: t; -*-
(after! crystal-mode (after! crystal-mode
(set-formatter! 'crystal-mode '("crystal" "tool" "format" "-") :modes '(crystal-mode))
(set-lookup-handlers! 'crystal-mode (set-lookup-handlers! 'crystal-mode
:definition #'crystal-def-jump :definition #'crystal-def-jump
:references #'crystal-tool-imp) :references #'crystal-tool-imp)

View file

@ -3,3 +3,6 @@
(unless (executable-find "icr") (unless (executable-find "icr")
(warn! "Couldn't find icr. REPL will not work")) (warn! "Couldn't find icr. REPL will not work"))
(unless (executable-find "crystal")
(error! "Couldn't find crystal. Most language features will not work."))

View file

@ -45,15 +45,22 @@ This module requires:
- .NET SDKs (on Windows) - .NET SDKs (on Windows)
- .NET Core 1.X - 3.X or .NET 5 for cross platform - .NET Core 1.X - 3.X or .NET 5 for cross platform
- omnisharp-rosyln (if [[doom-module:+lsp]]) - omnisharp-rosyln (if [[doom-module:+lsp]])
- [[doom-executable:csharpier]] (if [[doom-module::editor format]])
** TODO MacOS ** mono
*** TODO MacOS
** Arch Linux *** Arch Linux
#+begin_src sh #+begin_src sh
pacman --needed --noconfirm -S mono pacman --needed --noconfirm -S mono
#+end_src #+end_src
** TODO NixOS *** TODO NixOS
** csharpier
#+begin_src shell
dotnet tool install csharpier -g
#+end_src
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote

View file

@ -3,6 +3,7 @@
(use-package! csharp-mode (use-package! csharp-mode
:hook (csharp-mode . rainbow-delimiters-mode) :hook (csharp-mode . rainbow-delimiters-mode)
:config :config
(set-formatter! 'csharpier '("dotnet-csharpier") :modes '(csharp-mode))
(set-electric! 'csharp-mode :chars '(?\n ?\})) (set-electric! 'csharp-mode :chars '(?\n ?\}))
(set-rotate-patterns! 'csharp-mode (set-rotate-patterns! 'csharp-mode
:symbols '(("public" "protected" "private") :symbols '(("public" "protected" "private")

View file

@ -9,3 +9,7 @@
(assert! (or (not (modulep! +tree-sitter)) (assert! (or (not (modulep! +tree-sitter))
(modulep! :tools tree-sitter)) (modulep! :tools tree-sitter))
"This module requires (:tools tree-sitter)") "This module requires (:tools tree-sitter)")
(when (modulep! :editor format)
(unless (executable-find "dotnet-csharpier")
(warn! "csharpier is not installed, formatting will be disabled.")))

View file

@ -87,7 +87,7 @@ flutter doctor # for Dependency check and further instructions
🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]] 🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
#+end_quote #+end_quote
- Syntax highlighting and formatting for ~.dart~ files provided by LSP. - Syntax highlighting and formatting for ~.dart~ files provided by LSP or [[doom-module::editor format]].
- Auto import. - Auto import.
- Widget guide lines for Flutter. - Widget guide lines for Flutter.
- Closing labels for constructors. - Closing labels for constructors.

View file

@ -8,7 +8,8 @@
(setq nxml-slash-auto-complete-flag t (setq nxml-slash-auto-complete-flag t
nxml-auto-insert-xml-declaration-flag t) nxml-auto-insert-xml-declaration-flag t)
(set-company-backend! 'nxml-mode '(company-nxml company-yasnippet)) (set-company-backend! 'nxml-mode '(company-nxml company-yasnippet))
(setq-hook! 'nxml-mode-hook tab-width nxml-child-indent)) (setq-hook! 'nxml-mode-hook tab-width nxml-child-indent)
(set-formatter! 'xmllint '("xmllint" "--format" "-") :modes '(nxml-mode)))
;;;###package csv-mode ;;;###package csv-mode

View file

@ -0,0 +1,5 @@
;;; lang/data/doctor.el -*- lexical-binding: t; -*-
(when (modulep! :editor format)
(unless (executable-find "xmllint")
(warn! "Couldn't find xmllint. Formatting will be disabled.")))

View file

@ -74,6 +74,7 @@ zypper install elixir
- Phoenix support - Phoenix support
- ~iex~ integration ([[doom-module::tools eval]]) - ~iex~ integration ([[doom-module::tools eval]])
- Syntax checking ([[doom-module::checkers syntax]], using [[doom-package:flycheck-credo]]) - Syntax checking ([[doom-module::checkers syntax]], using [[doom-package:flycheck-credo]])
- Formatting for elixir files provided by [[doom-module::editor format]].
** exunit-mode ** exunit-mode
The exunit-mode prefix is [[kbd:][<localleader> t]]. Here is some examples: The exunit-mode prefix is [[kbd:][<localleader> t]]. Here is some examples:

View file

@ -43,6 +43,12 @@ This module adds [[https://elm-lang.org/][Elm]] support to Doom Emacs.
🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]] 🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]
#+end_quote #+end_quote
** formatter
By enabling [[doom-module::editor format]], [[doom-package:apheleia]] will be
used to format the current buffer.
Enable [[doom-module::editor format +onsave]] to format the buffer on save.
* TODO Configuration * TODO Configuration
#+begin_quote #+begin_quote
🔨 This module has no configuration documentation yet. [[doom-contrib-module:][Write some?]] 🔨 This module has no configuration documentation yet. [[doom-contrib-module:][Write some?]]

View file

@ -56,6 +56,12 @@ about it.
🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]] 🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]
#+end_quote #+end_quote
** formatter
By enabling [[doom-module::editor format]], [[doom-package:apheleia]] will be
used to format the current buffer.
Enable [[doom-module::editor format +onsave]] to format the buffer on save.
* TODO Configuration * TODO Configuration
#+begin_quote #+begin_quote
🔨 This module has no configuration documentation yet. [[doom-contrib-module:][Write some?]] 🔨 This module has no configuration documentation yet. [[doom-contrib-module:][Write some?]]

View file

@ -39,6 +39,7 @@ See `+emacs-lisp-non-package-mode' for details.")
:documentation #'+emacs-lisp-lookup-documentation) :documentation #'+emacs-lisp-lookup-documentation)
(set-docsets! '(emacs-lisp-mode lisp-interaction-mode) "Emacs Lisp") (set-docsets! '(emacs-lisp-mode lisp-interaction-mode) "Emacs Lisp")
(set-ligatures! 'emacs-lisp-mode :lambda "lambda") (set-ligatures! 'emacs-lisp-mode :lambda "lambda")
(set-formatter! 'lisp-indent #'apheleia--indent-lisp-buffer :modes '(emacs-lisp-mode))
(set-rotate-patterns! 'emacs-lisp-mode (set-rotate-patterns! 'emacs-lisp-mode
:symbols '(("t" "nil") :symbols '(("t" "nil")
("let" "let*") ("let" "let*")

View file

@ -39,13 +39,20 @@ Includes:
This module requires Erlang be installed (which includes ~erlang-mode~). Check This module requires Erlang be installed (which includes ~erlang-mode~). Check
your distribution's package manager or a version management tool such as [[https://github.com/kerl/kerl][kerl]]. your distribution's package manager or a version management tool such as [[https://github.com/kerl/kerl][kerl]].
For LSP support, install [[https://github.com/erlang/sourcer][sourcer]]. - [[https://github.com/erlang/sourcer][sourcer]] when [[doom-module::tools lsp]] & [[doom-module:+lsp]]
- [[https://github.com/sile/efmt][efmt]] when [[doom-module::editor format]]
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote
🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]] 🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]
#+end_quote #+end_quote
** formatter
By enabling [[doom-module::editor format]], [[doom-package:apheleia]] will be
used to format the current buffer.
Enable [[doom-module::editor format +onsave]] to format the buffer on save.
* TODO Configuration * TODO Configuration
#+begin_quote #+begin_quote
🔨 This module has no configuration documentation yet. [[doom-contrib-module:][Write some?]] 🔨 This module has no configuration documentation yet. [[doom-contrib-module:][Write some?]]

View file

@ -5,6 +5,7 @@
:mode ("/rebar\\.config\\(?:\\.script\\)?\\'" . erlang-mode) :mode ("/rebar\\.config\\(?:\\.script\\)?\\'" . erlang-mode)
:mode ("/\\(?:app\\|sys\\)\\.config\\'" . erlang-mode) :mode ("/\\(?:app\\|sys\\)\\.config\\'" . erlang-mode)
:config :config
(set-formatter! 'efmt '("efmt" "-") :modes '(erlang-mode))
(when (modulep! +lsp) (when (modulep! +lsp)
(add-hook 'erlang-mode-local-vars-hook #'lsp! 'append)) (add-hook 'erlang-mode-local-vars-hook #'lsp! 'append))

View file

@ -4,3 +4,7 @@
(assert! (or (not (modulep! +lsp)) (assert! (or (not (modulep! +lsp))
(modulep! :tools lsp)) (modulep! :tools lsp))
"This module requires (:tools lsp)") "This module requires (:tools lsp)")
(when (modulep! :editor format)
(unless (executable-find "efmt")
(warn! "Couldn't find efmt. Formatting will be disabled.")))

View file

@ -97,6 +97,11 @@ your Bash Profile, etc., and log out and in again._ Now Doom will be able to use
Good luck and happy computing! Good luck and happy computing!
** efmt
When [[doom-module::editor format]] is enabled and [[doom-executable:fprettify]] is installed, buffers can be formatted with [[fn:apheleia-format-buffer]].
Enable [[doom-module::editor format +onsave]] to format the buffer on save.
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote
🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]] 🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]

View file

@ -35,6 +35,8 @@
:desc "build" "b" #'+fortran/build :desc "build" "b" #'+fortran/build
:desc "run" "r" #'+fortran/run) :desc "run" "r" #'+fortran/run)
(set-formatter! 'fprettify '("fprettify" "-") :modes '(f90-mode fortran-mode))
(when (modulep! +intel) (when (modulep! +intel)
(map! :map f90-mode-map (map! :map f90-mode-map
:localleader :localleader

View file

@ -18,6 +18,8 @@
(when (modulep! +lsp) (when (modulep! +lsp)
(unless (executable-find "fortls") (unless (executable-find "fortls")
(warn! "Couldn't find fortls.")) (warn! "Couldn't find fortls. Language features will be disabled.")))
(when (modulep! :editor format)
(unless (executable-find "fprettify") (unless (executable-find "fprettify")
(warn! "Couldn't find fprettify."))) (warn! "Couldn't find fprettify. Formatting will be disabled.")))

View file

@ -48,6 +48,13 @@ pacman -S mono
** LSP ** LSP
The language server is automatically installed by [[https://github.com/emacs-lsp/lsp-mode/blob/master/clients/lsp-fsharp.el][lsp-fsharp]]. The language server is automatically installed by [[https://github.com/emacs-lsp/lsp-mode/blob/master/clients/lsp-fsharp.el][lsp-fsharp]].
** Fantomas
Fantomas is used for formatting via [[doom-module::editor format]] and can be installed as a [[https://dotnet.microsoft.com/en-us/download][dotnet]] tool.
#+begin_src shell
dotnet tool install -g fantomas-tool
#+end_src
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote
🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]] 🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]

View file

@ -11,6 +11,7 @@
(set-lookup-handlers! 'fsharp-mode :async t :definition #'fsharp-ac/gotodefn-at-point) (set-lookup-handlers! 'fsharp-mode :async t :definition #'fsharp-ac/gotodefn-at-point)
(set-company-backend! 'fsharp-mode 'fsharp-ac/company-backend)) (set-company-backend! 'fsharp-mode 'fsharp-ac/company-backend))
(set-repl-handler! 'fsharp-mode #'run-fsharp) (set-repl-handler! 'fsharp-mode #'run-fsharp)
(set-formatter! 'fantomas '("fantomas" "--stdin") :modes '(fsharp-mode))
(map! :localleader (map! :localleader
:map fsharp-mode-map :map fsharp-mode-map
"b" #'fsharp-ac/pop-gotodefn-stack ; Useful for re-tracing your steps "b" #'fsharp-ac/pop-gotodefn-stack ; Useful for re-tracing your steps

View file

@ -13,6 +13,8 @@
(set-lookup-handlers! 'gdscript-mode (set-lookup-handlers! 'gdscript-mode
:documentation #'gdscript-docs-browse-symbol-at-point) :documentation #'gdscript-docs-browse-symbol-at-point)
(set-formatter! 'gdformat '("gdformat" "-") :modes '(gdscript-mode))
(when (modulep! +lsp) (when (modulep! +lsp)
(add-hook 'gdscript-mode-local-vars-hook #'lsp! 'append)) (add-hook 'gdscript-mode-local-vars-hook #'lsp! 'append))

View file

@ -0,0 +1,5 @@
;;; lang/gdscript/doctor.el -*- lexical-binding: t; -*-
(when (modulep! :editor format)
(unless (executable-find "gdformat")
(warn! "Couldn't find gdformat. Formatting will be disabled.")))

View file

@ -11,14 +11,6 @@
:references #'go-guru-referrers :references #'go-guru-referrers
:documentation #'godoc-at-point) :documentation #'godoc-at-point)
;; Redefines default formatter to *not* use goimports if reformatting a
;; region; as it doesn't play well with partial code.
(set-formatter! 'gofmt
'(("%s" (if (or +format-region-p
(not (executable-find "goimports")))
"gofmt"
"goimports"))))
(if (modulep! +lsp) (if (modulep! +lsp)
(add-hook 'go-mode-local-vars-hook #'lsp! 'append) (add-hook 'go-mode-local-vars-hook #'lsp! 'append)
(add-hook 'go-mode-hook #'go-eldoc-setup)) (add-hook 'go-mode-hook #'go-eldoc-setup))

View file

@ -43,9 +43,15 @@ It includes:
* Installation * Installation
[[id:01cffea4-3329-45e2-a892-95a384ab2338][Enable this module in your ~doom!~ block.]] [[id:01cffea4-3329-45e2-a892-95a384ab2338][Enable this module in your ~doom!~ block.]]
** LSP
This module has no direct requirements, but the +lsp flag requires a [[https://emacs-lsp.github.io/lsp-mode/page/lsp-graphql/][supported This module has no direct requirements, but the +lsp flag requires a [[https://emacs-lsp.github.io/lsp-mode/page/lsp-graphql/][supported
LSP server]]. LSP server]].
** Formatter
Formatting is handled using the [[doom-module::editor format]] module via [[https://prettier.io/docs/en/install.html][prettier]].
* Usage * Usage
** Sending queries ** Sending queries
When visiting a graphql buffer, you have access to the ability to send the When visiting a graphql buffer, you have access to the ability to send the

View file

@ -52,6 +52,11 @@ system package manager, cabal, or stack.
formatters such as [[https://github.com/lspitzner/brittany][brittany]], [[https://github.com/ennocramer/floskell][floskell]], [[https://github.com/tweag/ormolu][ormolu]], [[https://github.com/fourmolu/fourmolu][fourmolu]], and [[https://github.com/haskell/stylish-haskell][stylish-haskell]], formatters such as [[https://github.com/lspitzner/brittany][brittany]], [[https://github.com/ennocramer/floskell][floskell]], [[https://github.com/tweag/ormolu][ormolu]], [[https://github.com/fourmolu/fourmolu][fourmolu]], and [[https://github.com/haskell/stylish-haskell][stylish-haskell]],
which can be installed through system package manager, cabal, or stack. which can be installed through system package manager, cabal, or stack.
** Formatter
[[doom-module::editor format]] by default uses [[https://github.com/fourmolu/fourmolu#installation][fourmolu]] to format code when not
relying on hls, follow the linked install instructions.
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote
🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]] 🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
@ -61,12 +66,12 @@ This module integrates the haskell packages into Doom by providing things such
as REPL support, project root recognition, etc. It also provide the following as REPL support, project root recognition, etc. It also provide the following
keybindings: keybindings:
| Keybinding | Description | | Keybinding | Description |
|-----------------+-----------------------------------------------| |-----------------+---------------------------------------------|
| [[kbd:][<localleader> b]] | Build the current cabal project | | [[kbd:][<localleader> b]] | Build the current cabal project |
| [[kbd:][<localleader> c]] | Visit the =.cabal= file of the current buffer | | [[kbd:][<localleader> c]] | Visit the =.cabal= file of the current buffer |
| [[kbd:][<localleader> h]] | Toggle visibility of the form at point | | [[kbd:][<localleader> h]] | Toggle visibility of the form at point |
| [[kbd:][<localleader> H]] | hides all top level functions | | [[kbd:][<localleader> H]] | hides all top level functions |
* TODO Configuration * TODO Configuration
#+begin_quote #+begin_quote

View file

@ -5,4 +5,5 @@
:interpreter "hy" :interpreter "hy"
:config :config
(set-repl-handler! 'hy-mode #'hy-shell-start-or-switch-to-shell) (set-repl-handler! 'hy-mode #'hy-shell-start-or-switch-to-shell)
(set-formatter! 'lisp-indent #'apheleia--indent-lisp-buffer :modes '(hy-mode))
(set-company-backend! 'hy-mode 'company-hy)) (set-company-backend! 'hy-mode 'company-hy))

View file

@ -98,6 +98,18 @@ JAVA_HOME=~/.jabba/jdk/adopt@1.11.0-3
And then run ~$ direnv allow .~ in the project directory. The [[doom-module::tools direnv]] And then run ~$ direnv allow .~ in the project directory. The [[doom-module::tools direnv]]
module will automatically source this environment before activating LSP servers. module will automatically source this environment before activating LSP servers.
** Formatter
[[doom-module::editor format]] uses [[https://github.com/google/google-java-format][google-java-format]] to handle formatting.
To install, grab the latest =all-deps.jar= release from the above, put it
somewhere and create a script similar to the below:
=/usr/local/bin/google-java-format=
#+begin_src shell
java -jar /path/to/google-java-format-all-deps.jar
#+end_src
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote
🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]] 🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]

View file

@ -58,6 +58,10 @@ This module requires [[https://nodejs.org/en/][NodeJS]] and one of [[https://www
- Arch Linux: ~$ pacman --needed --noconfirm -S nodejs npm~ - Arch Linux: ~$ pacman --needed --noconfirm -S nodejs npm~
- openSUSE: ~$ zypper install nodejs npm~ - openSUSE: ~$ zypper install nodejs npm~
** Formatter
Formatting is handled using the [[doom-module::editor format]] module via [[https://prettier.io/docs/en/install.html][prettier]].
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote
🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]] 🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]

View file

@ -32,7 +32,9 @@ This module adds [[https://www.json.org/json-en.html][JSON]] support to Doom Ema
* Installation * Installation
[[id:01cffea4-3329-45e2-a892-95a384ab2338][Enable this module in your ~doom!~ block.]] [[id:01cffea4-3329-45e2-a892-95a384ab2338][Enable this module in your ~doom!~ block.]]
/This module has no external requirements./ ** Formatter
Formatting is handled using the [[doom-module::editor format]] module via [[https://prettier.io/docs/en/install.html][prettier]].
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote

View file

@ -25,12 +25,22 @@ This module adds [[https://kotlinlang.org/][Kotlin]] support to Doom Emacs.
# This section will be machine generated. Don't edit it by hand. # This section will be machine generated. Don't edit it by hand.
/This module does not have a changelog yet./ /This module does not have a changelog yet./
* TODO Installation * Installation
[[id:01cffea4-3329-45e2-a892-95a384ab2338][Enable this module in your ~doom!~ block.]] [[id:01cffea4-3329-45e2-a892-95a384ab2338][Enable this module in your ~doom!~ block.]]
#+begin_quote Install kotlin through your distribution's package manager, eg:
🔨 /This module's prerequisites are not documented./ [[doom-contrib-module:][Document them?]]
#+end_quote #+begin_src shell
sudo apt install kotlin # Ubuntu
sudo pacman -S kotlin # Arch Linux
brew install kotlin # MacOS
#+end_src
or by getting the [[https://github.com/JetBrains/kotlin/releases/latest][latest]] release and adding to your =$PATH= manually.
** Formatter
Formatting is handled using the [[doom-module::editor format]] module via [[https://pinterest.github.io/ktlint/install/cli/][ktlint]].
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote

View file

@ -93,6 +93,10 @@ brew install --cask mactex # WARNING: large 4gb download!
environment.systemPackages = [ pkgs.texlive.combined.scheme-medium ]; environment.systemPackages = [ pkgs.texlive.combined.scheme-medium ];
#+end_src #+end_src
** Formatter
Formatting is handled using the [[doom-module::editor format]] module via [[https://github.com/cmhughes/latexindent.pl][latexindent]].
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote
🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]] 🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]

View file

@ -75,6 +75,10 @@ Eglot currently only supports one of the above servers out of the box:
=$EMACSDIR/.local/etc/lsp/lua-language-server/=. See ~+lua-lsp-dir~ variable =$EMACSDIR/.local/etc/lsp/lua-language-server/=. See ~+lua-lsp-dir~ variable
to change this. to change this.
** Formatter
Formatting is handled using the [[doom-module::editor format]] module via [[https://github.com/JohnnyMorganz/StyLua#installation][Stylua]].
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote
🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]] 🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]

View file

@ -115,6 +115,10 @@ installed through your OS's package manager:
+ MacOS: ~$ brew install multimarkdown~ + MacOS: ~$ brew install multimarkdown~
+ Arch Linux: [[https://aur.archlinux.org/packages/multimarkdown/][multimarkdown]] is available on the AUR + Arch Linux: [[https://aur.archlinux.org/packages/multimarkdown/][multimarkdown]] is available on the AUR
** Formatter
Formatting is handled using the [[doom-module::editor format]] module via [[https://prettier.io/docs/en/install.html][prettier]].
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote
🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]] 🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]

View file

@ -51,6 +51,10 @@ Alternatively, nim is usually available through your OS's package manager:
- Arch Linux: ~$ pacman --needed --noconfirm -S nim nimble~ - Arch Linux: ~$ pacman --needed --noconfirm -S nim nimble~
- openSUSE: ~$ zypper install nim~ - openSUSE: ~$ zypper install nim~
** Formatter
Formatting is handled using the [[doom-module::editor format]] module via [[https://github.com/FedericoCeratto/nimfmt#installation][nimfmt]].
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote
🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]] 🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]

View file

@ -12,6 +12,8 @@ nimsuggest isn't installed."
(when (and nimsuggest-path (file-executable-p nimsuggest-path)) (when (and nimsuggest-path (file-executable-p nimsuggest-path))
(nimsuggest-mode)))) (nimsuggest-mode))))
(set-formatter! 'nmfmt '("nimfmt" filepath) :modes '(nim-mode))
(when IS-WINDOWS (when IS-WINDOWS
;; TODO File PR/report upstream (https://github.com/nim-lang/nim-mode) ;; TODO File PR/report upstream (https://github.com/nim-lang/nim-mode)
(defadvice! +nim--suggest-get-temp-file-name-a (path) (defadvice! +nim--suggest-get-temp-file-name-a (path)

View file

@ -1,4 +1,4 @@
;; -*- lexical-binding: t; no-byte-compile: t; -*-
;;; lang/nim/doctor.el ;;; lang/nim/doctor.el
(unless (executable-find "nimsuggest") (unless (executable-find "nimsuggest")
@ -7,3 +7,6 @@
(unless (executable-find "nim") (unless (executable-find "nim")
(warn! "Could not find nim executable; build commands will be disabled.")) (warn! "Could not find nim executable; build commands will be disabled."))
(when (modulep! :editor format)
(unless (executable-find "nimfmt")
(warn! "Could not find nimfmt. Formatting will be disabled.")))

View file

@ -107,8 +107,6 @@
:commands ocamlformat :commands ocamlformat
:hook (tuareg-mode-local-vars . +ocaml-init-ocamlformat-h) :hook (tuareg-mode-local-vars . +ocaml-init-ocamlformat-h)
:config :config
(set-formatter! 'ocamlformat #'ocamlformat
:modes '(caml-mode tuareg-mode))
;; TODO Fix region-based formatting support ;; TODO Fix region-based formatting support
(defun +ocaml-init-ocamlformat-h () (defun +ocaml-init-ocamlformat-h ()
(setq +format-with 'ocp-indent) (setq +format-with 'ocp-indent)

View file

@ -30,7 +30,6 @@
(set-docsets! 'php-mode "PHP" "PHPUnit" "Laravel" "CakePHP" "CodeIgniter" "Doctrine_ORM") (set-docsets! 'php-mode "PHP" "PHPUnit" "Laravel" "CakePHP" "CodeIgniter" "Doctrine_ORM")
(set-repl-handler! 'php-mode #'+php/open-repl) (set-repl-handler! 'php-mode #'+php/open-repl)
(set-lookup-handlers! 'php-mode :documentation #'php-search-documentation) (set-lookup-handlers! 'php-mode :documentation #'php-search-documentation)
(set-formatter! 'php-mode #'php-cs-fixer-fix)
(set-ligatures! 'php-mode (set-ligatures! 'php-mode
;; Functional ;; Functional
:lambda "function()" :lambda "fn" :lambda "function()" :lambda "fn"

View file

@ -26,12 +26,20 @@ This module adds [[https://www.purescript.org/][Purescript]] support to Doom Ema
# This section will be machine generated. Don't edit it by hand. # This section will be machine generated. Don't edit it by hand.
/This module does not have a changelog yet./ /This module does not have a changelog yet./
* TODO Installation * Installation
[[id:01cffea4-3329-45e2-a892-95a384ab2338][Enable this module in your ~doom!~ block.]] [[id:01cffea4-3329-45e2-a892-95a384ab2338][Enable this module in your ~doom!~ block.]]
#+begin_quote The main tools for PureScript are installed via npm.
🔨 /This module's prerequisites are not documented./ [[doom-contrib-module:][Document them?]]
#+end_quote ** Compiler
#+begin_src shell
npm install -g purescript spago
#+end_src
** Formatter
#+begin_src sh
npm install -g purs-tidy
#+end_src
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote

View file

@ -8,6 +8,8 @@
#'purescript-indentation-mode #'purescript-indentation-mode
#'rainbow-delimiters-mode) #'rainbow-delimiters-mode)
(set-formatter! 'purs-tidy '("purs-tidy" "format") :modes '(purescript-mode))
(map! :localleader (map! :localleader
:map purescript-mode-map :map purescript-mode-map
"t" #'psc-ide-show-type "t" #'psc-ide-show-type

View file

@ -0,0 +1,5 @@
;;; lang/purescript/doctor.el -*- lexical-binding: t; -*-
(when (modulep! :editor format)
(unless (executable-find "purs-tidy")
(warn! "Could not find purs-tidy. Formatting will be disabled.")))

View file

@ -92,6 +92,10 @@ An alternative LSP server can be used by installing them through the
- To install *mspyls*: ~M-x lsp-install-server RET mspyls~. - To install *mspyls*: ~M-x lsp-install-server RET mspyls~.
- To install *pyright*: ~$ pip install pyright~ or ~$ npm i -g pyright~. - To install *pyright*: ~$ pip install pyright~ or ~$ npm i -g pyright~.
** Formatter
Formatting is handled using the [[doom-module::editor format]] module via [[https://black.readthedocs.io/en/stable/getting_started.html#installation][black]].
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote
🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]] 🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]

View file

@ -43,6 +43,10 @@ Or, for fewer dependencies:
pacman -S racket-minimal pacman -S racket-minimal
#+end_src #+end_src
** Formatter
Formatting is handled using the [[doom-module::editor format]] module via [[https://docs.racket-lang.org/fmt/][fmt]].
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote
🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]] 🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]

View file

@ -21,6 +21,7 @@
:dot ".") :dot ".")
(set-rotate-patterns! 'racket-mode (set-rotate-patterns! 'racket-mode
:symbols '(("#true" "#false"))) :symbols '(("#true" "#false")))
(set-formatter! 'raco-fmt '("raco" "fmt") :modes '(racket-mode))
(add-hook! 'racket-mode-hook (add-hook! 'racket-mode-hook
#'rainbow-delimiters-mode #'rainbow-delimiters-mode

View file

@ -9,3 +9,8 @@
(unless (executable-find "raco") (unless (executable-find "raco")
(warn! "Could not find raco executable; commands for install packages and build libraries will not work.")) (warn! "Could not find raco executable; commands for install packages and build libraries will not work."))
(when (modulep! :editor format)
(unless (and (executable-find "raco")
(eq 0 (call-process-shell-command "raco fmt --help" nil nil)))
(warn! "Couldn't find raco fmt. Formatting will be disabled.")))

View file

@ -27,6 +27,10 @@ This module adds [[https://docutils.sourceforge.io/rst.html][ReStructured Text]]
This module requires [[https://www.sphinx-doc.org/en/master/usage/installation.html][sphinx]] to build RST documents. This module requires [[https://www.sphinx-doc.org/en/master/usage/installation.html][sphinx]] to build RST documents.
** Formatter
Formatting is handled using the [[doom-module::editor format]] module via [[https://github.com/dzhu/rstfmt#usage][rstfmt]].
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote
🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]] 🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]

View file

@ -1,7 +1,9 @@
;;; lang/rst/config.el -*- lexical-binding: t; -*- ;;; lang/rst/config.el -*- lexical-binding: t; -*-
(use-package! sphinx-mode (use-package! sphinx-mode
:hook (rst-mode . sphinx-mode)) :hook (rst-mode . sphinx-mode)
:config
(set-formatter! 'rstfmt '("rstfmt") :modes '(rst-mode)))
(use-package! rst (use-package! rst
:defer t :defer t

View file

@ -0,0 +1,5 @@
;;; lang/rst/doctor.el -*- lexical-binding: t; -*-
(when (modulep! :editor format)
(unless (executable-find "rstfmt")
(warn! "Couldn't find rstfmt. Formatting will be disabled.")))

View file

@ -70,6 +70,10 @@ These guides will help you install Ruby:
Then run ~$ gem install rubocop~ to install rubocop. Then run ~$ gem install rubocop~ to install rubocop.
** Formatter
Formatting is handled using the [[doom-module::editor format]] module via [[https://prettier.io/docs/en/install.html][prettier]].
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote
🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]] 🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]

View file

@ -64,7 +64,7 @@ To install and manage Rust on Windows, consult [[https://forge.rust-lang.org/inf
** Other Requirements ** Other Requirements
- If [[doom-module::editor format]] is enabled, you'll need =rustfmt=: ~$ rustup component add - If [[doom-module::editor format]] is enabled, you'll need =rustfmt=: ~$ rustup component add
rustfmt-preview~. rustfmt~.
- Users with [[doom-module:+lsp]] enabled will need [[github:rust-analyzer/rust-analyzer][rust-analyzer]] (rls is supported, - Users with [[doom-module:+lsp]] enabled will need [[github:rust-analyzer/rust-analyzer][rust-analyzer]] (rls is supported,
but [[https://blog.rust-lang.org/2022/07/01/RLS-deprecation.html][deprecated]]). but [[https://blog.rust-lang.org/2022/07/01/RLS-deprecation.html][deprecated]]).
- Using the following commands requires: - Using the following commands requires:

View file

@ -95,6 +95,10 @@ coursier bootstrap \
yay -S metals yay -S metals
#+end_src #+end_src
** Formatter
Formatting is handled using the [[doom-module::editor format]] module via [[https://scalameta.org/scalafmt/docs/installation.html#cli][scalafmt]].
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote
🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]] 🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]

View file

@ -22,6 +22,8 @@
(when (modulep! +tree-sitter) (when (modulep! +tree-sitter)
(add-hook 'scala-mode-local-vars-hook #'tree-sitter! 'append)) (add-hook 'scala-mode-local-vars-hook #'tree-sitter! 'append))
(set-formatter! 'scalafmt '("scalafmt" "--stdin") :modes '(scala-mode))
(set-ligatures! 'scala-mode (set-ligatures! 'scala-mode
;; Functional ;; Functional
:def "def" :def "def"

View file

@ -11,3 +11,7 @@
(if (and (modulep! +lsp) (if (and (modulep! +lsp)
(not (executable-find "metals"))) (not (executable-find "metals")))
(warn! "metals isn't installed")) (warn! "metals isn't installed"))
(when (modulep! :editor format)
(unless (executable-find "scalafmt")
(warn! "Couldn't find scalafmt. Formatting will be disabled.")))

View file

@ -3,7 +3,9 @@
(use-package! scheme (use-package! scheme
:interpreter ("scsh" . scheme-mode) :interpreter ("scsh" . scheme-mode)
:hook (scheme-mode . rainbow-delimiters-mode) :hook (scheme-mode . rainbow-delimiters-mode)
:config (advice-add #'scheme-indent-function :override #'+scheme-indent-function-a)) :config
(set-formatter! 'lisp-indent #'apheleia--indent-lisp-buffer :modes '(scheme-mode))
(advice-add #'scheme-indent-function :override #'+scheme-indent-function-a))
(use-package! geiser (use-package! geiser

View file

@ -49,6 +49,8 @@ This module has several optional dependencies:
- With the [[doom-module::tools debugger]] module - With the [[doom-module::tools debugger]] module
- [[http://bashdb.sourceforge.net/][bashdb]]: Enables debugging for bash scripts - [[http://bashdb.sourceforge.net/][bashdb]]: Enables debugging for bash scripts
- [[https://github.com/rocky/zshdb][zshdb]]: Enables debugging for zsh scripts - [[https://github.com/rocky/zshdb][zshdb]]: Enables debugging for zsh scripts
- With the [[doom-module::editor format]] module
- [[https://github.com/patrickvane/shfmt][shfmt]]: Enables formatting for {posix,ba,mk}sh scripts
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote

View file

@ -17,10 +17,10 @@
:config :config
(set-docsets! 'sh-mode "Bash") (set-docsets! 'sh-mode "Bash")
(set-electric! 'sh-mode :words '("else" "elif" "fi" "done" "then" "do" "esac" ";;")) (set-electric! 'sh-mode :words '("else" "elif" "fi" "done" "then" "do" "esac" ";;"))
(set-formatter! 'shfmt (set-formatter! 'shfmt '("shfmt" "-ci"
'("shfmt" "-ci" (unless indent-tabs-mode
("-i" "%d" (unless indent-tabs-mode tab-width)) (list "-i" (number-to-string tab-width)))))
("-ln" "%s" (pcase sh-shell (`bash "bash") (`mksh "mksh") (_ "posix")))))
(set-repl-handler! 'sh-mode #'+sh/open-repl) (set-repl-handler! 'sh-mode #'+sh/open-repl)
(set-lookup-handlers! 'sh-mode :documentation #'+sh-lookup-documentation-handler) (set-lookup-handlers! 'sh-mode :documentation #'+sh-lookup-documentation-handler)
(set-ligatures! 'sh-mode (set-ligatures! 'sh-mode
@ -85,10 +85,6 @@
;; whatis lookups are exceptionally slow on macOS (#5860) ;; whatis lookups are exceptionally slow on macOS (#5860)
company-shell-dont-fetch-meta IS-MAC)) company-shell-dont-fetch-meta IS-MAC))
(use-package! fish-mode
:when (modulep! +fish)
:defer t
:config (set-formatter! 'fish-mode #'fish_indent))
(use-package! powershell (use-package! powershell
:when (modulep! +powershell) :when (modulep! +powershell)

View file

@ -28,6 +28,10 @@ THis module adds [[https://smlfamily.github.io/][SML (Standard ML) programming l
This module requires =sml= and =MLton=. This module requires =sml= and =MLton=.
** Formatter
Formatting is handled using the [[doom-module::editor format]] module via [[https://github.com/jluningp/smlformat#installation][smlformat]].
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote
🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]] 🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]

View file

@ -4,6 +4,7 @@
:mode "\\.s\\(?:ml\\|ig\\)\\'" :mode "\\.s\\(?:ml\\|ig\\)\\'"
:config :config
(set-repl-handler! 'sml-mode #'run-sml) (set-repl-handler! 'sml-mode #'run-sml)
(set-formatter! 'smlformat '("smlformat") :modes '(sml-mode))
;; don't auto-close apostrophes (type 'a = foo) and backticks (`Foo) ;; don't auto-close apostrophes (type 'a = foo) and backticks (`Foo)
(sp-with-modes 'sml-mode (sp-with-modes 'sml-mode

View file

@ -0,0 +1,5 @@
;;; lang/sml/doctor.el -*- lexical-binding: t; -*-
(when (modulep! :editor format)
(unless (executable-find "smlformat")
(warn! "Couldn't find smlformat. Formatting will be disabled.")))

View file

@ -55,6 +55,10 @@ can set it to your own =.soliumrc.json= with:
(setq flycheck-solidity-solium-soliumrcfile "~/.soliumrc.json") (setq flycheck-solidity-solium-soliumrcfile "~/.soliumrc.json")
#+end_src #+end_src
** Formatter
Formatting is handled using the [[doom-module::editor format]] module via [[https://github.com/prettier-solidity/prettier-plugin-solidity#installation-and-usage][prettier]].
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote
🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]] 🔨 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]

View file

@ -7,6 +7,7 @@
(setq solidity-comment-style 'slash) (setq solidity-comment-style 'slash)
(set-docsets! 'solidity-mode "Solidity") (set-docsets! 'solidity-mode "Solidity")
(set-company-backend! 'solidity-mode 'company-solidity) (set-company-backend! 'solidity-mode 'company-solidity)
(set-formatter! 'prettier-solidity '(npx "prettier" "--stdin-filepath" filepath "--parser=solidity") :modes '(solidity-mode))
(use-package! solidity-flycheck ; included with solidity-mode (use-package! solidity-flycheck ; included with solidity-mode
:when (and (modulep! :checkers syntax) :when (and (modulep! :checkers syntax)

View file

@ -35,6 +35,10 @@ This module adds support for the [[https://developer.apple.com/swift/][Swift pro
* TODO Installation * TODO Installation
[[id:01cffea4-3329-45e2-a892-95a384ab2338][Enable this module in your ~doom!~ block.]] [[id:01cffea4-3329-45e2-a892-95a384ab2338][Enable this module in your ~doom!~ block.]]
** Formatter
Formatting is handled using the [[doom-module::editor format]] module via [[https://github.com/nicklockwood/SwiftFormat#command-line-tool][swiftformat]].
#+begin_quote #+begin_quote
🔨 /This module's prerequisites are not documented./ [[doom-contrib-module:][Document them?]] 🔨 /This module's prerequisites are not documented./ [[doom-contrib-module:][Document them?]]
#+end_quote #+end_quote

View file

@ -27,6 +27,7 @@
:after swift-mode :after swift-mode
:init (add-hook 'swift-mode-local-vars-hook #'lsp! 'append) :init (add-hook 'swift-mode-local-vars-hook #'lsp! 'append)
:config :config
(set-formatter! 'swiftformat '("swiftformat" "--output" "stdout"))
(setq lsp-sourcekit-executable (setq lsp-sourcekit-executable
(cl-find-if #'executable-find (cl-find-if #'executable-find
(list lsp-sourcekit-executable ; 'sourcekit-lsp' by default (list lsp-sourcekit-executable ; 'sourcekit-lsp' by default

View file

@ -3,3 +3,7 @@
(assert! (or (not (modulep! +tree-sitter)) (assert! (or (not (modulep! +tree-sitter))
(modulep! :tools tree-sitter)) (modulep! :tools tree-sitter))
"This module requires (:tools tree-sitter)") "This module requires (:tools tree-sitter)")
(when (modulep! :editor format)
(unless (executable-find "swiftformat")
(warn! "Couldn't find swiftformat. Formatting will be disabled.")))

View file

@ -27,15 +27,15 @@
;; tidy is already defined by the format-all package. We redefine it to add ;; tidy is already defined by the format-all package. We redefine it to add
;; more sensible arguments to the tidy command. ;; more sensible arguments to the tidy command.
(set-formatter! 'html-tidy ;; (set-formatter! 'html-tidy
'("tidy" "-q" "-indent" ;; '("tidy" "-q" "-indent"
"--tidy-mark" "no" ;; "--tidy-mark" "no"
"--drop-empty-elements" "no" ;; "--drop-empty-elements" "no"
("--show-body-only" "%s" (if +format-region-p "true" "auto")) ;; ("--show-body-only" "%s" (if +format-region-p "true" "auto"))
("--indent-spaces" "%d" tab-width) ;; ("--indent-spaces" "%d" tab-width)
("--indent-with-tabs" "%s" (if indent-tabs-mode "yes" "no")) ;; ("--indent-with-tabs" "%s" (if indent-tabs-mode "yes" "no"))
("-xml" (memq major-mode '(nxml-mode xml-mode)))) ;; ("-xml" (memq major-mode '(nxml-mode xml-mode))))
:ok-statuses '(0 1)) ;; :ok-statuses '(0 1))
(setq web-mode-enable-html-entities-fontification t (setq web-mode-enable-html-entities-fontification t
web-mode-auto-close-style 1) web-mode-auto-close-style 1)

View file

@ -48,6 +48,10 @@ ReactJS, Wordpress, Jekyll, Phaser, AngularJS, Djano, and more.
* TODO Installation * TODO Installation
[[id:01cffea4-3329-45e2-a892-95a384ab2338][Enable this module in your ~doom!~ block.]] [[id:01cffea4-3329-45e2-a892-95a384ab2338][Enable this module in your ~doom!~ block.]]
** Formatter
Formatting is handled using the [[doom-module::editor format]] module via [[https://prettier.io/docs/en/install.html][prettier]].
#+begin_quote #+begin_quote
🔨 /No installation steps have been documented./ [[doom-contrib-module:][Document them?]] 🔨 /No installation steps have been documented./ [[doom-contrib-module:][Document them?]]
#+end_quote #+end_quote

View file

@ -30,7 +30,9 @@ This module provides support for the [[https://yaml.org/][YAML file format]] to
* Installation * Installation
[[id:01cffea4-3329-45e2-a892-95a384ab2338][Enable this module in your ~doom!~ block.]] [[id:01cffea4-3329-45e2-a892-95a384ab2338][Enable this module in your ~doom!~ block.]]
/This module has no external requirements./ ** Formatter
Formatting is handled using the [[doom-module::editor format]] module via [[https://prettier.io/docs/en/install.html][prettier]].
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote

View file

@ -11,6 +11,7 @@
:hook (zig-mode . rainbow-delimiters-mode) :hook (zig-mode . rainbow-delimiters-mode)
:config :config
(setq zig-format-on-save nil) ; rely on :editor format instead (setq zig-format-on-save nil) ; rely on :editor format instead
(set-formatter! 'zigfmt '("zig" "fmt" "--stdin") :modes '(zig-mode))
(when (modulep! +lsp) (when (modulep! +lsp)
(add-hook 'zig-mode-local-vars-hook #'lsp! 'append)) (add-hook 'zig-mode-local-vars-hook #'lsp! 'append))

View file

@ -10,7 +10,10 @@
"This module requires (:tools tree-sitter)") "This module requires (:tools tree-sitter)")
(unless (executable-find "zig") (unless (executable-find "zig")
(warn! "Couldn't find zig binary")) (warn! "Couldn't find zig binary")
(unless (modulep! :editor format)
(warn! "Formatting will be disabled")))
(when (modulep! +lsp) (when (modulep! +lsp)
(unless (executable-find "zls") (unless (executable-find "zls")

View file

@ -40,6 +40,7 @@ installed and accessible from your PATH.
Optionally, this module also uses the following programs: Optionally, this module also uses the following programs:
- =docker-langserver= (for LSP users): ~$ npm install -g - =docker-langserver= (for LSP users): ~$ npm install -g
dockerfile-language-server-nodejs~ dockerfile-language-server-nodejs~
- =dockfmt= for [[doom-module::editor format]]: https://github.com/jessfraz/dockfmt#installation
* TODO Usage * TODO Usage
#+begin_quote #+begin_quote

View file

@ -2,6 +2,7 @@
(after! dockerfile-mode (after! dockerfile-mode
(set-docsets! 'dockerfile-mode "Docker") (set-docsets! 'dockerfile-mode "Docker")
(set-formatter! 'dockfmt '("dockfmt" "fmt" filepath) :modes '(dockerfile-mode))
(when (modulep! +lsp) (when (modulep! +lsp)
(add-hook 'dockerfile-mode-local-vars-hook #'lsp! 'append))) (add-hook 'dockerfile-mode-local-vars-hook #'lsp! 'append)))

View file

@ -0,0 +1,5 @@
;;; tools/docker/doctor.el -*- lexical-binding: t; -*-
(when (modulep! :editor format)
(unless (executable-find "dockfmt")
(warn! "Couldn't find dockfmt. Formatting will be disabled.")))

View file

@ -116,6 +116,11 @@ is deferred until the file is saved. Respects `git-gutter:disabled-modes'."
;; UX: update git-gutter on focus (in case I was using git externally) ;; UX: update git-gutter on focus (in case I was using git externally)
(add-hook 'focus-in-hook #'git-gutter:update-all-windows) (add-hook 'focus-in-hook #'git-gutter:update-all-windows)
;; Stop git-gutter doing things when we don't want
(remove-hook 'post-command-hook #'git-gutter:post-command-hook)
(advice-remove #'quit-window #'git-gutter:quit-window)
(advice-remove #'switch-to-buffer #'git-gutter:switch-to-buffer)
(add-hook! '(doom-escape-hook doom-switch-window-hook) :append (add-hook! '(doom-escape-hook doom-switch-window-hook) :append
(defun +vc-gutter-update-h (&rest _) (defun +vc-gutter-update-h (&rest _)
"Refresh git-gutter on ESC. Return nil to prevent shadowing other "Refresh git-gutter on ESC. Return nil to prevent shadowing other
@ -130,6 +135,9 @@ is deferred until the file is saved. Respects `git-gutter:disabled-modes'."
(advice-add #'magit-stage-file :after #'+vc-gutter-update-h) (advice-add #'magit-stage-file :after #'+vc-gutter-update-h)
(advice-add #'magit-unstage-file :after #'+vc-gutter-update-h) (advice-add #'magit-unstage-file :after #'+vc-gutter-update-h)
;; UX: update git-gutter after reverting a buffer
(add-hook 'after-revert-hook #'+vc-gutter-update-h)
;; FIX: stop git-gutter:{next,previous}-hunk from jumping to random hunks. ;; FIX: stop git-gutter:{next,previous}-hunk from jumping to random hunks.
(defadvice! +vc-gutter--fix-linearity-of-hunks-a (diffinfos is-reverse) (defadvice! +vc-gutter--fix-linearity-of-hunks-a (diffinfos is-reverse)
:override #'git-gutter:search-near-diff-index :override #'git-gutter:search-near-diff-index