dev: merge branch 'master'

This commit is contained in:
Matt Nish-Lapidus 2024-07-08 09:03:24 -04:00
commit ad8f5470b0
39 changed files with 433 additions and 661 deletions

View file

@ -769,7 +769,7 @@ original state.")
(let ((doom-output-indent 0))
(terpri)
(print! (warn "Aborted")))
(doom-cli--exit 1))
(doom-cli--exit 1 doom-cli--context))
(nreverse options)))
(prompt
(format! "How to proceed? (%s%s) "

View file

@ -177,4 +177,6 @@ Also resizees `doom-variable-pitch-font' and `doom-serif-font'."
(font-get (doom-normalize-font doom-big-font) :size))
t `((doom-font . ,doom-big-font)))
;; Resize the current font
(doom-adjust-font-size (if doom-big-font-mode doom-big-font-increment))))
(doom-adjust-font-size nil)
(when doom-big-font-mode
(doom-adjust-font-size doom-big-font-increment))))

View file

@ -152,11 +152,12 @@ If DIR is not a project, it will be indexed (but not cached)."
((and (bound-and-true-p ivy-mode)
(fboundp 'counsel-file-jump))
(call-interactively #'counsel-file-jump))
((when-let ((pr (project-current nil dir)))
(project-find-file-in nil nil pr)))
((and (bound-and-true-p helm-mode)
(fboundp 'helm-find-files))
(call-interactively #'helm-find-files))
((when-let ((project-current-directory-override t)
(pr (project-current t dir)))
(project-find-file-in nil nil pr)))
((call-interactively #'find-file)))))
;;;###autoload

View file

@ -36,7 +36,7 @@
(interactive)
(if (modulep! :ui workspaces)
(when (+workspace-exists-p +calendar-workspace-name)
(+workspace/delete +calendar-workspace-name))
(+workspace/kill +calendar-workspace-name))
(when (window-configuration-p +calendar--wconf)
(set-window-configuration +calendar--wconf))
(setq +calendar--wconf nil))

View file

@ -60,7 +60,7 @@ workspace for it."
(mapc #'kill-buffer (doom-buffers-in-mode 'circe-mode (buffer-list) t))
(when (modulep! :ui workspaces)
(when (equal (+workspace-current-name) +irc--workspace-name)
(+workspace/delete +irc--workspace-name)))))
(+workspace/kill +irc--workspace-name)))))
;;;###autoload
(defun +irc/jump-to-channel (&optional this-server)

View file

@ -109,7 +109,7 @@
(mapc #'kill-buffer show-buffers))
(if (and (modulep! :ui workspaces)
(+workspace-exists-p +rss-workspace-name))
(+workspace/delete +rss-workspace-name)
(+workspace/kill +rss-workspace-name)
(when (window-configuration-p +rss--wconf)
(set-window-configuration +rss--wconf))
(setq +rss--wconf nil)

View file

@ -412,7 +412,7 @@
:desc "Rename workspace" "r" #'+workspace/rename
:desc "Create workspace" "c" #'+workspace/new
:desc "Create named workspace" "C" #'+workspace/new-named
:desc "Delete workspace" "k" #'+workspace/delete
:desc "Delete workspace" "k" #'+workspace/kill
:desc "Save workspace" "S" #'+workspace/save
:desc "Switch to other workspace" "o" #'+workspace/other
:desc "Switch to left workspace" "p" #'+workspace/switch-left

View file

@ -46,7 +46,8 @@
(doom-lookup-key (kbd "TAB") overriding-terminal-local-map))
cmd)
,@(when (modulep! :editor snippets)
'(((+yas-active-p)
'(((memq (bound-and-true-p yas--active-field-overlay)
(overlays-in (1- (point)) (1+ (point))))
#'yas-next-field-or-maybe-expand)
((yas-maybe-expand-abbrev-key-filter 'yas-expand)
#'yas-expand)))
@ -379,8 +380,8 @@
:desc "New named workspace" "N" #'+workspace/new-named
:desc "Load workspace from file" "l" #'+workspace/load
:desc "Save workspace to file" "s" #'+workspace/save
:desc "Delete session" "x" #'+workspace/kill-session
:desc "Delete this workspace" "d" #'+workspace/delete
:desc "Kill session" "x" #'+workspace/kill-session
:desc "Kill this workspace" "d" #'+workspace/kill
:desc "Rename workspace" "r" #'+workspace/rename
:desc "Restore last session" "R" #'+workspace/restore-last-session
:desc "Next workspace" "]" #'+workspace/switch-right
@ -484,6 +485,8 @@
:desc "Browse emacs.d" "E" #'doom/browse-in-emacsd
:desc "Find file" "f" #'find-file
:desc "Find file from here" "F" #'+default/find-file-under-here
(:when (modulep! :config literate)
:desc "Open heading in literate config" "h" #'+literate/find-heading)
:desc "Locate file" "l" #'locate
:desc "Find file in private config" "p" #'doom/find-file-in-private-config
:desc "Browse private config" "P" #'doom/open-private-config
@ -522,7 +525,7 @@
:desc "Magit fetch" "F" #'magit-fetch
:desc "Magit buffer log" "L" #'magit-log-buffer-file
:desc "Git stage this file" "S" #'magit-stage-buffer-file
:desc "Git unstage this file" "U" #'magit-unstage-file
:desc "Git unstage this file" "U" #'magit-unstage-buffer-file
(:prefix ("f" . "find")
:desc "Find file" "f" #'magit-find-file
:desc "Find gitconfig file" "g" #'magit-find-git-config-file

View file

@ -106,6 +106,41 @@
;;;###autoload
(defalias '+literate/reload #'doom/reload)
(defun +literate--flatten-imenu-index (index &optional prefix)
"Flatten an org-mode imenu index."
(let ((flattened '()))
(dolist (item index flattened)
(let* ((name (propertize (car item) 'face (intern (format "org-level-%d" (if prefix (+ 2 (cl-count ?/ prefix)) 1)))))
(prefix (if prefix (concat prefix "/" name) name)))
(if (imenu--subalist-p item)
(setq flattened (append flattened (+literate--flatten-imenu-index (cdr item) prefix)))
(push (cons prefix (cdr item)) flattened))))
(nreverse flattened)))
(defvar imenu-auto-rescan)
;;;###autoload
(defun +literate/find-heading (&optional level)
"Jump to a heading in your literate org config file."
(interactive "P")
(let* ((buffer (or (find-buffer-visiting +literate-config-file)
(find-file-noselect +literate-config-file t))))
(with-current-buffer buffer
(let* ((imenu-auto-rescan t)
(org-imenu-depth (or level 8))
(index (+literate--flatten-imenu-index (imenu--make-index-alist))))
(let ((c (current-window-configuration))
(result nil))
(unwind-protect
(progn
(switch-to-buffer buffer)
(if (modulep! :completion vertico)
(setq result (consult-outline level))
(let ((entry (assoc (completing-read "Go to heading: " index nil t) index)))
(setq result entry)
(imenu entry))))
(unless result
(set-window-configuration c))))))))
;;
;;; Hooks

View file

@ -44,28 +44,32 @@ replacing its contents."
If there are no windows there and there is only one window, split in that
direction and place this window there. If there are no windows and this isn't
the only window, use evil-window-move-* (e.g. `evil-window-move-far-left')."
(unless (memq direction '(left right up down))
(user-error "Invalid direction: %s" direction))
(when (window-dedicated-p)
(user-error "Cannot swap a dedicated window"))
(let* ((this-window (selected-window))
(this-buffer (current-buffer))
(that-window (window-in-direction direction nil this-window))
(that-buffer (window-buffer that-window)))
(when (or (minibufferp that-buffer)
(window-dedicated-p this-window))
(setq that-buffer nil that-window nil))
(if (not (or that-window (one-window-p t)))
(funcall (pcase direction
(if (and (window-at-side-p
this-window (pcase direction ('up 'top) ('down 'bottom) (_ direction)))
(not (cl-loop for dir in (if (memq direction '(left right))
'(up down) '(left right))
if (window-in-direction dir nil this-window)
return t)))
(user-error "Window is already at the edge")
(call-interactively
(pcase direction
('left #'evil-window-move-far-left)
('right #'evil-window-move-far-right)
('up #'evil-window-move-very-top)
('down #'evil-window-move-very-bottom)))
('down #'evil-window-move-very-bottom))))
(unless that-window
(setq that-window
(split-window this-window nil
(pcase direction
('up 'above)
('down 'below)
(_ direction))))
(setq that-window (split-window this-window nil direction))
(with-selected-window that-window
(switch-to-buffer (doom-fallback-buffer)))
(setq that-buffer (window-buffer that-window)))

View file

@ -27,17 +27,21 @@ be formatted and returned to the buffer using
Enable reformatting of a buffer when it is saved. See
[[var:+format-on-save-disabled-modes]] to disable format on save for certain
major modes.
- +lsp ::
Use ~lsp-mode~'s or ~eglot~'s formatters, instead of Apheleia's, if the active
client has the capabilities.
** Packages
- [[doom-package:apheleia]]
** Hacks
As of writing this, apheleia doesn't /yet/ support regions or similar kinds of
buffers, so there are a couple of hacks to attempt to rectify this.
For the most part, things should work as expected. However, because the
formatting occurs on an isolated version of the buffer; lisp/scheme or similarly
indentation-based languages may produce poor results.
- Apheleia -- and many formatters -- don't support partial formatting (i.e. the
opposite of whole-file formatting), so a couple of hacks are in place to
/force/ them to support this when you run [[fn:+format/region]]. This works by
copying the selection into a fake, standalone file and operating on that. This
works in many cases, but makes no guarantees that it will work with all
formatters. Lisp, Scheme, Python, or similarly indentation-based languages are
most likely to see strange results.
** TODO Changelog
# This section will be machine generated. Don't edit it by hand.
@ -65,7 +69,6 @@ or =apheleia-format-buffer= is called. The difference between them is
=+format/buffer= will use a LSP server if configured and available.
* Configuration
Detailed configuration can be found [[https://github.com/radian-software/apheleia/#user-guide][upstream]], but for most purposes here we
provide a simple macro that looks like the below:
@ -85,26 +88,71 @@ an =after!= form, eg below to override Clojure's with =zprint=:
There are a few bonus symbols that apheleia uses (for example =npx= will be
replaced by a correct path to npx) which are all documented in the link above.
** Disabling formatters
*** Permanently
To permanently disable a particular formatter with no provided alternative
** Selecting or disabling a specific formatter
:PROPERTIES:
:ID: ab7008f6-0d6e-4465-9980-adee2055aa16
:END:
Doom exposes a couple variables and functions to help you configure this module's behavior:
- [[var:+format-with]] :: What formatter(s) to use for the current buffer.
- [[var:+format-inhibit]] :: If non-nil, formatting-on-save behavior is disabled,
regardless of ~apehelia-global-mode~.
- [[var:+format-on-save-disabled-modes]] :: A list of major modes to disable
format-on-save behavior in. These buffers can still be formatted by calling
the ~+format/buffer~ or ~+format/region~ commands, manually.
- [[fn:set-formatter!]] :: A helper function for configuring registered formatters
(or adding some of your own) and assigning them to major modes.
Here are some ways to use them:
1. In a project's =.dir-locals.el= file:
#+begin_src emacs-lisp
(setq apheleia-formatters (delq (assoc 'csharpier apheleia-formatters) apheleia-formatters))
((js2-mode . (+format-with . lsp))
(python-mode . (+format-with . (isort black)))
;; If +format-inhibit is non-nil, formatting-on-save behavior will be
;; disabled, regardless of apheleia-global-mode.
(rustic-mode . (+format-inhibit . t)))
#+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.
2. With a file-local variable. E.g. At the top of a file:
#+begin_src js
// -*- +format-with: prettier -*-
#+end_src
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;
Or at the bottom of a file
#+begin_src python
# Local Variables:
# +format-with: (isort black)
# End:
#+end_src
3. From your Doom configuration:
#+begin_src emacs-lisp
;;; add to $DOOMDIR/config.el
(setq-hook! 'python-mode-hook +format-with 'black)
;; Or set it to `nil' to fallback to Apheleia's default
(setq-hook! 'python-mode-hook +format-with nil)
;; Disable format-on-save behavior in Emacs Lisp buffers
(setq-hook! 'emacs-lisp-mode-hook +format-inhibit t)
;; To permenantly disable a formatter:
(after! csharp-mode
(set-formatter! 'csharpier nil))
;; To define new formatters:
;; From modules/tools/docker/config.el:
(after! dockerfile-mode
(set-formatter! 'dockfmt '("dockfmt" "fmt" filepath) :modes '(dockerfile-mode)))
;; From modules/lang/sh/config.el:
(after! sh-script
(set-formatter! 'shfmt '("shfmt" "-ci"
(unless indent-tabs-mode
(list "-i" (number-to-string tab-width))))))
(setq +format-on-save-disabled-modes
'(emacs-lisp-mode ; elisp's mechanisms are good enough
sql-mode ; sqlformat is currently broken
@ -112,43 +160,38 @@ This behaviour is controlled via [[var:+format-on-save-disabled-modes]] thus;
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
=+format/buffer= or =apheleia-format-buffer=.
** Disabling the LSP formatter
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:apheleia]]'s formatter.
+ To disable this behavior universally use: ~(setq +format-with-lsp nil)~
+ To disable this behavior in one mode: ~(setq-hook! 'python-mode-hook
+format-with-lsp nil)~
** Selecting a specific formatter for a particular buffer
Set the buffer-local variable ~+format-with~ to the name of the formatter to
use. e.g.
#+begin_src emacs-lisp
;; Overrides `apheleia-mode-alist`
(setq-hook! 'python-mode-hook +format-with 'html-tidy)
;; Or set it to `nil' to fallback to `apheleia-mode-alist`
(setq-hook! 'python-mode-hook +format-with nil)
#+end_src
Formatters are referred to by the name they were defined with. They can be
looked up in the ~apheleia-mode-alist~ hash table.
looked up in the ~apheleia-mode-alist~ hash table (with [[kbd:<help> v]]).
** One-off ~save-buffer~ without auto-formatting
To save the buffer without formatting just once, pass the universal argument to
~save-buffer~ ([[kbd:][SPC u]] for evil users, [[kbd:][C-u]] for non-evil users). For example:
- Evil: [[kbd:][SPC u SPC f s]]
- Without evil: [[kbd:][C-u C-x C-s]]
** Using ~lsp-mode~ or ~eglot~'s formatter
If you have a buffer open with [[doom-package:lsp-mode]] or [[doom-package:eglot]]
enabled, and the running server supports =textDocument/formatting= or
=textDocument/rangeFormatting=, it can be used instead of
[[doom-package:apheleia]]'s (or Doom's) default formatters by enabling this module
with its =+lsp= flag or manually activating the [[fn:+format-with-lsp-mode]] minor
mode (though it's a better idea to use [[fn:+format-with-lsp-maybe-h]] if you're
looking for a function to use with mode hooks; this function will respect
pre-existing modifications to [[var:+format-with]]).
To enable this formatter selectively, see the next section.
* Troubleshooting
There are a few fail-safes apheleia has to prevent accidental code wipe,
included silently failing if the command errors or doesn't exist.
There are a few fail-safes [[doom-package: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
issues.
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.
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]].
Any issues specific to Apheleia should most often be reported upstream [[https://github.com/radian-software/apheleia/issues][here]].
* Frequently asked questions
/This module has no FAQs yet./ [[doom-suggest-faq:][Ask one?]]

View file

@ -6,6 +6,9 @@
(skip-chars-forward " \t\n")
(current-indentation)))
;;;###autoload (autoload 'apheleia--get-formatters "apheleia-formatters")
;;;###autoload
(defun +format-region (start end &optional callback)
"Format from START to END with `apheleia'."
(when-let* ((command (apheleia--get-formatters
@ -24,10 +27,10 @@
;; 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 cur-buffer))
;; Making enable-multibyte-characters buffer-local causes an
;; error.
;; `enable-multibyte-characters' can change how Emacs reads the
;; buffer's contents (or writes them to the formatters), which
;; can cause errors.
unless (eq var 'enable-multibyte-characters)
;; Using setq-local would quote var.
do (set (make-local-variable var) val))
;;
(insert-buffer-substring-no-properties cur-buffer start end)
@ -42,15 +45,16 @@
(lambda ()
(with-current-buffer formatted-buffer
(when (> indent 0)
;; restore indentation without affecting new
;; indentation
;; restore indentation without affecting new indentation
(indent-rigidly (point-min) (point-max)
(max 0 (- indent (+format--current-indentation)))))
(set-buffer-modified-p nil))
(with-current-buffer cur-buffer
(delete-region start end)
(goto-char start)
(save-excursion
(insert-buffer-substring-no-properties formatted-buffer)
(when callback (funcall callback))
(when callback (funcall callback)))
(kill-buffer formatted-buffer)))))))
@ -58,99 +62,50 @@
;;; Commands
;;;###autoload
(defun +format/buffer (&optional arg)
"Reformat the current buffer using LSP or `format-all-buffer'."
(interactive "P")
(or (run-hook-with-args-until-success '+format-functions (point-min) (point-max) 'buffer)
(call-interactively #'apheleia-format-buffer)))
(defalias '+format/buffer #'apheleia-format-buffer)
;;;###autoload
(defun +format/region (beg end &optional arg)
"Runs the active formatter on the lines within BEG and END.
(defun +format/region (beg end &optional _arg)
"Format the selected 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
snippets or single lines."
WARNING: if the formatter doesn't support partial formatting, this command tries
to pretend the active selection is the contents of a standalone file, but this
may not always work. Keep your undo keybind handy!"
(interactive "rP")
(or (run-hook-with-args-until-success '+format-functions beg end 'region)
(+format-region beg end)))
(+format-region beg end))
;;;###autoload
(defun +format/region-or-buffer ()
"Runs the active formatter on the selected region (or whole buffer, if nothing
is selected)."
"Format the selected region, or whole buffer if nothing is selected."
(interactive)
(call-interactively
(if (doom-region-active-p)
#'+format/region
#'+format/buffer)))
;;
;;; Specialized formatters
;;;###autoload
(defun +format-with-lsp-fn (beg end op)
"Format the region/buffer using any available lsp-mode formatter.
Does nothing if `+format-with-lsp' is nil or the active server doesn't support
the requested feature."
(and +format-with-lsp
(bound-and-true-p lsp-mode)
(pcase op
('buffer (condition-case _
;; Avoid lsp-feature? checks for this, since
;; `lsp-format-buffer' does its own, and allows clients
;; without formatting support (but with rangeFormatting,
;; for some reason) to work.
(always (lsp-format-buffer))
('lsp-capability-not-supported nil)))
('region (if (lsp-feature? "textDocument/rangeFormatting")
(always (lsp-format-region beg end))))
(_ (error "Invalid formatter operation: %s" op)))))
;;;###autoload
(defun +format-with-eglot-fn (beg end op)
"Format the region/buffer using any available eglot formatter.
Does nothing if `+format-with-lsp' is nil or the active server doesn't support
the requested feature."
(and +format-with-lsp
(bound-and-true-p eglot--managed-mode)
(pcase op
('buffer (if (eglot--server-capable :documentFormattingProvider)
(always (eglot-format-buffer))))
('region (if (eglot--server-capable :documentRangeFormattingProvider)
(always (eglot-format beg end))))
(_ (error "Invalid formatter operation: %s" op)))))
;;;###autoload
(defun +format-in-org-src-blocks-fn (beg end _op)
"Reformat org src blocks with apheleia as if they were independent buffers."
(when (derived-mode-p 'org-mode)
(goto-char beg)
(while (re-search-forward org-babel-src-block-regexp end t)
(let* ((element (org-element-at-point))
(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 (max beg block-beg))
(end (min end block-end))
(lang (org-element-property :language element))
(major-mode (org-src-get-lang-mode lang)))
(defun +format/org-block (&optional point)
"Reformat the org src block at POINT with a mode approriate formatter."
(interactive (list (point)))
(unless (derived-mode-p 'org-mode)
(user-error "Not an org-mode buffer!"))
(let ((element (org-element-at-point point)))
(unless (org-in-src-block-p nil element)
(user-error "Not in an org src block"))
(cl-destructuring-bind (beg end _) (org-src--contents-area element)
(let* ((lang (org-element-property :language element))
(mode (org-src-get-lang-mode lang)))
(save-excursion
(if (eq major-mode 'org-mode)
(user-error "Cannot reformat an org src block in org-mode")
;; Determine formatter based on language and format the region
(let ((formatter (apheleia--get-formatters 'interactive)))
(unless formatter
(setq formatter (apheleia--get-formatters 'prompt))
(unless formatter
(user-error "No formatter configured for language: %s" lang)))
(let ((apheleia-formatter formatter))
(+format-region beg end)))))))
t))
(if (provided-mode-derived-p mode 'org-mode)
(user-error "Cannot reformat an org-mode or org-derived src block")
(let* ((major-mode mode)
(after-change-functions
;; HACK: Silence excessive and unhelpful warnings about
;; 'org-element-at-point being used in non-org-mode
;; buffers'.
(remq 'org-indent-refresh-maybe after-change-functions))
(apheleia-formatter
(or (apheleia--get-formatters 'interactive)
(apheleia--get-formatters 'prompt)
(user-error "No formatter configured for language: %s" lang))))
(+format-region beg end))))))))

View file

@ -0,0 +1,86 @@
;;; editor/format/autoload/lsp.el -*- lexical-binding: t; -*-
;;;###if (modulep! :tools lsp)
(defvar +format-lsp--last nil)
;;;###autoload
(define-minor-mode +format-with-lsp-mode
"Toggles `lsp-mode'/`eglot' integration with `apheleia-mode' in this buffer.
When enabled, it changes `+format-with' to `lsp', and back to its old value when
disabled. Use `+format-wtih-lsp-maybe-h' to activate it, to ensure it only
activates if lsp-mode/eglot are on and connected to a valid client, and so this
mode won't conflict with pre-existing user config on `+format-with'."
:init-value nil
(unless (local-variable-p '+format-lsp--last)
(setq-local +format-lsp--last +format-with))
(setq-local +format-with
(if +format-with-lsp-mode
(cl-remove-duplicates (cons 'lsp +format-with) :test #'eq)
(prog1 (remq 'lsp (ensure-list +format-lsp--last))
(kill-local-variable '+format-lsp--last)))))
(defvar +format--lsp-alist
'((lsp-managed-mode . +format--with-lsp-mode)
(eglot--managed-mode . +format--with-eglot))
"A list of LSP formatter functions to try on `+format-lsp-buffer'.")
(defun +format--lsp-fn ()
(cl-loop for (sym . fn) in +format--lsp-alist
if (and (boundp sym) (symbol-value sym))
return fn))
;;;###autoload
(defun +format-with-lsp-toggle-h ()
"Toggle `+format-with-lsp-mode' depending on the state of lsp-mode/eglot.
Does not activate the mode if `+format-with' is already set. To activate the
mode unconditionally, call `+format-with-lsp-mode' instead."
(when (or (null +format-with) +format-with-lsp-mode)
(+format-with-lsp-mode (if (+format--lsp-fn) +1 -1))))
;;
;;; Apheleia formatters
;;;###autoload
(cl-defun +format-lsp-buffer (&rest plist &key callback &allow-other-keys)
"Format the current buffer with any available lsp-mode or eglot formatter."
(if-let* ((fn (+format--lsp-fn))
((apply fn plist)))
(funcall callback)
(funcall callback "LSP server doesn't support formatting")))
(cl-defun +format--with-lsp-mode (&key buffer scratch &allow-other-keys)
"Format the current buffer with any available lsp-mode formatter."
(with-current-buffer buffer
(let ((edits
(cond
((lsp-feature? "textDocument/formatting")
(lsp-request "textDocument/formatting"
(lsp--make-document-formatting-params)))
((lsp-feature? "textDocument/rangeFormatting")
(lsp-request "textDocument/rangeFormatting"
(lsp--make-document-range-formatting-params
(point-min) (point-max))))
(:err))))
(unless (eq edits :err)
(unless (seq-empty-p edits)
(with-current-buffer scratch
(lsp--apply-text-edits edits 'format)))
t))))
(cl-defun +format--with-eglot (&key buffer scratch &allow-other-keys)
"Format the current buffer with any available eglot formatter."
(with-current-buffer scratch
(when (setq-local
eglot--cached-server
(with-current-buffer buffer
(when (or (eglot-server-capable :documentFormattingProvider)
(eglot-server-capable :documentRangeFormattingProvider))
(eglot-current-server))))
(let ((buffer-file-name (buffer-file-name buffer)))
(eglot-format-buffer))
t)))
;;; lsp.el ends here

View file

@ -1,69 +1,54 @@
;;; editor/format/config.el -*- lexical-binding: t; -*-
(defvar +format-on-save-disabled-modes
(defcustom +format-on-save-disabled-modes
'(sql-mode ; sqlformat is currently broken
tex-mode ; latexindent is broken
latex-mode
org-msg-edit-mode) ; doesn't need a formatter
"A list of major modes in which to not reformat the buffer upon saving.
If it is t, it is disabled in all modes, the same as if the +onsave flag
wasn't used at all.
If nil, formatting is enabled in all modes.
Irrelevant if you do not have the +onsave flag enabled for this module.")
(defvar +format-preserve-indentation t
"If non-nil, the leading indentation is preserved when formatting the whole
buffer. This is particularly useful for partials.
If it is t, it is disabled in all modes, the same as if the +onsave flag wasn't
used at all.
If nil, formatting is enabled in all modes."
:type '(list symbol))
Indentation is always preserved when formatting regions.")
(defvaralias '+format-with 'apheleia-formatter)
(defvaralias '+format-inhibit 'apheleia-inhibit)
(defvar +format-with-lsp t
"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
select buffers.
This has no effect on the +onsave flag, apheleia will always be used there.")
(defvaralias '+format-with 'apheleia-formatter
"Set this to explicitly use a certain formatter for the current buffer.")
(defvar +format-functions
'(+format-in-org-src-blocks-fn
+format-with-lsp-fn
+format-with-eglot-fn)
"A list of functions to run when formatting a buffer or region.
Each function is given three arguments: the starting point, end point, and a
symbol indicating the type of operation being requested (as a symbol: either
`region' or `buffer').
The first function to return non-nil will abort all functions after it,
including Apheleia itself.")
;;
;;; Bootstrap
(use-package! apheleia
:defer t
:init
(when (modulep! +onsave)
(add-hook 'doom-first-file-hook #'apheleia-global-mode))
(add-hook 'doom-first-file-hook #'apheleia-global-mode)
;; apheleia autoloads `apheleia-inhibit-functions' so it will be immediately
;; available to mutate early.
(add-hook! 'apheleia-inhibit-functions
(defun +format-maybe-inhibit-h ()
"Check if formatting should be disabled for current buffer.
This is controlled by `+format-on-save-disabled-modes'."
(or (eq major-mode 'fundamental-mode)
(string-blank-p (buffer-name))
(eq +format-on-save-disabled-modes t)
(not (null (memq major-mode +format-on-save-disabled-modes)))))
(not (null (memq major-mode +format-on-save-disabled-modes)))))))
;; Use the formatter provided by lsp-mode and eglot, if available.
(when (modulep! +lsp)
(add-hook 'eglot-managed-mode-hook #'+format-with-lsp-maybe-h)
(add-hook 'lsp-managed-mode-hook #'+format-with-lsp-maybe-h))
(after! apheleia
:config
(add-to-list 'doom-debug-variables '(apheleia-log-only-errors . nil))
(add-to-list 'doom-debug-variables '(apheleia-log-debug-info . t))
(when (modulep! +onsave)
(add-to-list 'apheleia-inhibit-functions #'+format-maybe-inhibit-h)))
;;
;;; Hacks
;; A psuedo-formatter that dispatches to the appropriate LSP client (via
;; `lsp-mode' or `eglot') that is capable of formatting. Without +lsp, users
;; must manually set `+format-with' to `lsp' to use it, or activate
;; `+format-with-lsp-mode' in the appropriate modes.
(add-to-list 'apheleia-formatters '(lsp . +format-lsp-buffer))
(defadvice! +format--inhibit-reformat-on-prefix-arg-a (orig-fn &optional arg)
"Make it so \\[save-buffer] with prefix arg inhibits reformatting."
@ -71,17 +56,16 @@ This is controlled by `+format-on-save-disabled-modes'."
(let ((apheleia-mode (and apheleia-mode (memq arg '(nil 1)))))
(funcall orig-fn)))
;; HACK: Apheleia suppresses notifications that the current buffer has
;; changed, so plugins that listen for them need to be manually informed:
(add-hook!
'apheleia-post-format-hook
;; HACK `web-mode' doesn't update syntax highlighting after arbitrary buffer
;; modifications, so we must trigger refontification manually.
(defun +format--fix-web-mode-fontification-h ()
(defun +format--update-web-mode-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)))))
(defun +format--refresh-vc-gutter-h ()
(defun +format--update-vc-gutter-h ()
(when (fboundp '+vc-gutter-update-h)
(+vc-gutter-update-h))))
(+vc-gutter-update-h)))))

View file

@ -65,7 +65,7 @@ default/fallback account."
;; as otherwise you can accumulate empty workspaces
(progn
(unless (+workspace-buffer-list)
(+workspace-delete (+workspace-current-name)))
(+workspace-kill (+workspace-current-name)))
(+workspace-switch +mu4e-workspace-name t))
(setq +mu4e--old-wconf (current-window-configuration))
(delete-other-windows)
@ -365,7 +365,7 @@ When otherwise called, open a dired buffer and enable `dired-mu4e-attach-ctrl-c-
;; (prolusion-mail-hide)
(cond
((and (modulep! :ui workspaces) (+workspace-exists-p +mu4e-workspace-name))
(+workspace/delete +mu4e-workspace-name))
(+workspace/kill +mu4e-workspace-name))
(+mu4e--old-wconf
(set-window-configuration +mu4e--old-wconf)

View file

@ -32,7 +32,7 @@
;; (+popup/close (get-buffer-window "*notmuch-hello*"))
(doom-kill-matching-buffers "^\\*notmuch")
(when (modulep! :ui workspaces)
(+workspace/delete +notmuch-workspace-name)))
(+workspace/kill +notmuch-workspace-name)))
(defun +notmuch-get-sync-command ()
"Return a shell command string to synchronize your notmuch mail with."

View file

@ -120,11 +120,13 @@ If REVERSE (the prefix arg) is non-nil, sort the transactions in reverst order."
(defvar compilation-read-command)
;;;###autoload
(defun +beancount/balance ()
(defun +beancount/balance (&optional all-accounts)
"Display a balance report with bean-report (bean-report bal)."
(interactive)
(let (compilation-read-command)
(beancount--run "bean-report" buffer-file-name "bal")))
(interactive "P")
(let ((args (unless all-accounts '("-e" "Assets|Liabilities")))
compilation-read-command
current-prefix-arg)
(apply #'beancount--run "bean-report" buffer-file-name "balances" args)))
;;;###autoload
(defun +beancount/clone-transaction ()

View file

@ -19,8 +19,8 @@ intuitive out of the box:
org files to reveal.js slideshows.
- Drag-and-drop support for images (with inline preview) and media files (drops
a file icon and a short link) (requires [[doom-module:+dragndrop]] flag).
- Integration with pandoc, ipython, jupyter, reveal.js, beamer, and others
(requires flags).
- Integration with pandoc, jupyter, reveal.js, beamer, and others (requires
flags).
- Export-to-clipboard functionality, for copying text into formatted html,
markdown or rich text to the clipboard (see fn:+org/export-to-clipboard and
fn:+org/export-to-clipboard-as-rich-text).
@ -58,8 +58,6 @@ https://www.mfoot.com/blog/2015/11/22/literate-emacs-configuration-with-org-mode
- +hugo ::
Enable integration with [[https://gohugo.io][hugo]] to export from Emacs well-formed ([[https://github.com/russross/blackfriday][blackfriday]])
markdown.
- +ipython ::
(**DEPRECATED**) Enable ipython integration for babel.
- +journal ::
Enable [[doom-package:org-journal]] integration.
- +jupyter ::
@ -95,7 +93,6 @@ https://www.mfoot.com/blog/2015/11/22/literate-emacs-configuration-with-org-mode
- [[doom-package:ob-async]]
- [[doom-package:ob-crystal]] if [[doom-module::lang crystal]]
- [[doom-package:ob-go]] if [[doom-module::lang go]]
- [[doom-package:ob-ipython]] if [[doom-module:+ipython]]
- [[doom-package:ob-nim]] if [[doom-module::lang nim]]
- [[doom-package:ob-racket]] if [[doom-module::lang racket]]
- [[doom-package:ob-restclient]] if [[doom-module::lang rest]]

View file

@ -1,152 +0,0 @@
;;; lang/org/autoload/contrib-ipython.el -*- lexical-binding: t; -*-
;;;###if (modulep! +ipython)
;;;###autoload
(defun +org-ob-ipython-initiate-session-a (&optional session params)
"Create a session named SESSION according to PARAMS."
(if (string= session "none")
(error
"ob-ipython currently only supports evaluation using a session.
Make sure your src block has a :session param.")
(when (not (string-suffix-p ".json" session t))
(ob-ipython--create-kernel
(ob-ipython--normalize-session
session)
(cdr (assoc :kernel params))))
(ob-ipython--create-repl
(ob-ipython--normalize-session
session)
params)))
(defun +org--ob-ipython-generate-local-path-from-remote (session host params)
"Given a remote SESSION with PARAMS and corresponding HOST, copy remote config to local, start a jupyter console to generate a new one."
(let* ((runtime-dir
(cdr
(doom-call-process "ssh " host "jupyter" "--runtime-dir")))
(runtime-file (concat runtime-dir "/" "kernel-" session ".json"))
(tramp-path (concat "/ssh:" host ":" runtime-file))
(tramp-copy (concat (or +ob-ipython-local-runtime-dir
(cdr (doom-call-process "jupyter" "--runtime-dir")))
"/remote-" host "-kernel-" session ".json"))
(local-path
(concat
"Python:ob-ipython-"
(file-name-sans-extension (file-name-nondirectory tramp-copy))
"-ssh.json")))
;; scp remote file to local
(copy-file tramp-path tramp-copy t)
;; connect to remote use new config
(let* ((python-shell-interpreter-interactive-arg " console --simple-prompt")
(python-shell-prompt-detect-enabled nil)
(python-shell-completion-native-enable nil)
(buf (python-shell-make-comint
(concat ob-ipython-command
" console --simple-prompt --existing "
tramp-copy " --ssh " host)
(concat "" local-path)
t))
(proc (get-buffer-process buf))
(dir (cdr (assoc :pydir params))))
(sleep-for 3)
(when dir
(with-current-buffer buf
(setq-local default-directory dir)))
(format "*%s*" proc))))
;;;###autoload
(defun +org-ob-ipython-create-repl-a (name &optional params)
"Create repl based on NAME and PARAMS.
If PARAMS specifies remote kernel, copy the kernel config from remote server and
create a repl connecting to remote session."
(let ((cmd (string-join (ob-ipython--kernel-repl-cmd name) " ")))
(cond ((string= "default" name)
(run-python cmd nil nil)
(format "*%s*" python-shell-buffer-name))
((string-match "^remote-.*ssh.json" name)
(when (not (ignore-errors
(process-live-p
(get-process
(format
"Python:ob-ipython-%s"
name)))))
(let* ((remote (s-split "-" name))
(remote-host (nth 1 remote))
(remote-session (nth 3 remote)))
(+org--ob-ipython-generate-local-path-from-remote
remote-session
remote-host
params))))
((let* ((process-name (format "Python:ob-ipython-%s" name))
(python-shell-prompt-detect-enabled nil)
(python-shell-completion-native-enable nil)
(buf (python-shell-make-comint cmd process-name t))
(dir (cdr (assoc :pydir params))))
(if dir
(with-current-buffer buf
(setq-local default-directory dir)))
(sleep-for 1)
(format "*%s*" process-name))))))
;;;###autoload
(defun +org-babel-execute:ipython-a (body params)
"Execute a BODY of IPython code with PARAMS in org-babel.
This function is called by `org-babel-execute-src-block'."
(message default-directory)
(org-babel-ipython-initiate-session (cdr (assoc :session params))
params))
;;
;; * org-src-edit
;;;###autoload
(defun +org-babel-edit-prep:ipython-a (info)
(let* ((params (nth 2 info))
(session (cdr (assoc :session params))))
(org-babel-ipython-initiate-session session params))
;; Support for python.el's "send-code" commands within edit buffers.
(setq-local python-shell-buffer-name
(format "Python:ob-ipython-%s"
(ob-ipython--normalize-session
(cdr (assoc :session (nth 2 info))))))
(setq-local default-directory
(format "%s"
(ob-ipython--normalize-session
(cdr (assoc :pydir (nth 2 info))))))
(ob-ipython-mode 1)
;; hack on company mode to use company-capf rather than company-anaconda
(when (modulep! :completion company)
(setq-local company-backends
'(company-capf
company-dabbrev
company-files
company-yasnippet))
(setq-local company-idle-delay nil))
(when (featurep 'lpy)
(setq lispy-python-proc
(format "Python:ob-ipython-%s"
(ob-ipython--normalize-session
(cdr (assoc :session (nth 2 info)))))
lispy--python-middleware-loaded-p nil)
(lispy--python-middleware-load)))
;;
;; * retina
(defun +org--ob-ipython-mac-2x-image-file-name (filename &optional scale)
"Return the name of high-resolution image file for FILENAME.
The optional arg SCALE is scale factor, and defaults to 2."
(let ((pos (or (string-match "\\.[^./]*\\'" filename) (length filename))))
(format "%s@%dx%s"
(substring filename 0 pos)
(or scale 2)
(substring filename pos))))
;;;###autoload
(defun +org-ob-ipython-write-base64-string-a (oldfunc &rest args)
(let ((file (car args))
(b64-string (cdr args)))
(let ((file2x (+org--ob-ipython-mac-2x-image-file-name file)))
(apply oldfunc file2x b64-string)
(shell-command (concat "convert " file2x " -resize 50% " file)))))

View file

@ -53,15 +53,6 @@ re-align the table if necessary. (Necessary because org-mode has a
(if org-table-may-need-update (org-table-align))
(goto-char pt))))
;;;###autoload
(defun +org-enable-auto-reformat-tables-h ()
"Realign tables & update formulas when exiting insert mode (`evil-mode').
Meant for `org-mode-hook'."
(when (featurep 'evil)
(add-hook 'evil-insert-state-exit-hook #'+org-realign-table-maybe-h nil t)
(add-hook 'evil-replace-state-exit-hook #'+org-realign-table-maybe-h nil t)
(advice-add #'evil-replace :after #'+org-realign-table-maybe-a)))
;;;###autoload
(defun +org-delete-backward-char-and-realign-table-maybe-h ()
"Ensure deleting characters with backspace doesn't deform the table cell."

View file

@ -334,6 +334,24 @@ see how ARG affects this command."
(org-clock-in))
((org-clock-in-last arg))))
;;;###autoload
(defun +org/reformat-at-point ()
"Reformat the element at point.
If in an org src block, invokes `+format/org-block' if the ':editor format'
module is enabled.
If in an org table, realign the cells with `org-table-align'.
Otherwise, falls back to `org-fill-paragraph' to reflow paragraphs."
(interactive)
(let ((element (org-element-at-point)))
(cond ((org-in-src-block-p nil element)
(unless (modulep! :editor format)
(user-error ":editor format module is disabled, ignoring reformat..."))
(call-interactively #'+format/org-block))
((org-at-table-p)
(save-excursion (org-table-align)))
((call-interactively #'org-fill-paragraph)))))
;;; Folds
;;;###autoload
@ -520,10 +538,3 @@ All my (performant) foldings needs are met between this and `org-show-subtree'
(when org-occur-highlights
(org-remove-occur-highlights)
t))
;;;###autoload
(defun +org-enable-auto-update-cookies-h ()
"Update statistics cookies when saving or exiting insert mode (`evil-mode')."
(when (bound-and-true-p evil-local-mode)
(add-hook 'evil-insert-state-exit-hook #'org-update-parent-todo-statistics nil t))
(add-hook 'before-save-hook #'org-update-parent-todo-statistics nil t))

View file

@ -289,8 +289,8 @@ Also adds support for a `:sync' parameter to override `:async'."
initialize)
args))
;; Refresh inline images after executing src blocks (useful for plantuml or
;; ipython, where the result could be an image)
;; Refresh inline images after executing src blocks (useful for plantuml,
;; where the result could be an image)
(add-hook! 'org-babel-after-execute-hook
(defun +org-redisplay-inline-images-in-babel-result-h ()
(unless (or
@ -767,10 +767,9 @@ mutating hooks on exported output, like formatters."
(defun +org--restart-mode-h ()
"Restart `org-mode', but only once."
(remove-hook 'doom-switch-buffer-hook #'+org--restart-mode-h 'local)
(quiet! (org-mode-restart))
(delq! (current-buffer) org-agenda-new-buffers)
(remove-hook 'doom-switch-buffer-hook #'+org--restart-mode-h
'local)
(run-hooks 'find-file-hook))
(add-hook! 'org-agenda-finalize-hook
@ -796,14 +795,14 @@ can grow up to be fully-fledged org-mode buffers."
(add-hook 'doom-switch-buffer-hook #'+org--restart-mode-h
nil 'local))))))
(defadvice! +org--restart-mode-before-indirect-buffer-a (base-buffer &rest _)
(defadvice! +org--restart-mode-before-indirect-buffer-a (&optional buffer _)
"Restart `org-mode' in buffers in which the mode has been deferred (see
`+org-defer-mode-in-agenda-buffers-h') before they become the base buffer for an
indirect buffer. This ensures that the buffer is fully functional not only when
the *user* visits it, but also when some code interacts with it via an indirect
buffer as done, e.g., by `org-capture'."
:before #'make-indirect-buffer
(with-current-buffer base-buffer
:before #'org-capture-get-indirect-buffer
(with-current-buffer (or buffer (current-buffer))
(when (memq #'+org--restart-mode-h doom-switch-buffer-hook)
(+org--restart-mode-h))))
@ -872,6 +871,9 @@ between the two."
[remap doom/backward-to-bol-or-indent] #'org-beginning-of-line
[remap doom/forward-to-last-non-comment-or-eol] #'org-end-of-line
(:when (modulep! :completion vertico)
[remap imenu] #'consult-outline)
:localleader
"#" #'org-update-statistics-cookies
"'" #'org-edit-special
@ -1223,7 +1225,7 @@ between the two."
:m "[l" #'org-previous-link
:m "]c" #'org-babel-next-src-block
:m "[c" #'org-babel-previous-src-block
:n "gQ" #'org-fill-paragraph
:n "gQ" #'+org/reformat-at-point
;; sensible vim-esque folding keybinds
:n "za" #'+org/toggle-fold
:n "zA" #'org-shifttab
@ -1306,10 +1308,7 @@ between the two."
;; `org-indent-mode', so we turn off show-paren-mode altogether
#'doom-disable-show-paren-mode-h
;; disable `show-trailing-whitespace'; shows a lot of false positives
#'doom-disable-show-trailing-whitespace-h
;; #'+org-enable-auto-reformat-tables-h
;; #'+org-enable-auto-update-cookies-h
)
#'doom-disable-show-trailing-whitespace-h)
(add-hook! 'org-load-hook
#'+org-init-org-directory-h

View file

@ -1,41 +0,0 @@
;;; lang/org/contrib/babel.el -*- lexical-binding: t; -*-
;;;###if (modulep! +ipython)
(use-package! ob-ipython
:defer t
:init
(defvar +ob-ipython-local-runtime-dir nil)
(setq ob-ipython-resources-dir ".ob-ipython-resrc")
(add-hook! '+org-babel-load-functions
(defun +org-babel-load-ipython-h (lang)
(and (string-prefix-p "jupyter-" (symbol-name lang))
(require 'ob-ipython nil t))))
(after! org-src
(add-to-list 'org-src-lang-modes '("ipython" . python)))
(after! ox-latex
(add-to-list 'org-latex-minted-langs '(ipython "python")))
:config
(set-popup-rules!
'(("\\*ob-ipython.*"
:slot 2 :side right :size 100 :height 0.2
:select nil :quit nil :ttl nil)
("^ \\*Python"
:slot 0 :side right :size 100
:select nil :quit nil :ttl nil)))
;; advices for remote kernel and org-src-edit
(advice-add #'ob-ipython--create-repl :override #'+org-ob-ipython-create-repl-a)
(advice-add #'org-babel-edit-prep:ipython :override #'+org-babel-edit-prep:ipython-a)
(advice-add #'org-babel-execute:ipython :before #'+org-babel-execute:ipython-a)
(advice-add #'org-babel-ipython-initiate-session :override #'+org-ob-ipython-initiate-session-a)
;; retina resolution image hack
(when (featurep :system 'macos)
(advice-add #'ob-ipython--write-base64-string :around #'+org-ob-ipython-write-base64-string-a))
;; ipython has its own async keyword, disable ipython in ob-async.
(after! ob-async
(add-to-list 'ob-async-no-async-languages-alist "ipython")))

View file

@ -78,8 +78,6 @@
(when (modulep! +gnuplot)
(package! gnuplot :pin "7138b139d2dca9683f1a81325c643b2744aa1ea3")
(package! gnuplot-mode :pin "601f6392986f0cba332c87678d31ae0d0a496ce7"))
(when (modulep! +ipython) ; DEPRECATED
(package! ob-ipython :pin "7147455230841744fb5b95dcbe03320313a77124"))
(when (modulep! +jupyter)
(package! jupyter :pin "b279c90295ed7ef89832d655cf8d9077233f1098"))
(when (modulep! +journal)

View file

@ -41,7 +41,6 @@ This module adds support for PHP 5.3+ (including PHP8) to Doom Emacs.
- [[doom-package:async]]
- [[doom-package:hack-mode]] if [[doom-module:+hack]]
- [[doom-package:psysh]]
- [[doom-package:php-cs-fixer]] if [[doom-package::editor format]]
- [[doom-package:php-extras]]
- [[doom-package:php-mode]]
- [[doom-package:php-refactor-mode]]
@ -121,7 +120,7 @@ The others have to be installed manually and added to your =$PATH=.
- ~pysh~ (REPL)
- ~phpctags~ (better code completion)
- ~phpunit~ (unit test commands)
- ~php-cs-fixer~ and ~@prettier/plugin-php~ (for code formatting)
- ~phpcbf~, provided by ~squizlabs/php_codesniffer~ (for code formatting)
+ ~phpactor~ (for LSP if intelephense isn't desired)
#+begin_src sh
@ -129,12 +128,8 @@ composer global require \
psy/psysh \
phpunit/phpunit \
techlivezheng/phpctags \
friendsofphp/php-cs-fixer \
squizlabs/php_codesniffer \
phpactor/phpactor
# Needed by php-cs-fixer, otherwise you'll get "Couldn't resolve parser
# 'php'" errors
npm install -g @prettier/plugin-php
#+end_src
You must ensure that =$HOME/.composer/vendor/bin= is in =$PATH=, so these

View file

@ -20,8 +20,5 @@
(when (modulep! :completion company)
(package! company-phpactor :pin "6b5269ff82785a9bd1e648b2f91e5128353d5a67")))
(when (modulep! :editor format)
(package! php-cs-fixer :pin "efe4368d891f1eec6311363cfd6be3e9eadb5e0a"))
;; For building php-extras
(package! async :pin "cff2bd0be3c78a2eb76717eed60302972fe9b8c5")

View file

@ -10,7 +10,7 @@ This module adds [[https://www.python.org/][Python]] support to Doom Emacs.
- Snippets
- Run tests ([[doom-package:nose]], [[doom-package:pytest]])
- Auto-format (with ~black~, requires [[doom-module::editor format]])
- LSP integration (=mspyls=, =pyls=, or =pyright=)
- LSP integration (=pyls=, =jedi=, =ruff=, or =pyright=)
** Maintainers
- [[doom-user:][@hlissner]]
@ -23,15 +23,15 @@ This module adds [[https://www.python.org/][Python]] support to Doom Emacs.
- +cython ::
Enable support for Cython files support.
- +lsp ::
Enable LSP support for ~python-mode~. Requires [[doom-module::tools lsp]] and a langserver
(supports mspyls, pyls, and pyright).
Enable LSP support for ~python-mode~. Requires [[doom-module::tools lsp]] and a
langserver (=pyls=, =jedi=, =ruff=, or =pyright=).
- +poetry ::
Enable Python packaging, dependency management, and virtual environment
support via [[https://python-poetry.org/][Poetry]].
- +pyenv ::
Enable Python virtual environment support via [[https://github.com/pyenv/pyenv][pyenv]]
- +pyright ::
Use the pyright LSP server instead of mspyls or pyls (requires [[doom-module:+lsp]]).
Add support for the pyright LSP server (requires [[doom-module:+lsp]]).
- +tree-sitter ::
Leverages tree-sitter for better syntax highlighting and structural text
editing. Requires [[doom-module::tools tree-sitter]].
@ -53,8 +53,6 @@ This module adds [[https://www.python.org/][Python]] support to Doom Emacs.
- if [[doom-module:+lsp]]
- if [[doom-module:+pyright]]
- [[doom-package:lsp-pyright]]
- else
- [[doom-package:lsp-python-ms]]
** Hacks
- [[doom-package:anaconda-mode]] is configured to activate when [[doom-package:lsp-mode]] (or [[doom-package:eglot]]) don't -- or

View file

@ -134,7 +134,7 @@
(add-hook 'anaconda-mode-hook #'evil-normalize-keymaps))
(map! :localleader
:map anaconda-mode-map
:prefix "g"
:prefix ("g" . "conda")
"d" #'anaconda-mode-find-definitions
"h" #'anaconda-mode-show-doc
"a" #'anaconda-mode-find-assignments
@ -148,10 +148,10 @@
(map! :after python
:map python-mode-map
:localleader
(:prefix ("i" . "imports")
:prefix ("i" . "imports")
:desc "Insert missing imports" "i" #'pyimport-insert-missing
:desc "Remove unused imports" "R" #'pyimport-remove-unused
:desc "Optimize imports" "o" #'+python/optimize-imports)))
:desc "Optimize imports" "o" #'+python/optimize-imports))
(use-package! py-isort
@ -176,7 +176,7 @@
(map! :localleader
:map nose-mode-map
:prefix "t"
:prefix ("t" . "test")
"r" #'nosetests-again
"a" #'nosetests-all
"s" #'nosetests-one
@ -220,7 +220,7 @@
(:description . "Run Python script")))
(map! :map python-mode-map
:localleader
:prefix "e"
:prefix ("e" . "pipenv")
:desc "activate" "a" #'pipenv-activate
:desc "deactivate" "d" #'pipenv-deactivate
:desc "install" "i" #'pipenv-install
@ -342,16 +342,8 @@
;;
;;; LSP
(eval-when! (and (modulep! +lsp)
(not (modulep! :tools lsp +eglot)))
(use-package! lsp-python-ms
:unless (modulep! +pyright)
:after lsp-mode
:preface
(after! python
(setq lsp-python-ms-python-executable-cmd python-shell-interpreter)))
(use-package! lsp-pyright
:when (modulep! +lsp)
:when (modulep! +pyright)
:after lsp-mode))
:when (not (modulep! :tools lsp +eglot))
:after lsp-mode)

View file

@ -11,9 +11,8 @@
;; LSP
(when (modulep! +lsp)
(unless (modulep! :tools lsp +eglot)
(if (modulep! +pyright)
(package! lsp-pyright :pin "cc6df06aeaee3053eb800a24193483387b7b545b")
(package! lsp-python-ms :pin "7bda327bec7b219d140c34dab4b1e1fbd41bc516"))))
(when (modulep! +pyright)
(package! lsp-pyright :pin "cc6df06aeaee3053eb800a24193483387b7b545b"))))
;; Programming environment
(package! anaconda-mode :pin "79fa9b4d2bda9f69857aeffb30c75276848a2810")

View file

@ -54,6 +54,10 @@ Can be a list of backends; accepts any value `company-backends' accepts.")
lsp-xml-jar-file (expand-file-name "org.eclipse.lsp4xml-0.3.0-uber.jar" lsp-server-install-dir)
lsp-groovy-server-file (expand-file-name "groovy-language-server-all.jar" lsp-server-install-dir))
;; REVIEW: Remove when zigtools/zls#1879 is resolved.
(unless (featurep :system 'windows)
(setq lsp-zig-download-url-format "https://github.com/zigtools/zls/releases/latest/download/zls-%s-%s.tar.xz"))
(add-hook! 'doom-escape-hook
(defun +lsp-signature-stop-maybe-h ()
"Close the displayed `lsp-signature'."

View file

@ -1,9 +1,9 @@
;; -*- no-byte-compile: t; -*-
;;; tools/magit/packages.el
(when (package! magit :pin "ea0f07e54967197ac0b072a69ba314314a4080c1")
(when (package! magit :pin "9d1f8db507e080e032943a3ed1445bd8d9aaa9fc")
(when (modulep! +forge)
(package! forge :pin "4adb94d23c8f28ea3b15757936c2203b3376586a")
(package! forge :pin "0102834bb7c872c8a3f77cabf5221e8199346c43")
(package! code-review
:recipe (:host github
:repo "doomelpa/code-review"

View file

@ -1,62 +0,0 @@
#+title: :ui hydra
#+subtitle: Discount modality for mythological beast hunters
#+created: October 29, 2019
#+since: 2.0.0
#+begin_quote
*This module is deprecated.* The module is too trivially small, and it's
always been unclear how hydra fits into Doom's vision for its UI. It's been
decided that Doom will head toward Embark, transient, or hercules instead.
#+end_quote
* Description :unfold:
This module adds hydra to Doom Emacs, as well as a few custom built hydras to
start with:
- A hydra to control windows ~+hydra/window-nav/body~.
- A hydra to control text zoom level ~+hydra/text-zoom/body~.
** Maintainers
/This module has no dedicated maintainers./ [[doom-contrib-maintainer:][Become a maintainer?]]
** Module flags
/This module has no flags./
** Packages
- [[doom-package:hydra]]
** Hacks
/No hacks documented for this module./
** TODO Changelog
# This section will be machine generated. Don't edit it by hand.
/This module does not have a changelog yet./
* Installation
[[id:01cffea4-3329-45e2-a892-95a384ab2338][Enable this module in your ~doom!~ block.]]
/This module has no external requirements./
* TODO Usage
#+begin_quote
󱌣 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]]
#+end_quote
* TODO Configuration
#+begin_quote
󱌣 /This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
#+end_quote
Configuring this module is only setting bindings to the provided hydra, or
creating your own ones!
* Troubleshooting
/There are no known problems with this module./ [[doom-report:][Report one?]]
* Frequently asked questions
/This module has no FAQs yet./ [[doom-suggest-faq:][Ask one?]]
* TODO Appendix
#+begin_quote
󱌣 This module has no appendix yet. [[doom-contrib-module:][Write one?]]
#+end_quote

View file

@ -1,49 +0,0 @@
;;; ui/hydra/autoload/windows.el -*- lexical-binding: t; -*-
;;;###autoload (autoload '+hydra/text-zoom/body "ui/hydra/autoload/windows" nil t)
(defhydra +hydra/text-zoom (:hint nil :color red)
"
Text zoom: _j_:zoom in, _k_:zoom out, _0_:reset
"
("j" doom/increase-font-size "in")
("k" doom/decrease-font-size "out")
("0" doom/reset-font-size "reset"))
;;;###autoload (autoload '+hydra/window-nav/body "ui/hydra/autoload/windows" nil t)
(defhydra +hydra/window-nav (:hint nil)
"
Split: _v_ert _s_:horz
Delete: _c_lose _o_nly
Switch Window: _h_:left _j_:down _k_:up _l_:right _u_:undo _r_:redo
Buffers: _p_revious _n_ext _b_:select _f_ind-file
Resize: _H_:splitter left _J_:splitter down _K_:splitter up _L_:splitter right
Move: _a_:up _z_:down _i_menu
"
("z" scroll-up-line)
("a" scroll-down-line)
("i" idomenu)
("h" windmove-left)
("j" windmove-down)
("k" windmove-up)
("l" windmove-right)
("u" winner-undo)
("r" winner-redo)
("p" previous-buffer)
("n" next-buffer)
("b" switch-to-buffer)
("f" find-file)
("s" split-window-below)
("v" split-window-right)
("c" delete-window)
("o" delete-other-windows)
("H" hydra-move-splitter-left)
("J" hydra-move-splitter-down)
("K" hydra-move-splitter-up)
("L" hydra-move-splitter-right)
("q" nil))

View file

@ -1,15 +0,0 @@
;;; ui/hydra/config.el -*- lexical-binding: t; -*-
(use-package! hydra-examples
:commands (hydra-move-splitter-up
hydra-move-splitter-down
hydra-move-splitter-right
hydra-move-splitter-left))
;;;###package hydra
(setq lv-use-separator t)
(defadvice! +hydra--inhibit-window-switch-hooks-a (fn)
:around #'lv-window
(let (doom-switch-window-hook)
(funcall fn)))

View file

@ -1,4 +0,0 @@
;; -*- no-byte-compile: t; -*-
;;; ui/hydra/packages.el
(package! hydra :pin "317e1de33086637579a7aeb60f77ed0405bf359b")

View file

@ -86,7 +86,7 @@ in [[../../editor/evil/+commands.el][config/default/+evil-commands.el]]).
| ~+workspace/other~ | [[kbd:][SPC TAB `]] | Switch to last workspace |
| ~+workspace/switch-left~ | [[kbd:][SPC TAB []] / [[kbd:][[ w]] / [[kbd:][gT]] | Switch to previous workspace |
| ~+workspace/switch-right~ | [[kbd:][SPC TAB ]]] / [[kbd:][] w]] / [[kbd:][gt]] | Switch to next workspace |
| ~+workspace/delete~ | [[kbd:][SPC TAB d]] | Delete the current workspace |
| ~+workspace/kill~ | [[kbd:][SPC TAB d]] | Delete the current workspace |
| ~+workspace/kill-session~ | [[kbd:][SPC TAB x]] / [[kbd:][:sclear]] | Clears the current session (kills all windows and buffers) |
* TODO Configuration
@ -120,6 +120,6 @@ in [[../../editor/evil/+commands.el][config/default/+evil-commands.el]]).
+ ~+workspace-save-session NAME~
+ ~+workspace-new NAME~
+ ~+workspace-rename NAME NEW-NAME~
+ ~+workspace-delete NAME &optional INHIBIT-KILL-P~
+ ~+workspace-kill NAME &optional INHIBIT-KILL-P~
+ ~+workspace-switch NAME &optional AUTO-CREATE-P~
+ ~+workspace-protected-p NAME~ -> bool

View file

@ -23,8 +23,8 @@
;;;###autoload (autoload '+workspace:delete "ui/workspaces/autoload/evil" nil t)
(evil-define-command +workspace:delete ()
"Ex wrapper around `+workspace/delete'."
(interactive) (+workspace/delete (+workspace-current-name)))
"Ex wrapper around `+workspace/kill'."
(interactive) (+workspace/kill (+workspace-current-name)))
;;;###autoload (autoload '+workspace:switch-next "ui/workspaces/autoload/evil" nil t)
(evil-define-command +workspace:switch-next (&optional count)

View file

@ -150,10 +150,10 @@ success, nil otherwise."
(persp-rename new-name (+workspace-get name)))
;;;###autoload
(defun +workspace-delete (workspace &optional inhibit-kill-p)
"Delete the workspace denoted by WORKSPACE, which can be the name of a perspective
or its hash table. If INHIBIT-KILL-P is non-nil, don't kill this workspace's
buffers."
(defun +workspace-kill (workspace &optional inhibit-kill-p)
"Kill the workspace denoted by WORKSPACE, which can be the name of a
perspective or its hash table. If INHIBIT-KILL-P is non-nil, don't kill this
workspace's buffers."
(unless (stringp workspace)
(setq workspace (persp-name workspace)))
(when (+workspace--protected-p workspace)
@ -231,14 +231,14 @@ workspace."
('error (+workspace-error ex t))))
;;;###autoload
(defun +workspace/delete (name)
(defun +workspace/kill (name)
"Delete this workspace. If called with C-u, prompts you for the name of the
workspace to delete."
(interactive
(let ((current-name (+workspace-current-name)))
(list
(if current-prefix-arg
(completing-read (format "Delete workspace (default: %s): " current-name)
(completing-read (format "Kill workspace (default: %s): " current-name)
(+workspace-list-names)
nil nil nil nil current-name)
current-name))))
@ -250,9 +250,9 @@ workspace to delete."
(cond ((delq (selected-frame) (persp-frames-with-persp (get-frame-persp)))
(user-error "Can't close workspace, it's visible in another frame"))
((not (equal (+workspace-current-name) name))
(+workspace-delete name))
(+workspace-kill name))
((cdr workspaces)
(+workspace-delete name)
(+workspace-kill name)
(+workspace-switch
(if (+workspace-exists-p +workspace--last)
+workspace--last
@ -262,7 +262,7 @@ workspace to delete."
(t
(+workspace-switch +workspaces-main t)
(unless (string= (car workspaces) +workspaces-main)
(+workspace-delete name))
(+workspace-kill name))
(doom/kill-all-buffers (doom-buffer-list))))
(+workspace-message (format "Deleted '%s' workspace" name) 'success)))
('error (+workspace-error ex t))))
@ -275,7 +275,7 @@ workspace to delete."
(persps (length (+workspace-list-names)))
(buffers 0))
(let ((persp-autokill-buffer-on-remove t))
(unless (cl-every #'+workspace-delete (+workspace-list-names))
(unless (cl-every #'+workspace-kill (+workspace-list-names))
(+workspace-error "Could not clear session")))
(+workspace-switch +workspaces-main t)
(setq buffers (doom/kill-all-buffers (buffer-list)))
@ -401,7 +401,7 @@ the next."
(let ((frame-persp (frame-parameter nil 'workspace)))
(if (string= frame-persp (+workspace-current-name))
(delete-frame)
(+workspace/delete current-persp-name))))
(+workspace/kill current-persp-name))))
((+workspace-error "Can't delete last workspace" t)))))))
@ -490,7 +490,7 @@ created."
(setq frame (selected-frame)))
(let ((frame-persp (frame-parameter frame 'workspace)))
(when (string= frame-persp (+workspace-current-name))
(+workspace/delete frame-persp)))))
(+workspace/kill frame-persp)))))
;;;###autoload
(defun +workspaces-associate-frame-fn (frame &optional _new-frame-p)

View file

@ -35,7 +35,6 @@
;;doom-quit ; DOOM quit-message prompts when you quit Emacs
;;(emoji +unicode) ; 🙂
hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
;;hydra
;;indent-guides ; highlighted indent columns
;;ligatures ; ligatures and symbols to make your code pretty again
;;minimap ; show a map of the code on the side