Merge remote-tracking branch 'origin/develop' into download-iosevka

This commit is contained in:
James Ravn 2020-02-25 19:50:12 +00:00
commit 3a257cfc56
No known key found for this signature in database
GPG key ID: 52C372C72159D6EE
428 changed files with 9639 additions and 6497 deletions

View file

@ -3,9 +3,9 @@
(defvar +calendar--wconf nil)
(defun +calendar--init ()
(if-let* ((win (cl-loop for win in (doom-visible-windows)
if (string-match-p "^\\*cfw:" (buffer-name (window-buffer win)))
return win)))
(if-let (win (cl-find-if (lambda (b) (string-match-p "^\\*cfw:" (buffer-name b)))
(doom-visible-windows)
:key #'window-buffer))
(select-window win)
(call-interactively +calendar-open-function)))

View file

@ -1,6 +1,6 @@
;; -*- no-byte-compile: t; -*-
;;; app/calendar/packages.el
(package! calfw)
(package! calfw-org)
(package! org-gcal)
(package! calfw :pin "03abce9762")
(package! calfw-org :pin "03abce9762")
(package! org-gcal :pin "6821e34967")

View file

@ -7,8 +7,11 @@
- [[#description][Description]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#dependencies][Dependencies]]
- [[#prerequisites][Prerequisites]]
- [[#macos][macOS]]
- [[#debian--ubuntu][Debian / Ubuntu]]
- [[#arch-linux][Arch Linux]]
- [[#nixos][NixOS]]
- [[#features][Features]]
- [[#an-irc-client-in-emacs][An IRC Client in Emacs]]
- [[#configuration][Configuration]]
@ -17,7 +20,7 @@
- [[#troubleshooting][Troubleshooting]]
* Description
This module turns adds an IRC client to Emacs with OS notifications.
This module turns Emacs into an IRC client, capable of OS notifications.
** Module Flags
This module provides no flags.
@ -26,11 +29,27 @@ This module provides no flags.
+ [[https://github.com/jorgenschaefer/circe][circe]]
+ [[https://github.com/eqyiel/circe-notifications][circe-notifications]]
* Dependencies
This module requires =gnutls-cli= or =openssl= for secure connections.
* Prerequisites
This module has no direct prerequisites.
This module requires =gnutls= for secure IRC connections to work.
** macOS
#+BEGIN_SRC sh
brew install gnutls
#+END_SRC
** Debian / Ubuntu
#+BEGIN_SRC sh
apt install gnutls-bin
#+END_SRC
** Arch Linux
#+BEGIN_SRC sh
pacman -S gnutls
#+END_SRC
** NixOS
#+BEGIN_SRC nix
environment.systemPackages = [ pkgs.gnutls ];
#+END_SRC
* Features
** An IRC Client in Emacs
@ -54,20 +73,23 @@ When in a circe buffer these keybindings will be available.
| ~circe-reconnect~ | =SPC m R= | Reconnect the current server |
* Configuration
Use ~set-irc-server!~ to configure IRC servers. Its second argument (a plist)
Use ~set-irc-server! SERVER PLIST~ to configure IRC servers. Its second argument (a plist)
takes the same arguments as ~circe-network-options~.
#+BEGIN_SRC emacs-lisp :tangle no
(set-irc-server! "chat.freenode.net"
`(:tls t
:nick "doom"
:sasl-username "myusername"
:sasl-password "mypassword"
:channels ("#emacs")))
;; if you omit =:host=, ~SERVER~ will be used instead.
(after! circe
(set-irc-server! "chat.freenode.net"
`(:tls t
:port 6697
:nick "doom"
:sasl-username "myusername"
:sasl-password "mypassword"
:channels ("#emacs"))))
#+END_SRC
*It is a obviously a bad idea to store auth-details in plaintext,* so here are
some ways to avoid that:
However, *it is a obviously a bad idea to store your password in plaintext,* so
here are ways to avoid that:
** Pass: the unix password manager
[[https://www.passwordstore.org/][Pass]] is my tool of choice. I use it to manage my passwords. If you activate the
@ -80,6 +102,7 @@ password store.
#+BEGIN_SRC emacs-lisp :tangle no
(set-irc-server! "chat.freenode.net"
`(:tls t
:port 6697
:nick "doom"
:sasl-username ,(+pass-get-user "irc/freenode.net")
:sasl-password ,(+pass-get-secret "irc/freenode.net")
@ -105,10 +128,10 @@ Note that =+pass-get-user= tries to find your username by looking for the fields
listed in =+pass-user-fields= (by default =login=, =user==, =username== and
=email=)=). An example configuration looks like
#+BEGIN_SRC txt :tangle no
#+begin_example
mysecretpassword
username: myusername
#+END_SRC
#+end_example
** Emacs' auth-source API
~auth-source~ is built into Emacs. As suggested [[https://github.com/jorgenschaefer/circe/wiki/Configuration#safer-password-management][in the circe wiki]], you can store

View file

@ -3,8 +3,9 @@
(defvar +irc--workspace-name "*IRC*")
(defun +irc-setup-wconf (&optional inhibit-workspace)
(unless inhibit-workspace
(+workspace-switch +irc--workspace-name t))
(when (and (featurep! :ui workspaces)
(not inhibit-workspace))
(+workspace-switch +irc--workspace-name 'auto-create))
(let ((buffers (doom-buffers-in-mode 'circe-mode nil t)))
(if buffers
(ignore (switch-to-buffer (car buffers)))
@ -20,17 +21,12 @@
If INHIBIT-WORKSPACE (the universal argument) is non-nil, don't spawn a new
workspace for it."
(interactive "P")
(cond ((and (featurep! :ui workspaces)
(+workspace-exists-p +irc--workspace-name))
(+workspace-switch +irc--workspace-name))
((not (+irc-setup-wconf inhibit-workspace))
(user-error "Couldn't start up a workspace for IRC")))
(if (doom-buffers-in-mode 'circe-mode (buffer-list) t)
(message "Circe buffers are already open")
(if circe-network-options
(cl-loop for network in circe-network-options
collect (circe (car network)))
(call-interactively #'circe))))
(+irc-setup-wconf inhibit-workspace)
(cond ((doom-buffers-in-mode 'circe-mode (doom-buffer-list) t)
(message "Circe buffers are already open"))
(circe-network-options
(mapc #'circe (mapcar #'car circe-network-options)))
((call-interactively #'circe))))
;;;###autoload
(defun +irc/connect (&optional inhibit-workspace)
@ -52,16 +48,17 @@ workspace for it."
(defun +irc/quit ()
"Kill current circe session and workgroup."
(interactive)
(if (y-or-n-p "Really kill IRC session?")
(let (circe-channel-killed-confirmation
circe-server-killed-confirmation)
(when +irc--defer-timer
(cancel-timer +irc--defer-timer))
(disable-circe-notifications)
(mapc #'kill-buffer (doom-buffers-in-mode 'circe-mode (buffer-list) t))
(when (equal (+workspace-current-name) +irc--workspace-name)
(+workspace/delete +irc--workspace-name)))
(message "Aborted")))
(unless (y-or-n-p "Really kill IRC session?")
(user-error "Aborted"))
(let (circe-channel-killed-confirmation
circe-server-killed-confirmation)
(when +irc--defer-timer
(cancel-timer +irc--defer-timer))
(disable-circe-notifications)
(mapc #'kill-buffer (doom-buffers-in-mode 'circe-mode (buffer-list) t))
(when (featurep! :ui workspaces)
(when (equal (+workspace-current-name) +irc--workspace-name)
(+workspace/delete +irc--workspace-name)))))
;;;###autoload
(defun +irc/ivy-jump-to-channel (&optional this-server)
@ -93,7 +90,7 @@ argument) is non-nil only show channels in current server."
;;;###autoload
(defun +irc/tracking-next-buffer ()
"Dissables switching to an unread buffer unless in the irc workspace."
"Disables switching to an unread buffer unless in the irc workspace."
(interactive)
(when (derived-mode-p 'circe-mode)
(tracking-next-buffer)))
@ -106,13 +103,12 @@ argument) is non-nil only show channels in current server."
(defun +circe-buffer-p (buf)
"Return non-nil if BUF is a `circe-mode' buffer."
(with-current-buffer buf
(and (derived-mode-p 'circe-mode)
(eq (safe-persp-name (get-current-persp))
+irc--workspace-name))))
(derived-mode-p 'circe-mode)))
;;;###autoload
(defun +irc--add-circe-buffer-to-persp-h ()
(when (bound-and-true-p persp-mode)
(when (and (bound-and-true-p persp-mode)
(+workspace-exists-p +irc--workspace-name))
(let ((persp (get-current-persp))
(buf (current-buffer)))
;; Add a new circe buffer to irc workspace when we're in another workspace

View file

@ -1,9 +1,17 @@
;;; app/irc/autoload/settings.el -*- lexical-binding: t; -*-
;;;###autodef
(defun set-irc-server! (server letvars)
(defun set-irc-server! (server plist)
"Registers an irc SERVER for circe.
SERVER can either be a name for the network (in which case you must specify a
:host), or it may be the hostname itself, in which case it will be used as the
:host.
See `circe-network-options' for details."
(after! circe
(push (cons server letvars) circe-network-options)))
(unless (plist-member plist :host)
(plist-put! plist :host server))
(setf (alist-get server circe-network-options
nil nil #'equal)
plist)))

View file

@ -93,6 +93,7 @@ playback.")
(add-hook 'doom-real-buffer-functions #'+circe-buffer-p)
(add-hook 'circe-channel-mode-hook #'turn-on-visual-line-mode)
(add-hook 'circe-mode-hook #'+irc--add-circe-buffer-to-persp-h)
(add-hook 'circe-mode-hook #'turn-off-smartparens-mode)
(defadvice! +irc--circe-run-disconnect-hook-a (&rest _)
"Runs `+irc-disconnect-hook' after circe disconnects."
@ -175,7 +176,7 @@ playback.")
(define-key lui-mode-map "\C-u" #'lui-kill-to-beginning-of-line)
(setq lui-fill-type nil)
(when (featurep! :tools flyspell)
(when (featurep! :checkers spell)
(setq lui-flyspell-p t))
(after! evil

View file

@ -1,5 +1,5 @@
;; -*- no-byte-compile: t; -*-
;;; app/irc/packages.el
(package! circe)
(package! circe-notifications)
(package! circe :pin "0c79138fb2")
(package! circe-notifications :pin "291149ac12")

View file

@ -49,4 +49,3 @@ https://mediatemple.net"
(set-popup-rules!
'(("^\\*doom-regex\\*$" :size 4 :quit nil)
("^\\*doom-regex-groups" :side 'left :size 28 :select nil :quit nil)))

View file

@ -4,10 +4,6 @@
;; by apps Reeder and Readkit. It can be invoked via `=rss'. Otherwise, if you
;; don't care for the UI you can invoke elfeed directly with `elfeed'.
(defvar +rss-elfeed-files (list "elfeed.org")
"Where to look for elfeed.org files, relative to `org-directory'. Can be
absolute paths.")
(defvar +rss-split-direction 'below
"What direction to pop up the entry buffer in elfeed.")
@ -67,8 +63,11 @@ easier to scroll through.")
(use-package! elfeed-org
:when (featurep! +org)
:after elfeed
:init
(setq rmh-elfeed-org-files (list "elfeed.org"))
:config
(let ((default-directory org-directory))
(setq rmh-elfeed-org-files
(mapcar #'expand-file-name +rss-elfeed-files)))
(elfeed-org))
(and (let ((default-directory org-directory))
(setq rmh-elfeed-org-files
(cl-remove-if-not
#'file-exists-p (mapcar #'expand-file-name rmh-elfeed-org-files))))
(elfeed-org)))

View file

@ -1,5 +1,5 @@
;; -*- no-byte-compile: t; -*-
;;; app/rss/packages.el
(package! elfeed)
(package! elfeed-org)
(package! elfeed :pin "3f0edb1737")
(package! elfeed-org :pin "77b6bbf222")

View file

@ -83,6 +83,7 @@ that works with the feature/popup module."
"Open a visible link, username or hashtag in a `twittering-mode' buffer."
(interactive)
(require 'avy)
;; REVIEW Is this necessary anymore with `link-hint'
(let ((pt (avy-with +twitter/ace-link
(avy--process
(+twitter--collect-links)

View file

@ -1,5 +1,5 @@
;; -*- no-byte-compile: t; -*-
;;; app/twitter/packages.el
(package! twittering-mode)
(package! avy)
(package! twittering-mode :pin "114891e8fd")
(package! avy :pin "cf95ba9582")

View file

@ -1,131 +0,0 @@
#+TITLE: app/write
#+DATE: October 10, 2019
#+SINCE: v1.3
#+STARTUP: inlineimages
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#prerequisites][Prerequisites]]
- [[#language-tool][Language Tool]]
- [[#wordnut][Wordnut]]
- [[#features][Features]]
- [[#m-x-write-mode][~M-x +write-mode~]]
- [[#language-tool-langtool][Language Tool ~+langtool~]]
- [[#commands][Commands]]
- [[#wordnut-wordnut][Wordnut ~+wordnut~]]
- [[#commands-1][Commands]]
- [[#synosaurus][Synosaurus]]
- [[#commands-2][Commands]]
- [[#configuration][Configuration]]
- [[#mixed-pitch-mode][mixed-pitch-mode]]
- [[#appendix][Appendix]]
- [[#minor-modes][Minor modes]]
- [[#commands-3][Commands]]
* Description
Adds word processing tools and the ~+write-mode~ minor mode, which converts
Emacs into a more comfortable writing environment.
** Module Flags
This module provides two module flags:
- ~+langtool~ Enables language tool integration.
- ~+wordnut~ Enables wordnet integration.
** Plugins
+ [[https://github.com/hpdeifel/synosaurus][synosaurus]]
+ [[https://gitlab.com/jabranham/mixed-pitch][mixed-pitch]]
+ [[https://github.com/joostkremers/visual-fill-column][visual-fill-column]]
+ [[https://github.com/mhayashi1120/Emacs-langtool][langtool]]* (=+langtool=)
+ [[https://github.com/gromnitsky/wordnut][wordnut]]* (=+wordnut=)
* Prerequisites
** Language Tool
Either download and deploy it from https://languagetool.org/ or install it
through your OS package manager:
#+BEGIN_SRC sh
# MacOS/Homebrew users:
brew install languagetool
# Arch Linux users:
sudo pacman -S languagetool
#+END_SRC
This module tries to guess the location of languagetool-commandline.jar. If you
get a warning that Doom =couldn't find languagetool-commandline.jar=, you will
need to find langaugetool-commandline.jar and set ~langtool-language-tool-jar~
to its path.
** Wordnut
This requires =wordnet= to be installed, which should be available through your
OS package manager:
#+BEGIN_SRC sh
# MacOS/Homebrew users:
brew install wordnet
# Arch Linux users:
sudo pacaur -S wordnet # on the AUR
#+END_SRC
* Features
** ~M-x +write-mode~
Write mode makes Emacs a more comfortable writing environment by:
- Centering the buffer (with ~visual-fill-column-mode~), ala distraction-free
mode from other text editors.
- Soft-wrapping long text lines with ~visual-line-mode~.
- Enabling ~mixed-pitch-mode~, allowing fixed-width and variable-pitch fonts to
co-exist in one buffer. For example, a monospace font for SRC blocks and Arial
for everything else.
- In org-mode:
- Turns on ~org-indent-mode~
- Turns on ~+org-pretty-mode~
** Language Tool ~+langtool~
[[https://www.languagetool.org/][Language Tool]] is a polyglot proofreader service that checks for grammar and
stylistic issues in your writing. This requires Java 1.8+.
#+begin_quote
This requires Java 1.8+
#+end_quote
*** Commands
- ~langtool-check~
- ~langtool-correct-buffer~
** Wordnut ~+wordnut~
Wordnut provides a searchable dictionary frontend for Emacs. This requires
~wordnet~, which should be available in your OS's package manager.
*** Commands
- ~wordnut-search~
- ~wordnut-lookup-curent-word~
** Synosaurus
Synosaurus provides a service for looking up synonyms. It requires an internet
connection.
*** Commands
- ~synosaurus-lookup~
- ~synosaurus-choose-and-replace~
* Configuration
** mixed-pitch-mode
To configure which faces are displayed with fixed-pitch fonts in
~mixed-pitch-mode~, look into ~mixed-pitch-fixed-pitch-faces~.
* Appendix
** Minor modes
- ~+write-mode~
- ~mixed-pitch-mode~
** Commands
- ~langtool-check~
- ~langtool-correct-buffer~
- ~synosaurus-choose-and-replace~
- ~synosaurus-lookup~
- ~wordnut-lookup-curent-word~
- ~wordnut-search~

View file

@ -1,43 +0,0 @@
;;; app/write/autoload.el -*- lexical-binding: t; -*-
;;;###autoload
(defvar +write-mode-map (make-sparse-keymap)
"TODO")
;;;###autoload
(define-minor-mode +write-mode
"Turns Emacs into a more comfortable writing environment and word processor."
:init-value nil
:keymap +write-mode-map
(setq-local visual-fill-column-center-text t)
(when +write-text-scale
(text-scale-set (if +write-mode 2 0)))
(when +write-line-spacing
(setq-local line-spacing +write-line-spacing)))
;;;###autoload
(defun +write|init-org-mode ()
"Initializes `org-mode' specific settings for `+write-mode'."
(when (eq major-mode 'org-mode)
(+org-pretty-mode (if +write-mode +1 -1))))
;;;###autoload
(defun +write|init-line-numbers ()
(display-line-numbers-mode (if +write-mode +1 -1)))
;;;###autoload
(defun +write|init-mixed-pitch ()
(mixed-pitch-mode (if +write-mode +1 -1)))
;;;###autoload
(defun +write|init-visual-fill-column ()
(visual-fill-column-mode (if +write-mode +1 -1)))
;;;###autoload
(add-hook! '+write-mode-hook
#'(flyspell-mode
visual-line-mode
+write|init-mixed-pitch
+write|init-visual-fill-column
+write|init-line-numbers
+write|init-org-mode))

View file

@ -1,56 +0,0 @@
;;; app/write/config.el -*- lexical-binding: t; -*-
(defvar +write-text-scale nil
"What to scale the text up to in `+write-mode'. Uses `text-scale-set'.")
(defvar +write-line-spacing nil
"What to set `line-spacing' in `+write-mode'.")
;;
;; Packages
(use-package! langtool
:when (featurep! +langtool)
:commands (langtool-check
langtool-check-done
langtool-show-message-at-point
langtool-correct-buffer)
:init (setq langtool-default-language "en-US")
:config
(unless langtool-language-tool-jar
(setq langtool-language-tool-jar
(cond (IS-MAC
(locate-file "libexec/languagetool-commandline.jar"
(doom-files-in "/usr/local/Cellar/languagetool"
:type 'dirs
:depth 2)))
(IS-LINUX
"/usr/share/java/languagetool/languagetool-commandline.jar")))))
;; `synosaurus'
(setq synosaurus-choose-method 'default)
;; `mixed-pitch'
(after! mixed-pitch
(setq mixed-pitch-fixed-pitch-faces
(append mixed-pitch-fixed-pitch-faces
'(org-todo-keyword-todo
org-todo-keyword-habt
org-todo-keyword-done
org-todo-keyword-wait
org-todo-keyword-kill
org-todo-keyword-outd
org-todo
org-indent
line-number
line-number-current-line
org-special-keyword
org-date
org-property-value
org-special-keyword
org-property-value
org-ref-cite-face
org-tag
font-lock-comment-face))))

View file

@ -1,7 +0,0 @@
;; -*- lexical-binding: t; no-byte-compile: t; -*-
;;; app/write/doctor.el
(when (featurep! +langtool)
(require 'langtool)
(unless (file-exists-p langtool-language-tool-jar)
(warn! "Couldn't find languagetool-commandline.jar")))

View file

@ -1,12 +0,0 @@
;; -*- no-byte-compile: t; -*-
;;; app/write/packages.el
(package! synosaurus)
(package! mixed-pitch)
(when (featurep! +langtool)
(package! langtool))
(when (featurep! +wordnut)
(package! wordnut))
(package! visual-fill-column)

View file

@ -0,0 +1,68 @@
#+TITLE: checkers/grammar
#+DATE: January 9, 2020
#+SINCE: v3.0.0
#+STARTUP: inlineimages nofold
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#maintainers][Maintainers]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#prerequisites][Prerequisites]]
- [[#features][Features]]
- [[#language-tool][Language Tool]]
- [[#commands][Commands]]
- [[#writegood-mode][writegood-mode]]
- [[#configuration][Configuration]]
- [[#troubleshooting][Troubleshooting]]
* Description
This module adds grammar checking to Emacs to aid your writing by combining
=lang-tool= and =writegood-mode=.
** Maintainers
This module has no dedicated maintainers.
** Module Flags
This module provides no flags.
** Plugins
+ [[https://github.com/mhayashi1120/Emacs-langtool][langtool]]
+ [[https://github.com/bnbeckwith/writegood-mode][writegood-mode]]
* Prerequisites
This module requires langtool (which requires =Java 1.8+=).
It can be acquired either from https://languagetool.org/ or your OS's package
manager:
+ macOS: ~brew install languagetool~
+ Arch Linux: ~pacman -S languagetool~
This module tries to guess the location of languagetool-commandline.jar. If you
get a warning that Doom =couldn't find languagetool-commandline.jar=, you will
need to set ~langtool-language-tool-jar~ to its location.
* Features
An in-depth list of features, how to use them, and their dependencies.
** Language Tool
[[https://www.languagetool.org/][Language Tool]] is a polyglot proofreader service that checks for grammar and
stylistic issues in your writing. This requires Java 1.8+.
#+begin_quote
This requires Java 1.8+
#+end_quote
*** Commands
- ~langtool-check~
- ~langtool-correct-buffer~
** writegood-mode
This minor mode highlights weasel words, duplication and passive voice.
* Configuration
How to configure this module, including common problems and how to address them.
* Troubleshooting
Common issues and their solution, or places to look for help.

View file

@ -0,0 +1,29 @@
;;; checkers/grammar/config.el -*- lexical-binding: t; -*-
(use-package! langtool
:commands (langtool-check
langtool-check-done
langtool-show-message-at-point
langtool-correct-buffer)
:init (setq langtool-default-language "en-US")
:config
(unless langtool-language-tool-jar
(setq langtool-language-tool-jar
(cond (IS-MAC
(locate-file "libexec/languagetool-commandline.jar"
(doom-files-in "/usr/local/Cellar/languagetool"
:type 'dirs
:depth 2)))
(IS-LINUX
"/usr/share/java/languagetool/languagetool-commandline.jar")))))
;; Detects weasel words, passive voice and duplicates. Proselint would be a
;; better choice.
(use-package! writegood-mode
:hook (org-mode markdown-mode rst-mode asciidoc-mode latex-mode)
:config
(map! :localleader
:map writegood-mode-map
"g" #'writegood-grade-level
"r" #'writegood-reading-ease))

View file

@ -0,0 +1,5 @@
;; -*- no-byte-compile: t; -*-
;;; checkers/grammar/packages.el
(package! langtool :pin "a71ed02ce0")
(package! writegood-mode :pin "b71757ec33")

View file

@ -0,0 +1,27 @@
;;; checkers/spell/autoload.el -*- lexical-binding: t; -*-
;;;###autodef
(defalias 'flyspell-mode! #'flyspell-mode)
(defvar +spell--flyspell-predicate-alist nil
"TODO")
;;;###autodef
(defun set-flyspell-predicate! (modes predicate)
"TODO"
(declare (indent defun))
(dolist (mode (doom-enlist modes) +spell--flyspell-predicate-alist)
(add-to-list '+spell--flyspell-predicate-alist (cons mode predicate))))
;;;###autoload
(defun +spell-init-flyspell-predicate-h ()
"TODO"
(when-let (pred (assq major-mode +spell--flyspell-predicate-alist))
(setq-local flyspell-generic-check-word-predicate (cdr pred))))
;;;###autoload
(defun +spell-correction-at-point-p (&optional point)
"TODO"
(cl-loop for ov in (overlays-at (or point (point)))
if (overlay-get ov 'flyspell-overlay)
return t))

View file

@ -1,11 +1,8 @@
;;; tools/flyspell/config.el -*- lexical-binding: t; -*-
;;; checkers/spell/config.el -*- lexical-binding: t; -*-
;;
;;; Packages
(defvar ispell-dictionary "en_US")
(after! ispell
(add-to-list 'ispell-extra-args "--dont-tex-check-comments")
;; Don't spellcheck org blocks
(pushnew! ispell-skip-region-alist
'(":\\(PROPERTIES\\|LOGBOOK\\):" . ":END:")
@ -23,13 +20,13 @@
((executable-find "hunspell") 'hunspell))
(`aspell
(setq ispell-program-name "aspell"
ispell-extra-args '("--sug-mode=ultra" "--run-together"))
ispell-extra-args '("--sug-mode=ultra" "--run-together" "--dont-tex-check-comments"))
(add-hook! 'text-mode-hook
(defun +flyspell-remove-run-together-switch-for-aspell-h ()
(defun +spell-remove-run-together-switch-for-aspell-h ()
(setq-local ispell-extra-args (remove "--run-together" ispell-extra-args))))
(defun +flyspell-setup-ispell-extra-args-a (orig-fun &rest args)
(defun +spell-init-ispell-extra-args-a (orig-fun &rest args)
:around '(ispell-word flyspell-auto-correct-word)
(let ((ispell-extra-args (remove "--run-together" ispell-extra-args)))
(ispell-kill-ispell t)
@ -49,12 +46,23 @@
;; messages for every word when checking the entire buffer
flyspell-issue-message-flag nil)
(add-hook 'text-mode-hook #'flyspell-mode)
(when (featurep! +prog)
(add-hook 'prog-mode-hook #'flyspell-prog-mode))
(add-hook! '(org-mode-hook
markdown-mode-hook
TeX-mode-hook
rst-mode-hook
mu4e-compose-mode-hook
message-mode-hook
git-commit-mode-hook)
#'flyspell-mode)
(when (featurep! +everywhere)
(add-hook! '(yaml-mode-hook
conf-mode-hook
prog-mode-hook)
#'flyspell-prog-mode))
(add-hook! 'flyspell-mode-hook
(defun +flyspell-inhibit-duplicate-detection-maybe-h ()
(defun +spell-inhibit-duplicate-detection-maybe-h ()
"Don't mark duplicates when style/grammar linters are present.
e.g. proselint and langtool."
(when (or (and (bound-and-true-p flycheck-mode)
@ -64,16 +72,21 @@ e.g. proselint and langtool."
;; Ensure mode-local predicates declared with `set-flyspell-predicate!' are
;; used in their respective major modes.
(add-hook 'flyspell-mode-hook #'+flyspell-init-predicate-h)
(add-hook 'flyspell-mode-hook #'+spell-init-flyspell-predicate-h)
(map! :map flyspell-mouse-map
"RET" #'flyspell-correct-word-generic
[return] #'flyspell-correct-word-generic
[mouse-1] #'flyspell-correct-word-generic))
(let ((flyspell-correct
(general-predicate-dispatch nil
(and (not (or mark-active (ignore-errors (evil-insert-state-p))))
(memq 'flyspell-incorrect (face-at-point nil t)))
#'flyspell-correct-at-point)))
(map! :map flyspell-mouse-map
"RET" flyspell-correct
[return] flyspell-correct
[mouse-1] #'flyspell-correct-at-point)))
(use-package! flyspell-correct
:commands flyspell-correct-word-generic flyspell-correct-previous-word-generic
:commands flyspell-correct-at-point flyspell-correct-previous
:config
(cond ((and (featurep! :completion helm)
(require 'flyspell-correct-helm nil t)))
@ -82,3 +95,7 @@ e.g. proselint and langtool."
((require 'flyspell-correct-popup nil t)
(setq flyspell-popup-correct-delay 0.8)
(define-key popup-menu-keymap [escape] #'keyboard-quit))))
(use-package! flyspell-lazy
:after flyspell)

View file

@ -0,0 +1,11 @@
;; -*- no-byte-compile: t; -*-
;;; checkers/spell/packages.el
(package! flyspell-correct :pin "b0353a41a7")
(cond ((featurep! :completion ivy)
(package! flyspell-correct-ivy :pin "b0353a41a7"))
((featurep! :completion helm)
(package! flyspell-correct-helm :pin "b0353a41a7"))
((package! flyspell-correct-popup :pin "b0353a41a7")))
(package! flyspell-lazy :pin "3ebf68cc9e")

View file

@ -0,0 +1,25 @@
;;; checkers/syntax/autoload.el -*- lexical-binding: t; -*-
;;;###autodef
(defun set-next-checker! (mode checker next &optional append)
"TODO"
(let ((fn (intern (format "+syntax--init-checkers-for-%s-h" mode))))
(fset fn
(lambda ()
(if (not (bound-and-true-p flycheck-mode))
(add-hook 'flycheck-mode-hook fn 'append 'local)
(flycheck-add-next-checker checker next append)
(remove-hook 'flycheck-mode-hook fn 'local))))
(add-hook (intern (format "%s-hook" mode)) fn)))
;;;###autoload
(defun +syntax-init-popups-h ()
"Activate `flycheck-posframe-mode' if available and in GUI Emacs.
Activate `flycheck-popup-tip-mode' otherwise.
Do nothing if `lsp-ui-mode' is active and `lsp-ui-sideline-enable' is non-nil."
(unless (and (bound-and-true-p lsp-ui-mode)
lsp-ui-sideline-enable)
(if (and (fboundp 'flycheck-posframe-mode)
(display-graphic-p))
(flycheck-posframe-mode +1)
(flycheck-popup-tip-mode +1))))

View file

@ -1,12 +1,7 @@
;;; tools/flycheck/config.el -*- lexical-binding: t; -*-
(defvar +flycheck-lazy-idle-delay 3.0
"The delay before flycheck checks the buffer, after a check that produces no
errors.")
;;; checkers/syntax/config.el -*- lexical-binding: t; -*-
;;
;;; Packages
;;; Flycheck
(use-package! flycheck
:commands flycheck-list-errors flycheck-buffer
@ -24,11 +19,10 @@ errors.")
;; Don't commandeer input focus if the error message pops up (happens when
;; tooltips and childframes are disabled).
(after! flycheck
(set-popup-rule! flycheck-error-message-buffer :select nil))
(set-popup-rule! "^\\*Flycheck error messages\\*" :select nil)
(add-hook! 'doom-escape-hook :append
(defun +flycheck-buffer-h ()
(defun +syntax-check-buffer-h ()
"Flycheck buffer on ESC in normal mode."
(when flycheck-mode
(ignore-errors (flycheck-buffer))
@ -47,7 +41,7 @@ errors.")
(use-package! flycheck-popup-tip
:commands flycheck-popup-tip-show-popup flycheck-popup-tip-delete-popup
:init (add-hook 'flycheck-mode-hook #'+flycheck-init-popups-h)
:init (add-hook 'flycheck-mode-hook #'+syntax-init-popups-h)
:config
(setq flycheck-popup-tip-error-prefix "")
(after! evil
@ -55,7 +49,7 @@ errors.")
;; the cursor's position or cause disruptive input delays.
(add-hook! '(evil-insert-state-entry-hook evil-replace-state-entry-hook)
#'flycheck-popup-tip-delete-popup)
(defadvice! +flycheck--disable-popup-tip-maybe-a (&rest _)
(defadvice! +syntax--disable-flycheck-popup-tip-maybe-a (&rest _)
:before-while #'flycheck-popup-tip-show-popup
(if evil-local-mode
(eq evil-state 'normal)
@ -65,7 +59,7 @@ errors.")
(use-package! flycheck-posframe
:when (featurep! +childframe)
:defer t
:init (add-hook 'flycheck-mode-hook #'+flycheck-init-popups-h)
:init (add-hook 'flycheck-mode-hook #'+syntax-init-popups-h)
:config
(setq flycheck-posframe-warning-prefix ""
flycheck-posframe-info-prefix "··· "
@ -79,3 +73,7 @@ errors.")
(add-hook! 'flycheck-posframe-inhibit-functions
#'evil-insert-state-p
#'evil-replace-state-p)))
;;
;;; TODO Flymake

View file

@ -0,0 +1,9 @@
;; -*- no-byte-compile: t; -*-
;;; checkers/syntax/packages.el
(package! flycheck :pin "74377fa9c7")
(package! flycheck-popup-tip :pin "ef86aad907")
(when (featurep! +childframe)
(package! flycheck-posframe :pin "2b3e94c2e4"))
;; TODO flymake?

View file

@ -26,9 +26,10 @@ https://assets.doomemacs.org/completion/company/overlay.png
** Module Flags
+ =+childframe= Enables displaying completion candidates in a child frame,
rather than an overlay or tooltip (among with other UI enhancements). *This
requires GUI Emacs 26.1+.*
requires GUI Emacs 26.1+ and is incompatible with the =+tng= flag*
+ =+tng= Enables completion using only ~TAB~. Pressing ~TAB~ will select the
next completion suggestion, while ~S-TAB~ will select the previous one.
next completion suggestion, while ~S-TAB~ will select the previous one. *This
is incompatible with the =+childframe= flag*
** Plugins
+ [[https://github.com/company-mode/company-mode][company-mode]]

View file

@ -20,7 +20,8 @@
:config
(when (featurep! :editor evil)
(add-hook 'company-mode-hook #'evil-normalize-keymaps)
;; Don't persist company popups when switching back to normal mode.
(add-hook 'evil-normal-state-entry-hook #'company-abort)
;; Allow users to switch between backends on the fly. E.g. C-x C-s followed
;; by C-x C-n, will switch from `company-yasnippet' to
;; `company-dabbrev-code'.
@ -70,47 +71,42 @@
company-box-max-candidates 50
company-box-icons-alist 'company-box-icons-all-the-icons
company-box-icons-functions
'(+company-box-icons--yasnippet-fn
company-box-icons--lsp
+company-box-icons--elisp-fn
company-box-icons--acphp)
(cons #'+company-box-icons--elisp-fn
(delq 'company-box-icons--elisp
company-box-icons-functions))
company-box-icons-all-the-icons
`((Unknown . ,(all-the-icons-material "find_in_page" :height 0.8 :face 'all-the-icons-purple))
(Text . ,(all-the-icons-material "text_fields" :height 0.8 :face 'all-the-icons-green))
(Method . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red))
(Function . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red))
(Constructor . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red))
(Field . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red))
(Variable . ,(all-the-icons-material "adjust" :height 0.8 :face 'all-the-icons-blue))
(Class . ,(all-the-icons-material "class" :height 0.8 :face 'all-the-icons-red))
(Interface . ,(all-the-icons-material "settings_input_component" :height 0.8 :face 'all-the-icons-red))
(Module . ,(all-the-icons-material "view_module" :height 0.8 :face 'all-the-icons-red))
(Property . ,(all-the-icons-material "settings" :height 0.8 :face 'all-the-icons-red))
(Unit . ,(all-the-icons-material "straighten" :height 0.8 :face 'all-the-icons-red))
(Value . ,(all-the-icons-material "filter_1" :height 0.8 :face 'all-the-icons-red))
(Enum . ,(all-the-icons-material "plus_one" :height 0.8 :face 'all-the-icons-red))
(Keyword . ,(all-the-icons-material "filter_center_focus" :height 0.8 :face 'all-the-icons-red))
(Snippet . ,(all-the-icons-material "short_text" :height 0.8 :face 'all-the-icons-red))
(Color . ,(all-the-icons-material "color_lens" :height 0.8 :face 'all-the-icons-red))
(File . ,(all-the-icons-material "insert_drive_file" :height 0.8 :face 'all-the-icons-red))
(Reference . ,(all-the-icons-material "collections_bookmark" :height 0.8 :face 'all-the-icons-red))
(Folder . ,(all-the-icons-material "folder" :height 0.8 :face 'all-the-icons-red))
(EnumMember . ,(all-the-icons-material "people" :height 0.8 :face 'all-the-icons-red))
(Constant . ,(all-the-icons-material "pause_circle_filled" :height 0.8 :face 'all-the-icons-red))
(Struct . ,(all-the-icons-material "streetview" :height 0.8 :face 'all-the-icons-red))
(Event . ,(all-the-icons-material "event" :height 0.8 :face 'all-the-icons-red))
(Operator . ,(all-the-icons-material "control_point" :height 0.8 :face 'all-the-icons-red))
(TypeParameter . ,(all-the-icons-material "class" :height 0.8 :face 'all-the-icons-red))
;; (Template . ,(company-box-icons-image "Template.png"))))
(Yasnippet . ,(all-the-icons-material "short_text" :height 0.8 :face 'all-the-icons-green))
(ElispFunction . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red))
(ElispVariable . ,(all-the-icons-material "check_circle" :height 0.8 :face 'all-the-icons-blue))
(ElispFeature . ,(all-the-icons-material "stars" :height 0.8 :face 'all-the-icons-orange))
(ElispFace . ,(all-the-icons-material "format_paint" :height 0.8 :face 'all-the-icons-pink))))
(defun +company-box-icons--yasnippet-fn (candidate)
(when (get-text-property 0 'yas-annotation candidate)
'Yasnippet))
(let ((all-the-icons-scale-factor 0.8))
`((Unknown . ,(all-the-icons-material "find_in_page" :face 'all-the-icons-purple))
(Text . ,(all-the-icons-material "text_fields" :face 'all-the-icons-green))
(Method . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
(Function . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
(Constructor . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
(Field . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
(Variable . ,(all-the-icons-material "adjust" :face 'all-the-icons-blue))
(Class . ,(all-the-icons-material "class" :face 'all-the-icons-red))
(Interface . ,(all-the-icons-material "settings_input_component" :face 'all-the-icons-red))
(Module . ,(all-the-icons-material "view_module" :face 'all-the-icons-red))
(Property . ,(all-the-icons-material "settings" :face 'all-the-icons-red))
(Unit . ,(all-the-icons-material "straighten" :face 'all-the-icons-red))
(Value . ,(all-the-icons-material "filter_1" :face 'all-the-icons-red))
(Enum . ,(all-the-icons-material "plus_one" :face 'all-the-icons-red))
(Keyword . ,(all-the-icons-material "filter_center_focus" :face 'all-the-icons-red))
(Snippet . ,(all-the-icons-material "short_text" :face 'all-the-icons-red))
(Color . ,(all-the-icons-material "color_lens" :face 'all-the-icons-red))
(File . ,(all-the-icons-material "insert_drive_file" :face 'all-the-icons-red))
(Reference . ,(all-the-icons-material "collections_bookmark" :face 'all-the-icons-red))
(Folder . ,(all-the-icons-material "folder" :face 'all-the-icons-red))
(EnumMember . ,(all-the-icons-material "people" :face 'all-the-icons-red))
(Constant . ,(all-the-icons-material "pause_circle_filled" :face 'all-the-icons-red))
(Struct . ,(all-the-icons-material "streetview" :face 'all-the-icons-red))
(Event . ,(all-the-icons-material "event" :face 'all-the-icons-red))
(Operator . ,(all-the-icons-material "control_point" :face 'all-the-icons-red))
(TypeParameter . ,(all-the-icons-material "class" :face 'all-the-icons-red))
(Template . ,(all-the-icons-material "short_text" :face 'all-the-icons-green))
(ElispFunction . ,(all-the-icons-material "functions" :face 'all-the-icons-red))
(ElispVariable . ,(all-the-icons-material "check_circle" :face 'all-the-icons-blue))
(ElispFeature . ,(all-the-icons-material "stars" :face 'all-the-icons-orange))
(ElispFace . ,(all-the-icons-material "format_paint" :face 'all-the-icons-pink)))))
(defun +company-box-icons--elisp-fn (candidate)
(when (derived-mode-p 'emacs-lisp-mode)
@ -118,7 +114,15 @@
(cond ((fboundp sym) 'ElispFunction)
((boundp sym) 'ElispVariable)
((featurep sym) 'ElispFeature)
((facep sym) 'ElispFace))))))
((facep sym) 'ElispFace)))))
(defadvice! +company-remove-scrollbar-a (orig-fn &rest args)
"This disables the company-box scrollbar, because:
https://github.com/sebastiencs/company-box/issues/44"
:around #'company-box--update-scrollbar
(cl-letf (((symbol-function #'display-buffer-in-side-window)
(symbol-function #'ignore)))
(apply orig-fn args))))
(use-package! company-dict

View file

@ -1,8 +1,8 @@
;; -*- no-byte-compile: t; -*-
;;; completion/company/packages.el
(package! company)
(package! company-dict)
(package! company-prescient)
(package! company :pin "9de9905ed2")
(package! company-dict :pin "cd7b8394f6")
(package! company-prescient :pin "7fd8c3b802")
(when (featurep! +childframe)
(package! company-box))
(package! company-box :pin "8fc6168f2d"))

View file

@ -38,7 +38,7 @@ workspace."
;;; Project search
;;;###autoload
(cl-defun +helm-file-search (&key query in all-files (recursive t))
(cl-defun +helm-file-search (&key query in all-files (recursive t) _prompt args)
"Conduct a file search using ripgrep.
:query STRING
@ -51,46 +51,21 @@ workspace."
(declare (indent defun))
(unless (executable-find "rg")
(user-error "Couldn't find ripgrep in your PATH"))
(require 'helm-ag)
(helm-ag--init-state)
(let* ((project-root (or (doom-project-root) default-directory))
(directory (or in project-root))
(default-directory directory)
(helm-ag--default-directory directory)
(helm-ag--default-target (list directory))
(query (or query
(when (use-region-p)
(let ((beg (or (bound-and-true-p evil-visual-beginning) (region-beginning)))
(end (or (bound-and-true-p evil-visual-end) (region-end))))
(when (> (abs (- end beg)) 1)
(rxt-quote-pcre (buffer-substring-no-properties beg end)))))
""))
(prompt (format "[rg %s] "
(cond ((file-equal-p directory project-root)
(projectile-project-name))
((file-equal-p directory default-directory)
"./")
((file-relative-name directory project-root)))))
(command
(list "rg --no-heading --line-number --color never"
"-S"
(when all-files "-z -uu")
(unless recursive "--maxdepth 1")))
(helm-ag-base-command (string-join (delq nil command) " ")))
;; TODO Define our own sources instead
(helm-attrset 'name (format "[rg %s] Searching %s"
(string-join (delq nil (cdr command)) " ")
(abbreviate-file-name directory))
helm-source-do-ag)
(helm-attrset '+helm-command command helm-source-do-ag)
(cl-letf (((symbol-function 'helm-do-ag--helm)
(lambda () (helm :sources '(helm-source-do-ag)
:prompt prompt
:buffer "*helm-rg*"
:keymap helm-do-ag-map
:input query
:history 'helm-ag--helm-history))))
(helm-do-ag directory))))
(require 'helm-rg)
(let ((this-command 'helm-rg)
(helm-rg-default-directory (or in (doom-project-root) default-directory))
(helm-rg-default-extra-args
(delq nil (append (list (when all-files "-z -uu")
(unless recursive "--maxdepth 1"))
args))))
(setq deactivate-mark t)
(helm-rg (or query
(when (use-region-p)
(let ((beg (or (bound-and-true-p evil-visual-beginning) (region-beginning)))
(end (or (bound-and-true-p evil-visual-end) (region-end))))
(when (> (abs (- end beg)) 1)
(buffer-substring-no-properties beg end))))
""))))
;;;###autoload
(defun +helm/project-search (&optional arg initial-query directory)

View file

@ -23,6 +23,7 @@ bottom, which is easier on the eyes on big displays."
(setq +helm--posframe-buffer buffer)
:position (point)
:poshandler +helm-posframe-handler
:respect-header-line helm-echo-input-in-header-line
:width
(max (cl-typecase .width
(integer .width)

View file

@ -57,8 +57,6 @@ be negative.")
helm-mode-line-string nil
helm-ff-auto-update-initial-value nil
helm-find-files-doc-header nil
;; Don't override evil-ex's completion
helm-mode-handle-completion-in-region nil
;; Default helm window sizes
helm-display-buffer-default-width nil
helm-display-buffer-default-height 0.25
@ -73,11 +71,13 @@ be negative.")
:init
(when (featurep! +childframe)
;; If this is set to 'iconify-top-level then Emacs will be minimized upon
;; helm completion.
(setq iconify-child-frame 'make-invisible)
(setq helm-display-function #'+helm-posframe-display-fn))
(let ((fuzzy (featurep! +fuzzy)))
(setq helm-M-x-fuzzy-match fuzzy
helm-ag-fuzzy-match fuzzy
helm-apropos-fuzzy-match fuzzy
helm-apropos-fuzzy-match fuzzy
helm-bookmark-show-location fuzzy
@ -101,9 +101,9 @@ be negative.")
;; HACK Doom doesn't support these commands, which invite the user to install
;; the package via ELPA. Force them to use +helm/* instead, because they work
;; out of the box.
(advice-add #'helm-projectile-rg :override #'+helm/rg)
(advice-add #'helm-projectile-ag :override #'+helm/ag)
(advice-add #'helm-projectile-grep :override #'+helm/grep)
(advice-add #'helm-projectile-rg :override #'+helm/project-search)
(advice-add #'helm-projectile-ag :override #'+helm/project-search)
(advice-add #'helm-projectile-grep :override #'+helm/project-search)
;; Hide the modeline
(defun +helm--hide-mode-line (&rest _)
@ -114,6 +114,9 @@ be negative.")
(advice-add #'helm-display-mode-line :override #'+helm--hide-mode-line)
(advice-add #'helm-ag-show-status-default-mode-line :override #'ignore)
;; Hide minibuffer if `helm-echo-input-in-header-line'
(add-hook 'helm-minibuffer-set-up-hook #'helm-hide-minibuffer-maybe)
;; Use helpful instead of describe-* to display documentation
(dolist (fn '(helm-describe-variable helm-describe-function))
(advice-add fn :around #'doom-use-helpful-a)))
@ -125,14 +128,16 @@ be negative.")
:config (helm-flx-mode +1))
(after! helm-ag
(map! :map helm-ag-edit-map :n "RET" #'compile-goto-error)
(define-key helm-ag-edit-map [remap quit-window] #'helm-ag--edit-abort)
(set-popup-rule! "^\\*helm-ag-edit" :size 0.35 :ttl 0 :quit nil)
;; Recenter after jumping to match
(advice-add #'helm-ag--find-file-action :after-while #'doom-recenter-a)
;; And record position before jumping
(advice-add #'helm-ag--find-file-action :around #'doom-set-jump-maybe-a))
(after! helm-rg
(setq helm-rg-display-buffer-normal-method #'pop-to-buffer)
(set-popup-rule! "^helm-rg-" :ttl nil :select t :size 0.45)
(map! :map helm-rg-map
"C-c C-e" #'helm-rg--bounce)
(map! :map helm-rg--bounce-mode-map
"q" #'kill-current-buffer
"C-c C-c" (λ! (helm-rg--bounce-dump) (kill-current-buffer))
"C-x C-c" #'helm-rg--bounce-dump-current-file
"C-c C-k" #'kill-current-buffer))
;;;###package helm-bookmark
@ -176,6 +181,7 @@ be negative.")
(set-keymap-parent helm-projectile-find-file-map helm-map))
(setq ivy-height 20) ; for `swiper-isearch'
(after! swiper-helm
(setq swiper-helm-display-function
(lambda (buf &optional _resume) (pop-to-buffer buf)))

View file

@ -1,16 +1,18 @@
;; -*- no-byte-compile: t; -*-
;;; completion/helm/packages.el
(package! helm)
(package! helm-ag)
(package! helm-c-yasnippet)
(package! helm-company)
(package! helm-describe-modes :recipe (:host github :repo "emacs-helm/helm-describe-modes"))
(package! helm-projectile)
(package! swiper-helm)
(package! helm :pin "8f56312053")
(package! helm-rg :pin "785a80fe5c")
(package! helm-c-yasnippet :pin "65ca732b51")
(package! helm-company :pin "6eb5c2d730")
(package! helm-describe-modes
:recipe (:host github :repo "emacs-helm/helm-describe-modes")
:pin "11fb36af11")
(package! helm-projectile :pin "5328b74ddd")
(package! swiper-helm :pin "93fb6db87b")
(when (featurep! +fuzzy)
(package! helm-flx))
(package! helm-flx :pin "6640fac5cb"))
(when (featurep! +childframe)
(package! posframe))
(package! posframe :pin "087a7fc3c8"))
(when (featurep! :lang org)
(package! helm-org))
(package! helm-org :pin "8457e1e462"))

View file

@ -1,7 +1,7 @@
;; -*- no-byte-compile: t; -*-
;;; completion/ido/packages.el
(package! flx-ido)
(package! ido-completing-read+)
(package! ido-vertical-mode)
(package! crm-custom)
(package! flx-ido :pin "17f5c9cb2a")
(package! ido-completing-read+ :pin "74861eabd0")
(package! ido-vertical-mode :pin "16c4c1a112")
(package! crm-custom :pin "f1aaccf643")

View file

@ -14,7 +14,7 @@
- [[#arch-linux][Arch Linux]]
- [[#opensuse][openSUSE]]
- [[#features][Features]]
- [[#jump-to-file-project-navigation][Jump-to-file project navigation]]
- [[#jump-to-navigation][Jump-to navigation]]
- [[#project-search--replace][Project search & replace]]
- [[#in-buffer-searching][In-buffer searching]]
- [[#ivy-integration-for-various-completing-commands][Ivy integration for various completing commands]]
@ -88,7 +88,7 @@ sudo zypper install ripgrep
Ivy and its ilk are large plugins. Covering everything about them is outside of
this documentation's scope, so only Doom-specific Ivy features are listed here:
** Jump-to-file project navigation
** Jump-to navigation
Inspired by Sublime Text's jump-to-anywhere, CtrlP/Unite in Vim, and Textmate's
Command-T, this module provides similar functionality by bringing ~projectile~
and ~ivy~ together.
@ -99,22 +99,23 @@ https://assets.doomemacs.org/completion/ivy/projectile.png
|----------------------+-------------------------------------|
| =SPC p f=, =SPC SPC= | Jump to file in project |
| =SPC f f=, =SPC .= | Jump to file from current directory |
| =SPC s i= | Jump to symbol in file |
** Project search & replace
This module provides interactive text search and replace using ripgrep.
| Keybind | Description |
|-----------+---------------------------------|
| =SPC s b= | Search the current buffer |
| =SPC s p= | Search project |
| =SPC s d= | Search this directory |
| =SPC p t= | List all TODO/FIXMEs in project |
| Keybind | Description |
|-----------+--------------------------|
| =SPC s p= | Search project |
| =SPC s P= | Search another project |
| =SPC s d= | Search this directory |
| =SPC s D= | Search another directory |
https://assets.doomemacs.org/completion/ivy/search.png
The universal argument (=SPC u= for evil users; =C-u= otherwise) changes the
behavior of these commands, instructing the underlying search engine to include
ignored files.
Prefixing these keys with the universal argument (=SPC u= for evil users; =C-u=
otherwise) changes the behavior of these commands, instructing the underlying
search engine to include ignored files.
This module also provides Ex Commands for evil users:
@ -123,15 +124,16 @@ This module also provides Ex Commands for evil users:
| ~:pg[rep][!] [QUERY]~ | Search project (if ~!~, include hidden files) |
| ~:pg[rep]d[!] [QUERY]~ | Search from current directory (if ~!~, don't search recursively) |
The optional BANG functions is equivalent to the universal argument for the
previous commands.
The optional `!` is equivalent to the universal argument for the previous
commands.
-----
While in a search these extra keybindings are available to you:
These keybindings are available while a search is active:
| Keybind | Description |
|-----------+-----------------------------------------------|
| =C-c C-o= | Open a buffer with your search results |
| =C-c C-e= | Open a writable buffer of your search results |
| =C-SPC= | Preview the current candidate |
| =M-RET= | Open the selected candidate in other-window |
@ -146,8 +148,9 @@ https://assets.doomemacs.org/completion/ivy/search-replace.png
The =swiper= package provides an interactive buffer search powered by ivy. It
can be invoked with:
+ =SPC s s=
+ =SPC s S= (uses thing at point as initial input)
+ =SPC s s= (~swiper-isearch~)
+ =SPC s S= (~swiper-isearch-thing-at-point~)
+ =SPC s b= (~swiper~)
+ ~:sw[iper] [QUERY]~
https://assets.doomemacs.org/completion/ivy/swiper.png

View file

@ -21,16 +21,7 @@ Buffers that are considered unreal (see `doom-real-buffer-p') are dimmed with
`+ivy-buffer-unreal-face'."
(let ((b (get-buffer candidate)))
(when (null uniquify-buffer-name-style)
(when-let* ((file-path (buffer-file-name b))
(uniquify-buffer-name-style 'forward))
(setq candidate
(uniquify-get-proposed-name
(replace-regexp-in-string "<[0-9]+>$" "" (buffer-name b))
(directory-file-name
(if file-path
(file-name-directory file-path)
default-directory))
1))))
(setq candidate (replace-regexp-in-string "<[0-9]+>$" "" candidate)))
(cond ((ignore-errors
(file-remote-p
(buffer-local-value 'default-directory b)))
@ -165,10 +156,10 @@ If ARG (universal argument), open selection in other-window."
(user-error "No completion session is active"))
(require 'wgrep)
(let ((caller (ivy-state-caller ivy-last)))
(if-let* ((occur-fn (plist-get +ivy-edit-functions caller)))
(if-let (occur-fn (plist-get +ivy-edit-functions caller))
(ivy-exit-with-action
(lambda (_) (funcall occur-fn)))
(if-let* ((occur-fn (plist-get ivy--occurs-list caller)))
(if-let (occur-fn (plist-get ivy--occurs-list caller))
(let ((buffer (generate-new-buffer
(format "*ivy-occur%s \"%s\"*"
(if caller (concat " " (prin1-to-string caller)) "")
@ -222,22 +213,26 @@ non-project, `projectile-find-file' if in a big project (more than
The point of this is to avoid Emacs locking up indexing massive file trees."
(interactive)
(call-interactively
(cond ((or (file-equal-p default-directory "~")
(when-let (proot (doom-project-root))
(file-equal-p proot "~")))
#'counsel-find-file)
;; Spoof the command so that ivy/counsel will display the (well fleshed-out)
;; actions list for `counsel-find-file' on C-o. The actions list for the other
;; commands aren't as well configured or are empty.
(let ((this-command 'counsel-find-file))
(call-interactively
(cond ((or (file-equal-p default-directory "~")
(when-let (proot (doom-project-root))
(file-equal-p proot "~")))
#'counsel-find-file)
((doom-project-p)
(let ((files (projectile-current-project-files)))
(if (<= (length files) ivy-sort-max-size)
#'counsel-projectile-find-file
#'projectile-find-file)))
((doom-project-p)
(let ((files (projectile-current-project-files)))
(if (<= (length files) ivy-sort-max-size)
#'counsel-projectile-find-file
#'projectile-find-file)))
(#'counsel-file-jump))))
(#'counsel-file-jump)))))
;;;###autoload
(cl-defun +ivy-file-search (&key query in all-files (recursive t))
(cl-defun +ivy-file-search (&key query in all-files (recursive t) prompt args)
"Conduct a file search using ripgrep.
:query STRING
@ -251,36 +246,35 @@ The point of this is to avoid Emacs locking up indexing massive file trees."
(unless (executable-find "rg")
(user-error "Couldn't find ripgrep in your PATH"))
(require 'counsel)
(let* ((ivy-more-chars-alist '((t . 1)))
(let* ((this-command 'counsel-rg)
(project-root (or (doom-project-root) default-directory))
(directory (or in project-root))
(default-directory directory)
(args (concat (if all-files " -uu")
(unless recursive " --maxdepth 1"))))
(unless recursive " --maxdepth 1")
" "
(mapconcat #'shell-quote-argument args " "))))
(setq deactivate-mark t)
(counsel-rg
(or (if query query)
(when (use-region-p)
(let ((beg (or (bound-and-true-p evil-visual-beginning) (region-beginning)))
(end (or (bound-and-true-p evil-visual-end) (region-end))))
(when (> (abs (- end beg)) 1)
(let ((query (buffer-substring-no-properties beg end)))
;; Escape characters that are special to ivy searches
(replace-regexp-in-string "[! |]" (lambda (substr)
(cond ((and (string= substr " ")
(not (featurep! +fuzzy)))
" ")
((string= substr "|")
"\\\\\\\\|")
((concat "\\\\" substr))))
(rxt-quote-pcre query)))))))
(or query
(when (doom-region-active-p)
(replace-regexp-in-string
"[! |]" (lambda (substr)
(cond ((and (string= substr " ")
(not (featurep! +fuzzy)))
" ")
((string= substr "|")
"\\\\\\\\|")
((concat "\\\\" substr))))
(rxt-quote-pcre (doom-thing-at-point-or-region)))))
directory args
(format "rg%s %s"
args
(cond ((equal directory default-directory)
"./")
((equal directory project-root)
(projectile-project-name))
((file-relative-name directory project-root)))))))
(or prompt
(format "rg%s [%s]: "
args
(cond ((equal directory default-directory)
"./")
((equal directory project-root)
(projectile-project-name))
((file-relative-name directory project-root))))))))
;;;###autoload
(defun +ivy/project-search (&optional arg initial-query directory)

View file

@ -7,16 +7,6 @@ When nil, don't preview anything.
When non-nil, preview non-virtual buffers.
When 'everything, also preview virtual buffers")
(defvar +ivy-project-search-engines '(rg ag)
"What search tools for `+ivy/project-search' (and `+ivy-file-search' when no
ENGINE is specified) to try, and in what order.
To disable a particular tool, remove it from this list. To prioritize a tool
over others, move it to the front of the list. Later duplicates in this list are
silently ignored.
If you want to already use git-grep or grep, set this to nil.")
(defvar +ivy-buffer-unreal-face 'font-lock-comment-face
"The face for unreal buffers in `ivy-switch-to-buffer'.")
@ -24,18 +14,6 @@ If you want to already use git-grep or grep, set this to nil.")
"A plist mapping ivy/counsel commands to commands that generate an editable
results buffer.")
(defvar +ivy-standard-search-fn
(if (featurep! +prescient)
#'+ivy-prescient-non-fuzzy
#'ivy--regex-plus)
"Function to use for non-fuzzy search commands.")
(defvar +ivy-alternative-search-fn
(cond ((featurep! +prescient) #'ivy-prescient-re-builder)
((featurep! +fuzzy) #'ivy--regex-fuzzy)
(#'ivy--regex-ignore-order))
"Function to use for fuzzy search commands.")
;;
;;; Packages
@ -43,15 +21,24 @@ results buffer.")
(use-package! ivy
:after-call pre-command-hook
:init
(setq ivy-re-builders-alist
`(,@(cl-loop for cmd in '(counsel-ag
counsel-rg
counsel-grep
swiper
swiper-isearch)
collect (cons cmd +ivy-standard-search-fn))
;; Ignore order for non-fuzzy searches by default
(t . ,+ivy-alternative-search-fn)))
(let ((standard-search-fn
(if (featurep! +prescient)
#'+ivy-prescient-non-fuzzy
#'ivy--regex-plus))
(alt-search-fn
(if (featurep! +fuzzy)
#'ivy--regex-fuzzy
;; Ignore order for non-fuzzy searches by default
#'ivy--regex-ignore-order)))
(setq ivy-re-builders-alist
`((counsel-rg . ,standard-search-fn)
(swiper . ,standard-search-fn)
(swiper-isearch . ,standard-search-fn)
(t . ,alt-search-fn))
ivy-more-chars-alist
'((counsel-rg . 1)
(counsel-search . 2)
(t . 3))))
(define-key!
[remap switch-to-buffer] #'+ivy/switch-buffer
@ -75,7 +62,7 @@ results buffer.")
;; ...but if that ever changes, show their full path
ivy-virtual-abbreviate 'full
;; don't quit minibuffer on delete-error
ivy-on-del-error-function nil
ivy-on-del-error-function #'ignore
;; enable ability to select prompt (alternative to `ivy-immediate-done')
ivy-use-selectable-prompt t)
@ -110,7 +97,9 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
(let ((completion-in-region-function #'completion--in-region))
(apply orig-fn args)))
(define-key ivy-minibuffer-map (kbd "C-c C-e") #'+ivy/woccur)
(define-key! ivy-minibuffer-map
"C-c C-e" #'+ivy/woccur
[remap doom/delete-backward-word] #'ivy-backward-kill-word)
(ivy-mode +1)
@ -128,6 +117,8 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
(use-package! ivy-rich
:after ivy
:config
(setq ivy-rich-parse-remote-buffer nil)
(when (featurep! +icons)
(cl-pushnew '(+ivy-rich-buffer-icon)
(cadr (plist-get ivy-rich-display-transformers-list
@ -182,61 +173,52 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
(define-key!
[remap apropos] #'counsel-apropos
[remap bookmark-jump] #'counsel-bookmark
[remap compile] #'+ivy/compile
[remap describe-bindings] #'counsel-descbinds
[remap describe-face] #'counsel-faces
[remap describe-function] #'counsel-describe-function
[remap describe-variable] #'counsel-describe-variable
[remap describe-bindings] #'counsel-descbinds
[remap set-variable] #'counsel-set-variable
[remap evil-ex-registers] #'counsel-evil-registers
[remap evil-show-marks] #'counsel-mark-ring
[remap execute-extended-command] #'counsel-M-x
[remap find-file] #'counsel-find-file
[remap find-library] #'counsel-find-library
[remap info-lookup-symbol] #'counsel-info-lookup-symbol
[remap imenu] #'counsel-imenu
[remap recentf-open-files] #'counsel-recentf
[remap swiper] #'counsel-grep-or-swiper
[remap evil-ex-registers] #'counsel-evil-registers
[remap evil-show-marks] #'counsel-mark-ring
[remap yank-pop] #'counsel-yank-pop
[remap info-lookup-symbol] #'counsel-info-lookup-symbol
[remap load-theme] #'counsel-load-theme
[remap locate] #'counsel-locate
[remap org-set-tags-command] #'counsel-org-tag
[remap projectile-compile-project] #'+ivy/project-compile
[remap recentf-open-files] #'counsel-recentf
[remap set-variable] #'counsel-set-variable
[remap swiper] #'counsel-grep-or-swiper
[remap unicode-chars-list-chars] #'counsel-unicode-char
[remap compile] #'+ivy/compile
[remap projectile-compile-project] #'+ivy/project-compile)
[remap yank-pop] #'counsel-yank-pop)
:config
(set-popup-rule! "^\\*ivy-occur" :size 0.35 :ttl 0 :quit nil)
;; HACK Fix an issue where `counsel-projectile-find-file-action' would try to
;; open a candidate in an occur buffer relative to the wrong buffer,
;; causing it to fail to find the file we want.
(defadvice! +ivy--run-from-ivy-directory-a (orig-fn &rest args)
:around #'counsel-projectile-find-file-action
(let ((default-directory (ivy-state-directory ivy-last)))
(apply orig-fn args)))
;; Don't use ^ as initial input. Set this here because `counsel' defines more
;; of its own, on top of the defaults.
(setq ivy-initial-inputs-alist nil)
;; REVIEW Move this somewhere else and perhaps generalize this so both
;; ivy/helm users can enjoy it.
(defadvice! +ivy--counsel-file-jump-use-fd-rg-a (args)
"Change `counsel-file-jump' to use fd or ripgrep, if they are available."
:override #'counsel--find-return-list
(cl-destructuring-bind (find-program . args)
(cond ((executable-find "fd")
(cons "fd" (list "-t" "f" "-E" ".git")))
((executable-find "rg")
(cons "rg" (list "--files" "--hidden" "--no-messages")))
((cons find-program args)))
(unless (listp args)
(user-error "`counsel-file-jump-args' is a list now, please customize accordingly."))
(counsel--call
(cons find-program args)
(lambda ()
(goto-char (point-min))
(let ((offset (if (member find-program '("fd" "rg")) 0 2))
files)
(while (< (point) (point-max))
(push (buffer-substring
(+ offset (line-beginning-position)) (line-end-position)) files)
(forward-line 1))
(nreverse files))))))
;; Integrate with `helpful'
(setq counsel-describe-function-function #'helpful-callable
counsel-describe-variable-function #'helpful-variable)
;; Record in jumplist when opening files via counsel-{ag,rg,pt,git-grep}
(add-hook 'counsel-grep-post-action-hook #'better-jumper-set-jump)
(ivy-add-actions
'counsel-rg ; also applies to `counsel-rg'
'(("O" +ivy-git-grep-other-window-action "open in other window")))
;; Make `counsel-compile' projectile-aware (if you prefer it over
;; `+ivy/compile' and `+ivy/project-compile')
(add-to-list 'counsel-compile-root-functions #'projectile-project-root)
@ -244,51 +226,62 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
;; Persist `counsel-compile' history
(add-to-list 'savehist-additional-variables 'counsel-compile-history))
;; Use spotlight on mac for `counsel-locate' by default
;; `counsel-imenu' -- no sorting for imenu. Sort it by appearance in page.
(add-to-list 'ivy-sort-functions-alist '(counsel-imenu))
;; `counsel-locate'
(when IS-MAC
;; Use spotlight on mac by default since it doesn't need any additional setup
(setq counsel-locate-cmd #'counsel-locate-cmd-mdfind))
;; `swiper'
;; Don't mess with font-locking on the dashboard; it causes breakages
(add-to-list 'swiper-font-lock-exclude #'+doom-dashboard-mode)
;; Record in jumplist when opening files via counsel-{ag,rg,pt,git-grep}
(add-hook 'counsel-grep-post-action-hook #'better-jumper-set-jump)
;; Factories
(defun +ivy-action-reloading (cmd)
(lambda (x)
(funcall cmd x)
(ivy--reset-state ivy-last)))
(defun +ivy-action-given-file (cmd prompt)
(lambda (source)
(let* ((enable-recursive-minibuffers t)
(target (read-file-name (format "%s %s to:" prompt source))))
(funcall cmd source target 1))))
;; Configure `counsel-find-file'
;; `counsel-find-file'
(setq counsel-find-file-ignore-regexp "\\(?:^[#.]\\)\\|\\(?:[#~]$\\)\\|\\(?:^Icon?\\)")
(ivy-add-actions
'counsel-find-file
`(("b" counsel-find-file-cd-bookmark-action "cd bookmark")
("s" counsel-find-file-as-root "open as root")
("m" counsel-find-file-mkdir-action "mkdir")
("c" ,(+ivy-action-given-file #'copy-file "Copy file") "copy file")
("d" ,(+ivy-action-reloading #'+ivy-confirm-delete-file) "delete")
("r" (lambda (path) (rename-file path (read-string "New name: "))) "rename")
("R" ,(+ivy-action-reloading (+ivy-action-given-file #'rename-file "Move")) "move")
("f" find-file-other-window "other window")
("F" find-file-other-frame "other frame")
("p" (lambda (path) (with-ivy-window (insert (file-relative-name path default-directory)))) "insert relative path")
("P" (lambda (path) (with-ivy-window (insert path))) "insert absolute path")
("l" (lambda (path) "Insert org-link with relative path"
(with-ivy-window (insert (format "[[./%s]]" (file-relative-name path default-directory))))) "insert org-link (rel. path)")
("L" (lambda (path) "Insert org-link with absolute path"
(with-ivy-window (insert (format "[[%s]]" path)))) "insert org-link (abs. path)")))
(dolist (fn '(counsel-rg counsel-find-file))
(ivy-add-actions
fn '(("p" (lambda (path) (with-ivy-window (insert (file-relative-name path default-directory))))
"insert relative path")
("P" (lambda (path) (with-ivy-window (insert path)))
"insert absolute path")
("l" (lambda (path) (with-ivy-window (insert (format "[[./%s]]" (file-relative-name path default-directory)))))
"insert relative org-link")
("L" (lambda (path) (with-ivy-window (insert (format "[[%s]]" path))))
"Insert absolute org-link"))))
(ivy-add-actions
'counsel-ag ; also applies to `counsel-rg'
'(("O" +ivy-git-grep-other-window-action "open in other window"))))
(ivy-add-actions 'counsel-file-jump (plist-get ivy--actions-list 'counsel-find-file))
;; `counsel-search': use normal page for displaying results, so that we see
;; custom ddg themes (if one is set).
(setf (nth 1 (alist-get 'ddg counsel-search-engines-alist))
"https://duckduckgo.com/?q=")
;; REVIEW Move this somewhere else and perhaps generalize this so both
;; ivy/helm users can enjoy it.
(defadvice! +ivy--counsel-file-jump-use-fd-rg-a (args)
"Change `counsel-file-jump' to use fd or ripgrep, if they are available."
:override #'counsel--find-return-list
(cl-destructuring-bind (find-program . args)
(cond ((executable-find doom-projectile-fd-binary)
(cons doom-projectile-fd-binary (list "-t" "f" "-E" ".git")))
((executable-find "rg")
(split-string (format counsel-rg-base-command "--files --no-messages") " " t))
((cons find-program args)))
(unless (listp args)
(user-error "`counsel-file-jump-args' is a list now, please customize accordingly."))
(counsel--call
(cons find-program args)
(lambda ()
(goto-char (point-min))
(let ((offset (if (member find-program (list "rg" doom-projectile-fd-binary)) 0 2))
files)
(while (< (point) (point-max))
(push (buffer-substring
(+ offset (line-beginning-position)) (line-end-position)) files)
(forward-line 1))
(nreverse files)))))))
(use-package! counsel-projectile
@ -310,7 +303,10 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
#'+ivy/projectile-find-file)
;; no highlighting visited files; slows down the filtering
(ivy-set-display-transformer #'counsel-projectile-find-file nil))
(ivy-set-display-transformer #'counsel-projectile-find-file nil)
(if (featurep! +prescient)
(setq counsel-projectile-sort-files t)))
(use-package! wgrep
@ -332,8 +328,10 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
(setf (alist-get t ivy-posframe-display-functions-alist)
#'+ivy-display-at-frame-center-near-bottom-fn)
;; posframe doesn't work well with async sources
(dolist (fn '(swiper counsel-ag counsel-grep counsel-git-grep))
;; posframe doesn't work well with async sources (the posframe will
;; occasionally stop responding/redrawing), and causes violent resizing of the
;; posframe.
(dolist (fn '(swiper counsel-rg counsel-grep counsel-git-grep))
(setf (alist-get fn ivy-posframe-display-functions-alist)
#'ivy-display-function-fallback)))
@ -353,7 +351,6 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
(if (featurep! +fuzzy)
'(literal regexp initialism fuzzy)
'(literal regexp initialism))
ivy-prescient-enable-filtering nil ; we do this ourselves
ivy-prescient-retain-classic-highlighting t)
:config

View file

@ -1,22 +1,23 @@
;; -*- no-byte-compile: t; -*-
;;; completion/ivy/packages.el
(package! amx)
(package! swiper :pin "7084d60312")
(package! ivy)
(package! counsel)
(package! counsel-projectile)
(package! swiper)
(package! ivy-hydra)
(package! ivy-rich)
(package! wgrep)
(package! counsel)
(package! amx :pin "e512e74e83")
(package! counsel-projectile :pin "b556ed8995")
(package! ivy-rich :pin "af43abad5c")
(package! wgrep :pin "5977b8e000")
(if (featurep! +prescient)
(package! ivy-prescient)
(package! ivy-prescient :pin "7fd8c3b802")
(when (featurep! +fuzzy)
(package! flx)))
(package! flx :pin "17f5c9cb2a")))
(when (featurep! +childframe)
(package! ivy-posframe))
(package! ivy-posframe :pin "6d697ff00a"))
(when (featurep! +icons)
(package! all-the-icons-ivy))
(package! all-the-icons-ivy :pin "a70cbfa1ef"))

View file

@ -25,28 +25,80 @@
(:prefix ("l" . "<localleader>")) ; bound locally
(:prefix ("!" . "checkers")) ; bound by flycheck
;;; <leader> c --- code
(:prefix-map ("c" . "code")
:desc "Compile" "c" #'compile
:desc "Recompile" "C" #'recompile
:desc "Jump to definition" "d" #'+lookup/definition
:desc "Jump to references" "D" #'+lookup/references
:desc "Evaluate buffer/region" "e" #'+eval/buffer-or-region
:desc "Evaluate & replace region" "E" #'+eval/region-and-replace
:desc "Format buffer/region" "f" #'+format/region-or-buffer
:desc "Jump to documentation" "k" #'+lookup/documentation
:desc "Send to repl" "s" #'+eval/send-region-to-repl
:desc "Delete trailing whitespace" "w" #'delete-trailing-whitespace
:desc "Delete trailing newlines" "W" #'doom/delete-trailing-newlines
:desc "List errors" "x" #'flymake-show-diagnostics-buffer
(:when (featurep! :tools flycheck)
:desc "List errors" "x" #'flycheck-list-errors)
(:when (featurep! :tools lsp)
:desc "LSP Code actions" "a" #'lsp-execute-code-action
:desc "LSP Format buffer/region" "F" #'+default/lsp-format-region-or-buffer
:desc "LSP Organize imports" "i" #'lsp-organize-imports
:desc "LSP Rename" "r" #'lsp-rename
(:when (featurep! :completion ivy)
:desc "Jump to symbol in current workspace" "j" #'lsp-ivy-workspace-symbol
:desc "Jump to symbol in any workspace" "J" #'lsp-ivy-global-workspace-symbol)
(:when (featurep! :completion helm)
:desc "Jump to symbol in current workspace" "j" #'helm-lsp-workspace-symbol
:desc "Jump to symbol in any workspace" "J" #'helm-lsp-global-workspace-symbol)))
;;; <leader> f --- file
(:prefix-map ("f" . "file")
:desc "Open project editorconfig" "." #'editorconfig-find-current-editorconfig
:desc "Find other file" "a" #'projectile-find-other-file
:desc "Browse private config" "c" #'doom/open-private-config
:desc "Copy this file" "C" #'doom/copy-this-file
:desc "Find file in private config" "C" #'doom/find-file-in-private-config
:desc "Find directory" "d" #'dired
:desc "Delete this file" "D" #'doom/delete-this-file
:desc "Find file in emacs.d" "e" #'+default/find-in-emacsd
:desc "Browse emacs.d" "E" #'+default/browse-emacsd
:desc "Find file from here" "f" (if (fboundp 'counsel-file-jump) #'counsel-file-jump #'find-file)
:desc "Find file in other project" "F" #'doom/browse-in-other-project
:desc "Delete this file" "K" #'doom/delete-this-file
:desc "Move this file" "m" #'doom/move-this-file
:desc "Find file in project" "p" #'projectile-find-file
:desc "Find file in other project" "P" #'doom/find-file-in-other-project
:desc "Find file from here" "f" #'+default/find-file-under-here
:desc "Rename/move this file" "m" #'doom/move-this-file
:desc "Browse private config" "p" #'doom/open-private-config
:desc "Browse private config" "P" #'doom/open-private-config
:desc "Recent files" "r" #'recentf-open-files
:desc "Recent project files" "R" #'projectile-recentf
:desc "Sudo this file" "s" #'doom/sudo-this-file
:desc "Sudo find file" "S" #'doom/sudo-find-file
:desc "Yank filename" "y" #'+default/yank-buffer-filename
:desc "Open scratch buffer" "x" #'doom/open-scratch-buffer
:desc "Open project scratch buffer" "X" #'doom/switch-to-scratch-buffer)
:desc "Switch to scratch buffer" "X" #'doom/switch-to-scratch-buffer
(:when (featurep! :tools editorconfig)
:desc "Open project editorconfig" "." #'editorconfig-find-current-editorconfig))
;;; <leader> r --- remote
(:when (featurep! :tools upload)
(:prefix-map ("r" . "remote")
:desc "Upload local" "u" #'ssh-deploy-upload-handler
:desc "Upload local (force)" "U" #'ssh-deploy-upload-handler-forced
:desc "Download remote" "d" #'ssh-deploy-download-handler
:desc "Diff local & remote" "D" #'ssh-deploy-diff-handler
:desc "Browse remote files" "." #'ssh-deploy-browse-remote-handler
:desc "Detect remote changes" ">" #'ssh-deploy-remote-changes-handler))
;;; <leader> s --- search
(:prefix-map ("s" . "search")
:desc "Search buffer" "b" #'swiper
:desc "Search current directory" "d" #'+default/search-cwd
:desc "Search other directory" "D" #'+default/search-other-cwd
:desc "Locate file" "f" #'locate
:desc "Jump to symbol" "i" #'imenu
:desc "Jump to visible link" "l" #'link-hint-open-link
:desc "Jump to link" "L" #'ffap-menu
:desc "Jump list" "j" #'evil-show-jumps
:desc "Jump to mark" "m" #'evil-show-marks
:desc "Search project" "p" #'+default/search-project
:desc "Search other project" "P" #'+default/search-other-project
:desc "Search buffer" "s" #'swiper-isearch
:desc "Search buffer for thing at point" "S" #'swiper-isearch-thing-at-point)
;;; <leader> g --- lookup
(:when (featurep! :tools lookup)
@ -59,24 +111,72 @@
"i" #'+lookup/in-docsets
"I" #'+lookup/in-all-docsets))
;;; <leader> o --- org
"o" nil ; we need to unbind it first as Org claims this
(:prefix-map ("o". "org")
:desc "Do what I mean" "o" #'+org/dwim-at-point
:desc "Display inline images" "i" #'org-display-inline-images
:desc "Search notes for symbol" "." #'+default/search-notes-for-symbol-at-point
(:prefix ("a" . "org agenda")
:desc "Agenda" "a" #'org-agenda
:desc "Todo list" "t" #'org-todo-list
:desc "Tags view" "m" #'org-tags-view
:desc "View search" "v" #'org-search-view)
:desc "Browse notes" "f" #'+default/browse-notes
:desc "Search org-directory" "s" #'+default/org-notes-search
:desc "Switch org buffers" "b" #'org-switchb
:desc "Capture" "c" #'org-capture
:desc "Goto capture" "C" #'org-capture-goto-target
:desc "Link store" "l" #'org-store-link
:desc "Sync org caldav" "S" #'org-caldav-sync)
;;; <leader> i --- insert
(:prefix-map ("i" . "insert")
:desc "Current file name" "f" #'+default/insert-file-path
:desc "Current file path" "F" (λ!! #'+default/insert-file-path t)
:desc "Snippet" "s" #'yas-insert-snippet
:desc "Unicode" "u" #'unicode-chars-list-chars
:desc "From clipboard" "y" #'+default/yank-pop)
;;; <leader> n --- notes
(:prefix-map ("n" . "notes")
:desc "Search notes for symbol" "." #'+default/search-notes-for-symbol-at-point
:desc "Org agenda" "a" #'org-agenda
:desc "Find file in notes" "f" #'+default/find-in-notes
:desc "Browse notes" "F" #'+default/browse-notes
:desc "Org store link" "l" #'org-store-link
:desc "Tags search" "m" #'org-tags-view
:desc "Org capture" "n" #'org-capture
:desc "Goto capture" "N" #'org-capture-goto-target
:desc "Active org-clock" "o" #'org-clock-goto
:desc "Todo list" "t" #'org-todo-list
:desc "Search notes" "s" #'+default/org-notes-search
:desc "Search org agenda headlines" "S" #'+default/org-notes-headlines
:desc "View search" "v" #'org-search-view
:desc "Org export to clipboard" "y" #'+org/export-to-clipboard
:desc "Org export to clipboard as RTF" "Y" #'+org/export-to-clipboard-as-rich-text
(:when (featurep! :lang org +journal)
(:prefix ("j" . "journal")
:desc "New Entry" "j" #'org-journal-new-entry
:desc "Search Forever" "s" #'org-journal-search-forever)))
;;; <leader> o --- open
"o" nil ; we need to unbind it first as Org claims this prefix
(:prefix-map ("o" . "open")
:desc "Browser" "b" #'browse-url-of-file
:desc "Debugger" "d" #'+debugger/start
:desc "New frame" "f" #'make-frame
:desc "REPL" "r" #'+eval/open-repl-other-window
:desc "REPL (same window)" "R" #'+eval/open-repl-same-window
:desc "Dired" "-" #'dired-jump
(:when (featurep! :ui neotree)
:desc "Project sidebar" "p" #'+neotree/open
:desc "Find file in project sidebar" "P" #'+neotree/find-this-file)
(:when (featurep! :ui treemacs)
:desc "Project sidebar" "p" #'+treemacs/toggle
:desc "Find file in project rsidebar" "P" #'+treemacs/find-file)
(:when (featurep! :term shell)
:desc "Toggle shell popup" "t" #'+shell/toggle
:desc "Open shell here" "T" #'+shell/here)
(:when (featurep! :term term)
:desc "Toggle terminal popup" "t" #'+term/toggle
:desc "Open terminal here" "T" #'+term/here)
(:when (featurep! :term vterm)
:desc "Toggle vterm popup" "t" #'+vterm/toggle
:desc "Open vterm here" "T" #'+vterm/here)
(:when (featurep! :term eshell)
:desc "Toggle eshell popup" "e" #'+eshell/toggle
:desc "Open eshell here" "E" #'+eshell/here)
(:when (featurep! :tools macos)
:desc "Reveal in Finder" "o" #'+macos/reveal-in-finder
:desc "Reveal project in Finder" "O" #'+macos/reveal-project-in-finder
:desc "Send to Transmit" "u" #'+macos/send-to-transmit
:desc "Send project to Transmit" "U" #'+macos/send-project-to-transmit
:desc "Send to Launchbar" "l" #'+macos/send-to-launchbar
:desc "Send project to Launchbar" "L" #'+macos/send-project-to-launchbar)
(:when (featurep! :tools docker)
:desc "Docker" "D" #'docker))
;;; <leader> p --- project
(:prefix ("p" . "project")
@ -91,10 +191,16 @@
;;; <leader> q --- quit/restart
(:prefix-map ("q" . "quit/restart")
:desc "Restart emacs server" "d" #'+default/restart-server
:desc "Delete frame" "f" #'delete-frame
:desc "Clear current frame" "F" #'doom/kill-all-buffers
:desc "Kill Emacs (and daemon)" "K" #'save-buffers-kill-emacs
:desc "Quit Emacs" "q" #'kill-emacs
:desc "Save and quit Emacs" "Q" #'save-buffers-kill-terminal
(:when (featurep! :ui workspaces)
:desc "Quit Emacs & forget session" "X" #'+workspace/kill-session-and-quit)
:desc "Quick save current session" "s" #'doom/quicksave-session
:desc "Restore last session" "l" #'doom/quickload-session
:desc "Save session to file" "S" #'doom/save-session
:desc "Restore session from file" "L" #'doom/load-session
:desc "Restart & restore Emacs" "r" #'doom/restart-and-restore
:desc "Restart Emacs" "R" #'doom/restart)
@ -107,20 +213,33 @@
:desc "Create Temp Template" "c" #'aya-create
:desc "Use Temp Template" "e" #'aya-expand)
(:prefix-map ("t" . "terminal")
(:when (featurep! :term term)
:desc "Toggle term popup" "t" #'+term/toggle
:desc "Open term here" "T" #'+term/here)
(:when (featurep! :term vterm)
:desc "Toggle vterm popup" "t" #'+vterm/toggle
:desc "Open vterm here" "T" #'+vterm/here)
(:when (featurep! :term eshell)
:desc "Toggle eshell popup" "t" #'+eshell/toggle
:desc "Open eshell here" "T" #'+eshell/here))
;;; <leader> t --- toggle
(:prefix-map ("t" . "toggle")
:desc "Big mode" "b" #'doom-big-font-mode
:desc "Flymake" "f" #'flymake-mode
:desc "Frame fullscreen" "F" #'toggle-frame-fullscreen
:desc "Indent style" "I" #'doom/toggle-indent-style
:desc "Line numbers" "l" #'doom/toggle-line-numbers
:desc "Word-wrap mode" "w" #'+word-wrap-mode
(:when (featurep! :tools flycheck)
:desc "Flycheck" "f" #'flycheck-mode)
(:when (featurep! :ui indent-guides)
:desc "Indent guides" "i" #'highlight-indent-guides-mode)
(:when (featurep! :lang org +present)
:desc "org-tree-slide mode" "p" #'+org-present/start)
:desc "Read-only mode" "r" #'read-only-mode
(:when (featurep! :tools flyspell)
:desc "Flyspell" "s" #'flyspell-mode)
(:when (featurep! :lang org +pomodoro)
:desc "Pomodoro timer" "t" #'org-pomodoro)
(:when (featurep! :ui zen)
:desc "Zen mode" "z" #'writeroom-mode))
;;; <leader> v --- versioning
(:prefix-map ("v" . "versioning")
:desc "Git revert file" "R" #'vc-revert
:desc "Kill link to remote" "y" #'+vc/browse-at-remote-kill-file-or-region
:desc "Kill link to homepage" "Y" #'+vc/browse-at-remote-kill-homepage
(:when (featurep! :ui vc-gutter)
:desc "Git revert hunk" "r" #'git-gutter:revert-hunk
:desc "Git stage hunk" "s" #'git-gutter:stage-hunk
@ -133,7 +252,7 @@
:desc "Magit status" "g" #'magit-status
:desc "Magit file delete" "x" #'magit-file-delete
:desc "Magit blame" "B" #'magit-blame-addition
:desc "Magit clone" "C" #'+magit/clone
:desc "Magit clone" "C" #'magit-clone
:desc "Magit fetch" "F" #'magit-fetch
:desc "Magit buffer log" "L" #'magit-log
:desc "Git stage file" "S" #'magit-stage-file
@ -145,7 +264,8 @@
:desc "Find issue" "i" #'forge-visit-issue
:desc "Find pull request" "p" #'forge-visit-pullreq)
(:prefix ("o" . "open in browser")
:desc "Browse region or line" "." #'+vc/git-browse-region-or-line
:desc "Browse file or region" "." #'+vc/browse-at-remote-file-or-region
:desc "Browse homepage" "h" #'+vc/browse-at-remote-homepage
:desc "Browse remote" "r" #'forge-browse-remote
:desc "Browse commit" "c" #'forge-browse-commit
:desc "Browse an issue" "i" #'forge-browse-issue
@ -162,7 +282,7 @@
:desc "List notifications" "n" #'forge-list-notifications)
(:prefix ("c" . "create")
:desc "Initialize repo" "r" #'magit-init
:desc "Clone repo" "R" #'+magit/clone
:desc "Clone repo" "R" #'magit-clone
:desc "Commit" "c" #'magit-commit-create
:desc "Fixup" "f" #'magit-commit-fixup
:desc "Issue" "i" #'forge-create-issue
@ -269,12 +389,15 @@
"M-SPC" #'objed-activate)
;;; buffer management
"C-x b" #'persp-switch-to-buffer
(:when (featurep! :completion ivy)
"C-x 4 b" #'+ivy/switch-workspace-buffer-other-window)
"C-x b" #'switch-to-buffer
"C-x 4 b" #'switch-to-buffer-other-window
(:when (featurep! :ui workspaces)
"C-x b" #'persp-switch-to-buffer
"C-x B" #'switch-to-buffer
"C-x 4 B" #'switch-to-buffer-other-window
(:when (featurep! :completion ivy)
"C-x 4 b" #'+ivy/switch-workspace-buffer-other-window))
"C-x C-b" #'ibuffer-list-buffers
"C-x B" #'switch-to-buffer
"C-x 4 B" #'switch-to-buffer-other-window
"C-x K" #'doom/kill-this-buffer-in-all-windows
;;; company-mode
@ -288,7 +411,7 @@
"C-S-h" #'company-show-doc-buffer
"C-s" #'company-search-candidates
"M-s" #'company-filter-candidates
"<C-tab>" #'company-complete-common-or-cycle
[C-tab] #'company-complete-common-or-cycle
[tab] #'company-complete-common-or-cycle
[backtab] #'company-select-previous
"C-RET" #'counsel-company
@ -316,22 +439,22 @@
;;; help and info
(:after help-mode
:map help-mode-map
"o" #'ace-link-help
"o" #'link-hint-open-link
">" #'help-go-forward
"<" #'help-go-back
"n" #'forward-button
"p" #'backward-button)
(:after helpful
:map helpful-mode-map
"o" #'ace-link-help)
"o" #'link-hint-open-link)
(:after apropos
:map apropos-mode-map
"o" #'ace-link-help
"o" #'link-hint-open-link
"n" #'forward-button
"p" #'backward-button)
(:after info
:map Info-mode-map
"o" #'ace-link-info)
"o" #'link-hint-open-link)
;;; ivy & counsel
(:when (featurep! :completion ivy)
@ -374,10 +497,6 @@
"C-`" #'+popup/toggle
"C-~" #'+popup/raise)
;;; repl
"C-c C-z" #'+eval/open-repl-other-window
"C-c C-S-z" #'+eval/open-repl-same-window
;;; smartparens
(:after smartparens
:map smartparens-mode-map

View file

@ -1,18 +1,12 @@
;;; config/default/+bindings.el -*- lexical-binding: t; -*-
(when (featurep! :editor evil +everywhere)
;; Have C-u behave similarly to `doom/backward-to-bol-or-indent'.
;; NOTE SPC u replaces C-u as the universal argument.
(map! :i "C-u" #'doom/backward-kill-to-bol-and-indent
:i "C-w" #'backward-kill-word
;; Vimmish ex motion keys
:i "C-b" #'backward-word
:i "C-f" #'forward-word)
;; Minibuffer
(define-key! evil-ex-completion-map
"C-a" #'move-beginning-of-line
"C-b" #'backward-word
"C-a" #'evil-beginning-of-line
"C-b" #'evil-backward-char
"C-s" (if (featurep! :completion ivy)
#'counsel-minibuffer-history
#'helm-minibuffer-history))
@ -20,12 +14,10 @@
(define-key! :keymaps +default-minibuffer-maps
[escape] #'abort-recursive-edit
"C-a" #'move-beginning-of-line
"C-b" #'backward-word
"C-f" #'forward-word
"C-r" #'evil-paste-from-register
"C-u" #'doom/backward-kill-to-bol-and-indent
"C-u" #'evil-delete-back-to-indentation
"C-v" #'yank
"C-w" #'backward-kill-word
"C-w" #'doom/delete-backward-word
"C-z" (λ! (ignore-errors (call-interactively #'undo)))
;; Scrolling lines
"C-j" #'next-line
@ -69,13 +61,13 @@
:i "C-j" #'+default/newline ; default behavior
(:after help :map help-mode-map
:n "o" #'ace-link-help)
:n "o" #'link-hint-open-link)
(:after helpful :map helpful-mode-map
:n "o" #'ace-link-help)
:n "o" #'link-hint-open-link)
(:after info :map Info-mode-map
:n "o" #'ace-link-info)
:n "o" #'link-hint-open-link)
(:after apropos :map apropos-mode-map
:n "o" #'ace-link-help
:n "o" #'link-hint-open-link
:n "TAB" #'forward-button
:n [tab] #'forward-button
:n [backtab] #'backward-button)
@ -85,6 +77,10 @@
:n "q" #'kill-current-buffer)
:m "gs" #'+evil/easymotion ; lazy-load `evil-easymotion'
(:after evil-org
:map evil-org-mode-map
:m "gsh" #'+org/goto-visible)
(:when (featurep! :editor multiple-cursors)
:prefix "gz"
:nv "d" #'evil-mc-make-and-goto-next-match
@ -137,14 +133,15 @@
"C-SPC" #'company-complete-common
"TAB" #'company-complete-common-or-cycle
[tab] #'company-complete-common-or-cycle
[backtab] #'company-select-previous)
[backtab] #'company-select-previous
[f1] nil)
(:map company-search-map ; applies to `company-filter-map' too
"C-n" #'company-select-next-or-abort
"C-p" #'company-select-previous-or-abort
"C-j" #'company-select-next-or-abort
"C-k" #'company-select-previous-or-abort
"C-s" (λ! (company-search-abort) (company-filter-candidates))
"ESC" #'company-search-abort))
[escape] #'company-search-abort))
;; TAB auto-completion in term buffers
(:after comint :map comint-mode-map
"TAB" #'company-complete
@ -335,6 +332,8 @@
:desc "Kill buffer" "k" #'kill-current-buffer
:desc "Kill all buffers" "K" #'doom/kill-all-buffers
:desc "Switch to last buffer" "l" #'evil-switch-to-windows-last-buffer
:desc "Set bookmark" "m" #'bookmark-set
:desc "Delete bookmark" "M" #'bookmark-delete
:desc "Next buffer" "n" #'next-buffer
:desc "New empty buffer" "N" #'evil-buffer-new
:desc "Kill other buffers" "O" #'doom/kill-other-buffers
@ -342,6 +341,7 @@
:desc "Revert buffer" "r" #'revert-buffer
:desc "Save buffer" "s" #'basic-save-buffer
:desc "Save all buffers" "S" #'evil-write-all
:desc "Save buffer as root" "u" #'doom/sudo-save-buffer
:desc "Pop up scratch buffer" "x" #'doom/open-scratch-buffer
:desc "Switch to scratch buffer" "X" #'doom/switch-to-scratch-buffer
:desc "Bury buffer" "z" #'bury-buffer
@ -349,23 +349,30 @@
;;; <leader> c --- code
(:prefix-map ("c" . "code")
:desc "Compile" "c" #'compile
:desc "Recompile" "C" #'recompile
:desc "Jump to definition" "d" #'+lookup/definition
:desc "Jump to references" "D" #'+lookup/references
:desc "Evaluate buffer/region" "e" #'+eval/buffer-or-region
:desc "Evaluate & replace region" "E" #'+eval:replace-region
:desc "Format buffer/region" "f" #'+format/region-or-buffer
:desc "LSP Format buffer/region" "F" #'+default/lsp-format-region-or-buffer
:desc "LSP Organize imports" "i" #'lsp-organize-imports
:desc "Jump to documentation" "k" #'+lookup/documentation
:desc "LSP Rename" "r" #'lsp-rename
:desc "Send to repl" "s" #'+eval/send-region-to-repl
:desc "Delete trailing whitespace" "w" #'delete-trailing-whitespace
:desc "Delete trailing newlines" "W" #'doom/delete-trailing-newlines
:desc "List errors" "x" #'flymake-show-diagnostics-buffer
(:when (featurep! :tools flycheck)
:desc "List errors" "x" #'flycheck-list-errors))
:desc "LSP Execute code action" "a" #'lsp-execute-code-action
:desc "Compile" "c" #'compile
:desc "Recompile" "C" #'recompile
:desc "Jump to definition" "d" #'+lookup/definition
:desc "Jump to references" "D" #'+lookup/references
:desc "Evaluate buffer/region" "e" #'+eval/buffer-or-region
:desc "Evaluate & replace region" "E" #'+eval:replace-region
:desc "Format buffer/region" "f" #'+format/region-or-buffer
:desc "LSP Format buffer/region" "F" #'+default/lsp-format-region-or-buffer
:desc "LSP Organize imports" "i" #'lsp-organize-imports
(:when (featurep! :completion ivy)
:desc "Jump to symbol in current workspace" "j" #'lsp-ivy-workspace-symbol
:desc "Jump to symbol in any workspace" "J" #'lsp-ivy-global-workspace-symbol)
(:when (featurep! :completion helm)
:desc "Jump to symbol in current workspace" "j" #'helm-lsp-workspace-symbol
:desc "Jump to symbol in any workspace" "J" #'helm-lsp-global-workspace-symbol)
:desc "Jump to documentation" "k" #'+lookup/documentation
:desc "LSP Rename" "r" #'lsp-rename
:desc "Send to repl" "s" #'+eval/send-region-to-repl
:desc "Delete trailing whitespace" "w" #'delete-trailing-whitespace
:desc "Delete trailing newlines" "W" #'doom/delete-trailing-newlines
:desc "List errors" "x" #'flymake-show-diagnostics-buffer
(:when (featurep! :checkers syntax)
:desc "List errors" "x" #'flycheck-list-errors))
;;; <leader> f --- file
(:prefix-map ("f" . "file")
@ -378,11 +385,10 @@
:desc "Find file" "f" #'find-file
:desc "Find file from here" "F" #'+default/find-file-under-here
:desc "Locate file" "l" #'locate
:desc "Move/rename file" "m" #'doom/move-this-file
:desc "Find file in private config" "p" #'doom/find-file-in-private-config
:desc "Browse private config" "P" #'doom/open-private-config
:desc "Recent files" "r" #'recentf-open-files
:desc "Recent project files" "R" #'projectile-recentf
:desc "Rename/move file" "R" #'doom/move-this-file
:desc "Save file" "s" #'save-buffer
:desc "Save file as..." "S" #'write-file
:desc "Sudo find file" "u" #'doom/sudo-find-file
@ -392,8 +398,10 @@
;;; <leader> g --- git
(:prefix-map ("g" . "git")
:desc "Git revert file" "R" #'vc-revert
:desc "Copy git link" "y" #'git-link
:desc "Copy git link to homepage" "Y" #'git-link-homepage
:desc "Copy link to remote" "y" #'+vc/browse-at-remote-kill-file-or-region
:desc "Copy link to homepage" "Y" #'+vc/browse-at-remote-kill-homepage
(:when (featurep! :ui hydra)
:desc "SMerge" "m" #'+vc/smerge-hydra/body)
(:when (featurep! :ui vc-gutter)
:desc "Git revert hunk" "r" #'git-gutter:revert-hunk
:desc "Git stage hunk" "s" #'git-gutter:stage-hunk
@ -407,7 +415,7 @@
:desc "Magit status" "g" #'magit-status
:desc "Magit file delete" "D" #'magit-file-delete
:desc "Magit blame" "B" #'magit-blame-addition
:desc "Magit clone" "C" #'+magit/clone
:desc "Magit clone" "C" #'magit-clone
:desc "Magit fetch" "F" #'magit-fetch
:desc "Magit buffer log" "L" #'magit-log
:desc "Git stage file" "S" #'magit-stage-file
@ -419,7 +427,8 @@
:desc "Find issue" "i" #'forge-visit-issue
:desc "Find pull request" "p" #'forge-visit-pullreq)
(:prefix ("o" . "open in browser")
:desc "Browse region or line" "o" #'+vc/git-browse-region-or-line
:desc "Browse file or region" "o" #'browse-at-remote
:desc "Browse homepage" "h" #'+vc/browse-at-remote-homepage
:desc "Browse remote" "r" #'forge-browse-remote
:desc "Browse commit" "c" #'forge-browse-commit
:desc "Browse an issue" "i" #'forge-browse-issue
@ -436,7 +445,7 @@
:desc "List notifications" "n" #'forge-list-notifications)
(:prefix ("c" . "create")
:desc "Initialize repo" "r" #'magit-init
:desc "Clone repo" "R" #'+magit/clone
:desc "Clone repo" "R" #'magit-clone
:desc "Commit" "c" #'magit-commit-create
:desc "Fixup" "f" #'magit-commit-fixup
:desc "Branch" "b" #'magit-branch-and-checkout
@ -457,15 +466,18 @@
(:prefix-map ("n" . "notes")
:desc "Search notes for symbol" "*" #'+default/search-notes-for-symbol-at-point
:desc "Org agenda" "a" #'org-agenda
:desc "Org capture" "c" #'org-capture
:desc "Toggle org-clock" "c" #'+org/toggle-clock
:desc "Cancel org-clock" "C" #'org-clock-cancel
:desc "Open deft" "d" #'deft
:desc "Search org agenda headlines" "h" #'+default/org-notes-headlines
:desc "Find file in notes" "f" #'+default/find-in-notes
:desc "Browse notes" "F" #'+default/browse-notes
:desc "Org store link" "l" #'org-store-link
:desc "Tags search" "m" #'org-tags-view
:desc "Find file in notes" "n" #'+default/find-in-notes
:desc "Browse notes" "N" #'+default/browse-notes
:desc "Org capture" "n" #'org-capture
:desc "Active org-clock" "o" #'org-clock-goto
:desc "Todo list" "t" #'org-todo-list
:desc "Search notes" "s" #'+default/org-notes-search
:desc "Search org agenda headlines" "S" #'+default/org-notes-headlines
:desc "View search" "v" #'org-search-view
:desc "Org export to clipboard" "y" #'+org/export-to-clipboard
:desc "Org export to clipboard as RTF" "Y" #'+org/export-to-clipboard-as-rich-text
@ -527,6 +539,7 @@
:desc "Compile in project" "c" #'projectile-compile-project
:desc "Repeat last command" "C" #'projectile-repeat-last-command
:desc "Remove known project" "d" #'projectile-remove-known-project
:desc "Discover projects in folder" "D" #'+default/discover-projects
:desc "Edit project .dir-locals" "e" #'projectile-edit-dir-locals
:desc "Find file in project" "f" #'projectile-find-file
:desc "Find file in other project" "F" #'doom/find-file-in-other-project
@ -575,23 +588,27 @@
:desc "Search other directory" "D" #'+default/search-other-cwd
:desc "Locate file" "f" #'locate
:desc "Jump to symbol" "i" #'imenu
:desc "Jump to link" "l" #'ace-link
:desc "Jump to visible link" "l" #'link-hint-open-link
:desc "Jump to link" "L" #'ffap-menu
:desc "Jump list" "j" #'evil-show-jumps
:desc "Jump to mark" "m" #'evil-show-marks
:desc "Jump to bookmark" "m" #'bookmark-jump
:desc "Look up online" "o" #'+lookup/online
:desc "Look up online (w/ prompt)" "O" #'+lookup/online-select
:desc "Look up in local docsets" "k" #'+lookup/in-docsets
:desc "Look up in all docsets" "K" #'+lookup/in-all-docsets
:desc "Search project" "p" #'+default/search-project
:desc "Search other project" "P" #'+default/search-other-project
:desc "Jump to mark" "r" #'evil-show-marks
:desc "Search buffer" "s" #'swiper-isearch
:desc "Search buffer for thing at point" "S" #'swiper-isearch-thing-at-point)
:desc "Search buffer for thing at point" "S" #'swiper-isearch-thing-at-point
:desc "Dictionary" "t" #'+lookup/dictionary-definition
:desc "Thesaurus" "T" #'+lookup/synonyms)
;;; <leader> t --- toggle
(:prefix-map ("t" . "toggle")
:desc "Big mode" "b" #'doom-big-font-mode
:desc "Flymake" "f" #'flymake-mode
(:when (featurep! :tools flycheck)
(:when (featurep! :checkers syntax)
:desc "Flycheck" "f" #'flycheck-mode)
:desc "Frame fullscreen" "F" #'toggle-frame-fullscreen
:desc "Evil goggles" "g" #'evil-goggles-mode
@ -600,13 +617,14 @@
:desc "Indent style" "I" #'doom/toggle-indent-style
:desc "Line numbers" "l" #'doom/toggle-line-numbers
(:when (featurep! :lang org +present)
:desc "org-tree-slide mode" "p" #'+org-present/start)
:desc "org-tree-slide mode" "p" #'org-tree-slide-mode)
:desc "Read-only mode" "r" #'read-only-mode
(:when (featurep! :tools flyspell)
(:when (featurep! :checkers spell)
:desc "Flyspell" "s" #'flyspell-mode)
(:when (featurep! :lang org +pomodoro)
:desc "Pomodoro timer" "t" #'org-pomodoro)
:desc "Word-wrap mode" "w" #'+word-wrap-mode))
:desc "Word-wrap mode" "w" #'+word-wrap-mode
:desc "Zen mode" "z" #'writeroom-mode))
(after! which-key
(let ((prefix-re (regexp-opt (list doom-leader-key doom-leader-alt-key))))

View file

@ -1,39 +1,5 @@
;; config/default/autoload/default.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +default/yank-buffer-filename ()
"Copy the current buffer's path to the kill ring."
(interactive)
(if-let* ((filename (or buffer-file-name (bound-and-true-p list-buffers-directory))))
(message (kill-new (abbreviate-file-name filename)))
(error "Couldn't find filename in current buffer")))
;;;###autoload
(defun +default/browse-project ()
(interactive) (doom-project-browse (doom-project-root)))
;; NOTE No need for find-in-project, use `projectile-find-file'
;;;###autoload
(defun +default/browse-templates ()
(interactive) (doom-project-browse +file-templates-dir))
;;;###autoload
(defun +default/find-in-templates ()
(interactive) (doom-project-find-file +file-templates-dir))
;;;###autoload
(defun +default/browse-emacsd ()
(interactive) (doom-project-browse doom-emacs-dir))
;;;###autoload
(defun +default/find-in-emacsd ()
(interactive) (doom-project-find-file doom-emacs-dir))
;;;###autoload
(defun +default/browse-notes ()
(interactive) (doom-project-browse org-directory))
;;;###autoload
(defun +default/find-in-notes ()
(interactive) (doom-project-find-file org-directory))
;;;###autoload
(defun +default/compile (arg)
"Runs `compile' from the root of the current project.
@ -59,9 +25,6 @@ If ARG (universal argument), runs `compile' from the current directory."
#'man
#'woman)))
;;;###autoload
(defalias '+default/newline #'newline)
;;;###autoload
(defun +default/new-buffer ()
"TODO"
@ -73,246 +36,14 @@ If ARG (universal argument), runs `compile' from the current directory."
(with-current-buffer buffer
(funcall (default-value 'major-mode))))))
;;;###autoload
(defun +default/newline-above ()
"Insert an indented new line before the current one."
(interactive)
(if (featurep 'evil)
(call-interactively 'evil-open-above)
(beginning-of-line)
(save-excursion (newline))
(indent-according-to-mode)))
;;;###autoload
(defun +default/newline-below ()
"Insert an indented new line after the current one."
(interactive)
(if (featurep 'evil)
(call-interactively 'evil-open-below)
(end-of-line)
(newline-and-indent)))
;;;###autoload
(defun +default/yank-pop ()
"Interactively select what text to insert from the kill ring."
(interactive)
(call-interactively
(cond ((fboundp 'counsel-yank-pop) #'counsel-yank-pop)
((fboundp 'helm-show-kill-ring) #'helm-show-kill-ring)
((error "No kill-ring search backend available. Enable ivy or helm!")))))
;;;###autoload
(defun +default--newline-indent-and-continue-comments-a ()
"A replacement for `newline-and-indent'.
Continues comments if executed from a commented line, with special support for
languages with weak native comment continuation support (like C-family
languages)."
(interactive)
(if (and (sp-point-in-comment)
comment-line-break-function)
(funcall comment-line-break-function nil)
(delete-horizontal-space t)
(newline nil t)
(indent-according-to-mode)))
(defun doom--backward-delete-whitespace-to-column ()
"Delete back to the previous column of whitespace, or as much whitespace as
possible, or just one char if that's not possible."
(interactive)
(let* ((context (ignore-errors (sp-get-thing)))
(op (plist-get context :op))
(cl (plist-get context :cl))
open-len close-len)
(cond ;; When in strings (sp acts weird with quotes; this is the fix)
;; Also, skip closing delimiters
((and op cl
(string= op cl)
(and (string= (char-to-string (or (char-before) 0)) op)
(setq open-len (length op)))
(and (string= (char-to-string (or (char-after) 0)) cl)
(setq close-len (length cl))))
(delete-char (- open-len))
(delete-char close-len))
;; Delete up to the nearest tab column IF only whitespace between
;; point and bol.
((and (not indent-tabs-mode)
(not (bolp))
(not (sp-point-in-string))
(save-excursion (>= (- (skip-chars-backward " \t")) tab-width)))
(let ((movement (% (current-column) tab-width)))
(when (= movement 0)
(setq movement tab-width))
(delete-char (- movement)))
(unless (memq (char-before) (list ?\n ?\ ))
(insert " ")))
;; Otherwise do a regular delete
((delete-char -1)))))
;;;###autoload
(defun +default--delete-backward-char-a (n &optional killflag)
"Same as `delete-backward-char', but preforms these additional checks:
+ If point is surrounded by (balanced) whitespace and a brace delimiter ({} []
()), delete a space on either side of the cursor.
+ If point is at BOL and surrounded by braces on adjacent lines, collapse
newlines:
{
|
} => {|}
+ Otherwise, resort to `doom--backward-delete-whitespace-to-column'.
+ Resorts to `delete-char' if n > 1"
(interactive "p\nP")
(or (integerp n)
(signal 'wrong-type-argument (list 'integerp n)))
(cond ((and (use-region-p)
delete-active-region
(= n 1))
;; If a region is active, kill or delete it.
(if (eq delete-active-region 'kill)
(kill-region (region-beginning) (region-end) 'region)
(funcall region-extract-function 'delete-only)))
;; In Overwrite mode, maybe untabify while deleting
((null (or (null overwrite-mode)
(<= n 0)
(memq (char-before) '(?\t ?\n))
(eobp)
(eq (char-after) ?\n)))
(let ((ocol (current-column)))
(delete-char (- n) killflag)
(save-excursion
(insert-char ?\s (- ocol (current-column)) nil))))
;;
((and (= n 1) (bound-and-true-p smartparens-mode))
(cond ((and (memq (char-before) (list ?\ ?\t))
(save-excursion
(and (/= (skip-chars-backward " \t" (line-beginning-position)) 0)
(bolp))))
(doom--backward-delete-whitespace-to-column))
((let* ((pair (ignore-errors (sp-get-thing)))
(op (plist-get pair :op))
(cl (plist-get pair :cl))
(beg (plist-get pair :beg))
(end (plist-get pair :end)))
(cond ((and end beg (= end (+ beg (length op) (length cl))))
(sp-backward-delete-char 1))
((doom-surrounded-p pair 'inline 'balanced)
(delete-char -1 killflag)
(delete-char 1)
(when (= (point) (+ (length cl) beg))
(sp-backward-delete-char 1)
(sp-insert-pair op)))
((and (bolp) (doom-surrounded-p pair nil 'balanced))
(delete-region beg end)
(sp-insert-pair op)
t)
((run-hook-with-args-until-success 'doom-delete-backward-functions))
((doom--backward-delete-whitespace-to-column)))))))
;; Otherwise, do simple deletion.
((delete-char (- n) killflag))))
;;;###autoload
(defun +default/search-cwd (&optional arg)
"Conduct a text search in files under the current folder.
If prefix ARG is set, prompt for a directory to search from."
(interactive "P")
(let ((default-directory
(if arg
(read-directory-name "Search directory: ")
default-directory)))
(call-interactively
(cond ((featurep! :completion ivy) #'+ivy/project-search-from-cwd)
((featurep! :completion helm) #'+helm/project-search-from-cwd)
(#'rgrep)))))
;;;###autoload
(defun +default/search-other-cwd ()
"Conduct a text search in another directory."
(interactive)
(+default/search-cwd 'other))
;;;###autoload
(defun +default/search-project (&optional arg)
"Conduct a text search in the current project root.
If prefix ARG is set, prompt for a known project to search from."
(interactive "P")
(let ((default-directory
(if arg
(if-let (projects (projectile-relevant-known-projects))
(completing-read "Search project: " projects
nil t nil nil (doom-project-root))
(user-error "There are no known projects"))
default-directory)))
(call-interactively
(cond ((featurep! :completion ivy) #'+ivy/project-search)
((featurep! :completion helm) #'+helm/project-search)
(#'projectile-grep)))))
;;;###autoload
(defun +default/search-other-project ()
"Conduct a text search in a known project."
(interactive)
(+default/search-project 'other))
;;;###autoload
(defun +default/search-project-for-symbol-at-point (&optional arg symbol)
"Conduct a text search in the current project for symbol at point.
If prefix ARG is set, prompt for a known project to search from."
(interactive
(list current-prefix-arg
(or (and (use-region-p)
(rxt-quote-pcre
(buffer-substring-no-properties (region-beginning)
(region-end))))
(rxt-quote-pcre (thing-at-point 'symbol t))
"")))
(let ((default-directory
(if arg
(if-let (projects (projectile-relevant-known-projects))
(completing-read "Switch to project: " projects
nil t nil nil (doom-project-root))
(user-error "There are no known projects"))
default-directory)))
(cond ((featurep! :completion ivy)
(+ivy/project-search nil symbol))
((featurep! :completion helm)
(+helm/project-search nil symbol))
((rgrep (regexp-quote symbol))))))
;;;###autoload
(defun +default/search-notes-for-symbol-at-point (&optional symbol)
"Conduct a text search in the current project for symbol at point. If prefix
ARG is set, prompt for a known project to search from."
(interactive
(list (rxt-quote-pcre (or (thing-at-point 'symbol t) ""))))
(require 'org)
(let ((default-directory org-directory))
(+default/search-project-for-symbol-at-point
nil symbol)))
;;;###autoload
(defun +default/org-notes-search ()
"Perform a text search on `org-directory'."
(interactive)
(require 'org)
(let ((default-directory org-directory))
(+default/search-project-for-symbol-at-point nil "")))
;;;###autoload
(defun +default/org-notes-headlines ()
"Jump to an Org headline in `org-agenda-files'."
(interactive)
(doom-completing-read-org-headings
"Jump to org headline: " org-agenda-files 3 t))
;;;###autoload
(defun +default/lsp-format-region-or-buffer ()
"Format the buffer (or selection) with LSP."
(interactive)
(unless (bound-and-true-p lsp-mode)
(user-error "Not in an LSP buffer"))
(call-interactively
(if (use-region-p)
(if (doom-region-active-p)
#'lsp-format-region
#'lsp-format-buffer)))
@ -322,24 +53,5 @@ ARG is set, prompt for a known project to search from."
(interactive)
(server-force-delete)
(while (server-running-p)
(sit-for 1))
(sleep-for 1))
(server-start))
;;;###autoload
(defun +default/find-file-under-here ()
"Perform a recursive file search from the current directory."
(interactive)
(if (featurep! :completion ivy)
(call-interactively #'counsel-file-jump)
(λ! (doom-project-find-file default-directory))))
;;;###autoload
(defun +default/insert-file-path (arg)
"Insert the file name (absolute path if prefix ARG).
If `buffer-file-name' isn't set, uses `default-directory'."
(interactive "P")
(let ((path (or buffer-file-name default-directory)))
(insert
(if arg
(abbreviate-file-name path)
(file-name-nondirectory path)))))

View file

@ -0,0 +1,51 @@
;;; config/default/autoload/files.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +default/browse-project ()
"Browse files from the current project's root."
(interactive) (doom-project-browse (doom-project-root)))
;; NOTE No need for find-in-project, use `projectile-find-file'
;;;###autoload
(defun +default/browse-templates ()
"Browse files from `+file-templates-dir'."
(interactive) (doom-project-browse +file-templates-dir))
;;;###autoload
(defun +default/find-in-templates ()
"Find a file under `+file-templates-dir', recursively."
(interactive) (doom-project-find-file +file-templates-dir))
;;;###autoload
(defun +default/browse-emacsd ()
"Browse files from `doom-emacs-dir'."
(interactive) (doom-project-browse doom-emacs-dir))
;;;###autoload
(defun +default/find-in-emacsd ()
"Find a file under `doom-emacs-dir', recursively."
(interactive) (doom-project-find-file doom-emacs-dir))
;;;###autoload
(defun +default/browse-notes ()
"Browse files from `org-directory'."
(interactive) (doom-project-browse org-directory))
;;;###autoload
(defun +default/find-in-notes ()
"Find a file under `org-directory', recursively."
(interactive) (doom-project-find-file org-directory))
;;;###autoload
(defun +default/find-file-under-here ()
"Perform a recursive file search from the current directory."
(interactive)
(if (featurep! :completion ivy)
(call-interactively #'counsel-file-jump)
(λ! (doom-project-find-file default-directory))))
;;;###autoload
(defun +default/discover-projects (arg)
"Discover projects in `projectile-project-search-path'.
If prefix ARG is non-nil, prompt for the search path."
(interactive "P")
(if arg
(call-interactively #'projectile-discover-projects-in-directory)
(mapc #'projectile-discover-projects-in-directory projectile-project-search-path)))

View file

@ -0,0 +1,91 @@
;;; config/default/autoload/search.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +default/search-cwd (&optional arg)
"Conduct a text search in files under the current folder.
If prefix ARG is set, prompt for a directory to search from."
(interactive "P")
(let ((default-directory
(if arg
(read-directory-name "Search directory: ")
default-directory)))
(call-interactively
(cond ((featurep! :completion ivy) #'+ivy/project-search-from-cwd)
((featurep! :completion helm) #'+helm/project-search-from-cwd)
(#'rgrep)))))
;;;###autoload
(defun +default/search-other-cwd ()
"Conduct a text search in another directory."
(interactive)
(+default/search-cwd 'other))
;;;###autoload
(defun +default/search-project (&optional arg)
"Conduct a text search in the current project root.
If prefix ARG is set, prompt for a known project to search from."
(interactive "P")
(let* ((disabled-command-function nil)
(default-directory
(if arg
(if-let (projects (projectile-relevant-known-projects))
(completing-read "Search project: " projects
nil t nil nil (doom-project-root))
(user-error "There are no known projects"))
default-directory)))
(call-interactively
(cond ((featurep! :completion ivy) #'+ivy/project-search)
((featurep! :completion helm) #'+helm/project-search)
(#'projectile-ripgrep)))))
;;;###autoload
(defun +default/search-other-project ()
"Conduct a text search in a known project."
(interactive)
(+default/search-project 'other))
;;;###autoload
(defun +default/search-project-for-symbol-at-point (&optional symbol arg)
"Search current project for symbol at point.
If prefix ARG is set, prompt for a known project to search from."
(interactive
(list (rxt-quote-pcre (or (doom-thing-at-point-or-region) ""))
current-prefix-arg))
(let ((default-directory
(if arg
(if-let (projects (projectile-relevant-known-projects))
(completing-read "Switch to project: " projects
nil t nil nil (doom-project-root))
(user-error "There are no known projects"))
default-directory)))
(cond ((featurep! :completion ivy)
(+ivy/project-search nil symbol))
((featurep! :completion helm)
(+helm/project-search nil symbol))
((rgrep (regexp-quote symbol))))))
;;;###autoload
(defun +default/search-notes-for-symbol-at-point (&optional symbol)
"Conduct a text search in the current project for symbol at point. If prefix
ARG is set, prompt for a known project to search from."
(interactive
(list (rxt-quote-pcre (or (doom-thing-at-point-or-region) ""))))
(require 'org)
(let ((default-directory org-directory))
(+default/search-project-for-symbol-at-point
nil symbol)))
;;;###autoload
(defun +default/org-notes-search ()
"Perform a text search on `org-directory'."
(interactive)
(require 'org)
(let ((default-directory org-directory))
(+default/search-project-for-symbol-at-point "")))
;;;###autoload
(defun +default/org-notes-headlines ()
"Jump to an Org headline in `org-agenda-files'."
(interactive)
(doom-completing-read-org-headings
"Jump to org headline: " org-agenda-files 3 t))

View file

@ -0,0 +1,164 @@
;;; config/default/autoload/text.el -*- lexical-binding: t; -*-
;;;###autoload
(defalias '+default/newline #'newline)
;;;###autoload
(defun +default/newline-above ()
"Insert an indented new line before the current one."
(interactive)
(if (featurep 'evil)
(call-interactively 'evil-open-above)
(beginning-of-line)
(save-excursion (newline))
(indent-according-to-mode)))
;;;###autoload
(defun +default/newline-below ()
"Insert an indented new line after the current one."
(interactive)
(if (featurep 'evil)
(call-interactively 'evil-open-below)
(end-of-line)
(newline-and-indent)))
;;;###autoload
(defun +default/yank-pop ()
"Interactively select what text to insert from the kill ring."
(interactive)
(call-interactively
(cond ((fboundp 'counsel-yank-pop) #'counsel-yank-pop)
((fboundp 'helm-show-kill-ring) #'helm-show-kill-ring)
((error "No kill-ring search backend available. Enable ivy or helm!")))))
;;;###autoload
(defun +default/yank-buffer-filename ()
"Copy the current buffer's path to the kill ring."
(interactive)
(if-let* ((filename (or buffer-file-name (bound-and-true-p list-buffers-directory))))
(message (kill-new (abbreviate-file-name filename)))
(error "Couldn't find filename in current buffer")))
;;;###autoload
(defun +default/insert-file-path (arg)
"Insert the file name (absolute path if prefix ARG).
If `buffer-file-name' isn't set, uses `default-directory'."
(interactive "P")
(let ((path (or buffer-file-name default-directory)))
(insert
(if arg
(abbreviate-file-name path)
(file-name-nondirectory path)))))
;;;###autoload
(defun +default--newline-indent-and-continue-comments-a ()
"A replacement for `newline-and-indent'.
Continues comments if executed from a commented line, with special support for
languages with weak native comment continuation support (like C-family
languages)."
(interactive)
(if (and (sp-point-in-comment)
comment-line-break-function)
(funcall comment-line-break-function nil)
(delete-horizontal-space t)
(newline nil t)
(indent-according-to-mode)))
(defun doom--backward-delete-whitespace-to-column ()
"Delete back to the previous column of whitespace, or as much whitespace as
possible, or just one char if that's not possible."
(interactive)
(let* ((context (ignore-errors (sp-get-thing)))
(op (plist-get context :op))
(cl (plist-get context :cl))
open-len close-len)
(cond ;; When in strings (sp acts weird with quotes; this is the fix)
;; Also, skip closing delimiters
((and op cl
(string= op cl)
(and (string= (char-to-string (or (char-before) 0)) op)
(setq open-len (length op)))
(and (string= (char-to-string (or (char-after) 0)) cl)
(setq close-len (length cl))))
(delete-char (- open-len))
(delete-char close-len))
;; Delete up to the nearest tab column IF only whitespace between
;; point and bol.
((and (not indent-tabs-mode)
(not (bolp))
(not (sp-point-in-string))
(save-excursion (>= (- (skip-chars-backward " \t")) tab-width)))
(let ((movement (% (current-column) tab-width)))
(when (= movement 0)
(setq movement tab-width))
(delete-char (- movement)))
(unless (memq (char-before) (list ?\n ?\ ))
(insert " ")))
;; Otherwise do a regular delete
((delete-char -1)))))
;;;###autoload
(defun +default--delete-backward-char-a (n &optional killflag)
"Same as `delete-backward-char', but preforms these additional checks:
+ If point is surrounded by (balanced) whitespace and a brace delimiter ({} []
()), delete a space on either side of the cursor.
+ If point is at BOL and surrounded by braces on adjacent lines, collapse
newlines:
{
|
} => {|}
+ Otherwise, resort to `doom--backward-delete-whitespace-to-column'.
+ Resorts to `delete-char' if n > 1"
(interactive "p\nP")
(or (integerp n)
(signal 'wrong-type-argument (list 'integerp n)))
(cond ((and (use-region-p)
delete-active-region
(= n 1))
;; If a region is active, kill or delete it.
(if (eq delete-active-region 'kill)
(kill-region (region-beginning) (region-end) 'region)
(funcall region-extract-function 'delete-only)))
;; In Overwrite mode, maybe untabify while deleting
((null (or (null overwrite-mode)
(<= n 0)
(memq (char-before) '(?\t ?\n))
(eobp)
(eq (char-after) ?\n)))
(let ((ocol (current-column)))
(delete-char (- n) killflag)
(save-excursion
(insert-char ?\s (- ocol (current-column)) nil))))
;;
((and (= n 1) (bound-and-true-p smartparens-mode))
(cond ((and (memq (char-before) (list ?\ ?\t))
(save-excursion
(and (/= (skip-chars-backward " \t" (line-beginning-position)) 0)
(bolp))))
(doom--backward-delete-whitespace-to-column))
((let* ((pair (ignore-errors (sp-get-thing)))
(op (plist-get pair :op))
(cl (plist-get pair :cl))
(beg (plist-get pair :beg))
(end (plist-get pair :end)))
(cond ((and end beg (= end (+ beg (length op) (length cl))))
(sp-backward-delete-char 1))
((doom-surrounded-p pair 'inline 'balanced)
(delete-char -1 killflag)
(delete-char 1)
(when (= (point) (+ (length cl) beg))
(sp-backward-delete-char 1)
(sp-insert-pair op)))
((and (bolp) (doom-surrounded-p pair nil 'balanced))
(delete-region beg end)
(sp-insert-pair op)
t)
((run-hook-with-args-until-success 'doom-delete-backward-functions))
((doom--backward-delete-whitespace-to-column)))))))
;; Otherwise, do simple deletion.
((delete-char (- n) killflag))))

View file

@ -23,20 +23,29 @@
;;;###package avy
(setq avy-all-windows nil
avy-all-windows-alt t
avy-background t)
avy-background t
;; the unpredictability of this (when enabled) makes it a poor default
avy-single-candidate-jump nil)
(after! epa
(setq epa-file-encrypt-to
(or epa-file-encrypt-to
;; Collect all public key IDs with your username
(unless (string-empty-p user-full-name)
(cl-loop for key in (ignore-errors (epg-list-keys (epg-make-context) user-full-name))
collect (epg-sub-key-id (car (epg-key-sub-key-list key)))))
user-mail-address)
;; With GPG 2.1, this forces gpg-agent to use the Emacs minibuffer to
;; prompt for the key passphrase.
epa-pinentry-mode 'loopback))
;; With GPG 2.1+, this forces gpg-agent to use the Emacs minibuffer to prompt
;; for the key passphrase.
(setq epa-pinentry-mode 'loopback)
;; Default to the first secret key available in your keyring.
(setq-default
epa-file-encrypt-to
(or (default-value 'epa-file-encrypt-to)
(unless (string-empty-p user-full-name)
(cl-loop for key in (ignore-errors (epg-list-keys (epg-make-context) user-full-name))
collect (epg-sub-key-id (car (epg-key-sub-key-list key)))))
user-mail-address))
;; And suppress prompts if epa-file-encrypt-to has a default value (without
;; overwriting file-local values).
(defadvice! +default--dont-prompt-for-keys-a (&rest _)
:before #'epa-file-write-region
(unless (local-variable-p 'epa-file-encrypt-to)
(setq-local epa-file-encrypt-to (default-value 'epa-file-encrypt-to)))))
(use-package! drag-stuff
@ -62,11 +71,6 @@
;; or specific :post-handlers with:
;; (sp-pair "{" nil :post-handlers '(:rem ("| " "SPC")))
(after! smartparens
;; Smartparens is broken in `cc-mode' as of Emacs 27. See
;; <https://github.com/Fuco1/smartparens/issues/963>.
(unless EMACS27+
(pushnew! sp--special-self-insert-commands 'c-electric-paren 'c-electric-brace))
;; Smartparens' navigation feature is neat, but does not justify how
;; expensive it is. It's also less useful for evil users. This may need to
;; be reactivated for non-evil users though. Needs more testing!
@ -76,7 +80,7 @@
sp-navigate-consider-sgml-tags nil)))
;; Autopair quotes more conservatively; if I'm next to a word/before another
;; quote, I likely don't want to open a new pair.
;; quote, I don't want to open a new pair or it would unbalance them.
(let ((unless-list '(sp-point-before-word-p
sp-point-after-word-p
sp-point-before-same-p)))
@ -114,9 +118,7 @@
;; Disable electric keys in C modes because it interferes with smartparens
;; and custom bindings. We'll do it ourselves (mostly).
(after! cc-mode
(c-toggle-electric-state -1)
(c-toggle-auto-newline -1)
(setq c-electric-flag nil)
(setq-default c-electric-flag nil)
(dolist (key '("#" "{" "}" "/" "*" ";" "," ":" "(" ")" "\177"))
(define-key c-mode-base-map key nil))
@ -278,6 +280,7 @@
(define-key! help-map
;; new keybinds
"'" #'describe-char
"u" #'doom/help-autodefs
"E" #'doom/sandbox
"M" #'doom/describe-active-minor-mode
"O" #'+lookup/online
@ -301,32 +304,43 @@
"rf" #'doom/reload-font
"re" #'doom/reload-env
;; make `describe-bindings' available under the b prefix which it previously
;; occupied. Add more binding related commands under that prefix as well
"b" nil
"bb" #'describe-bindings
"bi" #'which-key-show-minor-mode-keymap
"bm" #'which-key-show-major-mode
"bt" #'which-key-show-top-level
"bf" #'which-key-show-full-keymap
"bk" #'which-key-show-keymap
;; replaces `apropos-documentation' b/c `apropos' covers this
"d" nil
"d/" #'doom/help-search
"da" #'doom/help-autodefs
"db" #'doom/report-bug
"dc" #'doom/goto-private-config-file
"dC" #'doom/goto-private-init-file
"dd" #'doom/toggle-debug-mode
"df" #'doom/help-faq
"dh" #'doom/help
"dk" #'doom/goto-packages-file
"dl" #'doom/help-search-load-path
"dL" #'doom/help-search-loaded-files
"dm" #'doom/help-modules
"dn" #'doom/help-news
"dN" #'doom/help-news-search
"di" #'doom/goto-doomblock
"dp" #'doom/help-packages
"dP" #'doom/help-package-homepage
"dc" #'doom/goto-config-file
"dC" #'doom/help-package-config
"ds" #'doom/sandbox
"dpc" #'doom/help-package-config
"dpd" #'doom/goto-private-packages-file
"dph" #'doom/help-package-homepage
"dpp" #'doom/help-packages
"ds" #'doom/help-search-headings
"dS" #'doom/help-search
"dt" #'doom/toggle-profiler
"du" #'doom/help-autodefs
"dv" #'doom/version
"dx" #'doom/sandbox
;; replaces `apropos-command'
"a" #'apropos
"A" #'apropos-documentation
"/" #'apropos-documentation
;; replaces `describe-copying' b/c not useful
"C-c" #'describe-coding-system
;; replaces `Info-got-emacs-command-node' b/c redundant w/ `Info-goto-node'
@ -335,9 +349,11 @@
"h" nil
;; replaces `view-emacs-news' b/c it's on C-n too
"n" #'doom/help-news
;; replaces `finder-by-keyword' b/c not usefull
;; replaces `help-with-tutorial', b/c it's less useful than `load-theme'
"t" #'load-theme
;; replaces `finder-by-keyword' b/c not useful
"p" #'doom/help-packages
;; replaces `describe-package' b/c redundant w/ `doom/describe-package'
;; replaces `describe-package' b/c redundant w/ `doom/help-packages'
"P" #'find-library)
(after! which-key
@ -347,6 +363,9 @@
which-key-replacement-alist)
(cl-pushnew `((,(format "\\`\\(?:<\\(?:\\(?:f1\\|help\\)>\\)\\|C-h\\|%s h\\) r\\'" prefix-re))
nil . "reload")
which-key-replacement-alist)
(cl-pushnew `((,(format "\\`\\(?:<\\(?:\\(?:f1\\|help\\)>\\)\\|C-h\\|%s h\\) b\\'" prefix-re))
nil . "bindings")
which-key-replacement-alist)))
@ -373,14 +392,11 @@
;; which ctrl+RET will add a new "item" below the current one and
;; cmd+RET (Mac) / meta+RET (elsewhere) will add a new, blank line below
;; the current one.
:gni [C-return] #'+default/newline-below
:gni [C-S-return] #'+default/newline-above
:gn [C-return] #'+default/newline-below
:gn [C-S-return] #'+default/newline-above
(:when IS-MAC
:gni [s-return] #'+default/newline-below
:gni [S-s-return] #'+default/newline-above)
(:unless IS-MAC
:gni [M-return] #'+default/newline-below
:gni [M-S-return] #'+default/newline-above)))
:gn [s-return] #'+default/newline-below
:gn [S-s-return] #'+default/newline-above)))
;;

View file

@ -1,9 +1,9 @@
;; -*- no-byte-compile: t; -*-
;;; config/default/packages.el
(package! avy)
(package! ace-link)
(package! drag-stuff)
(package! avy :pin "cf95ba9582")
(package! drag-stuff :pin "6d06d846cd")
(package! link-hint :pin "0d9cabcdb7")
(unless (featurep! :editor evil)
(package! expand-region))
(package! expand-region :pin "1603d01fbf"))

View file

@ -14,6 +14,7 @@
(evil-ex-define-cmd "na[rrow]" #'+evil:narrow-buffer)
(evil-ex-define-cmd "retab" #'+evil:retab)
(evil-ex-define-cmd "rev[erse]" #'+evil:reverse-lines)
(evil-ex-define-cmd "l[ine]diff" #'evil-quick-diff)
;;; External resources
;; TODO (evil-ex-define-cmd "db" #'doom:db)
@ -34,7 +35,7 @@
;;; GIT
(evil-ex-define-cmd "gist" #'+gist:send) ; send current buffer/region to gist
(evil-ex-define-cmd "gistl" #'+gist:list) ; list gists by user
(evil-ex-define-cmd "gbrowse" #'+vc:git-browse) ; show file/region in github/gitlab
(evil-ex-define-cmd "gbrowse" #'+vc/browse-at-remote-file-or-region) ; show file/region in github/gitlab
(evil-ex-define-cmd "gissues" #'forge-browse-issues) ; show github issues
(evil-ex-define-cmd "git" #'magit-status) ; open magit status window
(evil-ex-define-cmd "gstage" #'magit-stage)
@ -72,8 +73,9 @@
(evil-ex-define-cmd "pg[grep]d" #'+helm:project-search-from-cwd)))
;;; Project tools
(evil-ex-define-cmd "compile" #'+evil:compile)
(evil-ex-define-cmd "mak[e]" #'+evil:make)
(evil-ex-define-cmd "com[pile]" #'+evil:compile)
(evil-ex-define-cmd "make" #'+evil:make)
(evil-ex-define-cmd "mk" #'+evil:make) ; convenience alias
(evil-ex-define-cmd "debug" #'+debugger/start)
(evil-ex-define-cmd "er[rors]" #'flycheck-list-errors)

View file

@ -11,8 +11,8 @@
;; their changes will override evil-collection's.
;; 3. Ideally, we'd do away with evil-collection entirely. It changes too often,
;; introduces breaking bugs too frequently, and I don't agree with all their
;; design choices. Regardless, it does mork than it causes trouble, so it may
;; be here to stay.
;; design choices. Regardless, it does more good than trouble, so it may be
;; here to stay.
;; 4. Adds `+evil-collection-disabled-list', to make it easier for users to
;; disable modules, and to reduce the effort required to maintain our copy of
;; `evil-collection-list' (now I can just copy it from time to time).
@ -35,7 +35,8 @@
package-menu
ruby-mode
simple
slime)
slime
lispy)
"A list of `evil-collection' modules to ignore. See the definition of this
variable for an explanation of the defaults (in comments). See
`evil-collection-mode-list' for a list of available options.")
@ -45,6 +46,9 @@ variable for an explanation of the defaults (in comments). See
;; We do this ourselves, and better.
(defvar evil-collection-want-unimpaired-p nil)
;; We handle loading evil-collection ourselves
(defvar evil-collection--supported-modes nil)
;; This has to be defined here since evil-collection doesn't autoload its own.
;; It must be updated whenever evil-collection updates theirs. Here's an easy
;; way to update it:
@ -78,11 +82,13 @@ variable for an explanation of the defaults (in comments). See
(custom cus-edit)
cus-theme
daemons
dashboard
deadgrep
debbugs
debug
diff-mode
dired
dired-sidebar
disk-usage
doc-view
docker
@ -108,6 +114,7 @@ variable for an explanation of the defaults (in comments). See
geiser
ggtags
git-timemachine
gnus
go-mode
grep
guix
@ -127,6 +134,7 @@ variable for an explanation of the defaults (in comments). See
ivy
js2-mode
leetcode
lispy
log-edit
log-view
lsp-ui-imenu
@ -169,6 +177,7 @@ variable for an explanation of the defaults (in comments). See
slime
sly
tablist
tar-mode
(term term ansi-term multi-term)
tetris
tide
@ -220,7 +229,7 @@ and complains if a module is loaded too early (during startup)."
(add-transient-hook! 'emacs-lisp-mode
(+evil-collection-init 'elisp-mode))
(add-transient-hook! 'occur-mode
(+evil-collection-init 'replace))
(+evil-collection-init 'occur))
(evil-define-key* 'normal process-menu-mode-map
"q" #'kill-current-buffer
@ -231,7 +240,10 @@ and complains if a module is loaded too early (during startup)."
(list doom-leader-key doom-localleader-key
doom-leader-alt-key doom-localleader-alt-key))
;; Load the rest
;; HACK Do this ourselves because evil-collection break's `eval-after-load' load
;; order by loading their target plugin before applying keys. It'd be too
;; much work to accommodate this eveywhere we want to bind our own evil
;; keybinds.
(dolist (mode evil-collection-mode-list)
(dolist (req (or (cdr-safe mode) (list mode)))
(with-eval-after-load req

View file

@ -1,7 +1,7 @@
#+TITLE: feature/evil
#+DATE: February 2, 2017
#+SINCE: v2.0
#+STARTUP: inlineimages
#+STARTUP: inlineimages nofold
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
@ -16,6 +16,8 @@
- [[#configuration][Configuration]]
- [[#removing-evil-mode][Removing evil-mode]]
- [[#restoring-old-substitution-behavior-on-ss][Restoring old substitution behavior on s/S]]
- [[#restoring-old-y-behavior-yank-the-whole-line][Restoring old Y behavior (yank the whole line)]]
- [[#disabling-cursor-movement-when-exiting-insert-mode][Disabling cursor movement when exiting insert mode]]
* Description
This holy module brings the vim experience to Emacs.
@ -32,6 +34,7 @@ This holy module brings the vim experience to Emacs.
+ [[https://github.com/syl20bnr/evil-escape][evil-escape]]
+ [[https://github.com/Dewdrops/evil-exchange][evil-exchange]]
+ [[https://github.com/TheBB/evil-indent-plus][evil-indent-plus]]
+ [[https://github.com/edkolev/evil-lion][evil-lion]]
+ [[https://github.com/redguardtoo/evil-nerd-commenter][evil-nerd-commentary]]
+ [[https://github.com/redguardtoo/evil-matchit][evil-matchit]]
+ [[https://github.com/cofi/evil-numbers][evil-numbers]]
@ -42,9 +45,9 @@ This holy module brings the vim experience to Emacs.
+ [[https://github.com/bling/evil-visualstar][evil-visualstar]]
+ [[https://github.com/ninrod/exato][exato]]
+ [[https://github.com/emacs-evil/evil-collection][evil-collection]]*
+ [[https://www.github.com/rgrinberg/evil-quick-diff][evil-quick-diff]]
** Hacks
+ When a window is split, the new window will be focused.
+ The o/O keys will respect and continue commented lines (can be disabled by
setting ~+evil-want-o/O-to-continue-comments~ to ~nil~).
+ In visual mode, =*= and =#= will search for the current selection instead of
@ -66,6 +69,7 @@ The following vim plugins have been ported to evil:
|-----------------------+--------------------------------+--------------------------------------------|
| vim-commentary | evil-nerd-commenter | omap =gc= |
| vim-easymotion | evil-easymotion | omap =gs= |
| vim-lion | evil-lion | omap =gl= / =gL= |
| vim-seek or vim-sneak | evil-snipe | mmap =s= / =S=, omap =z= / =Z= & =x= / =X= |
| vim-surround | evil-embrace and evil-surround | vmap =S=, omap =ys= |
@ -96,6 +100,9 @@ And these are text objects added by this module:
+ =a= C-style function arguments (provided by ~evil-args~)
+ =B= any block delimited by braces, parentheses or brackets (provided by
~evil-textobj-anyblock~)
+ =c= Comments
+ =f= For functions (but relies on the major mode to have defined a sane
+ =g= The entire buffer
+ =i j k= by indentation (=k= includes one line above; =j= includes one line
above and below) (provided by ~evil-indent-plus~)
+ =x= XML attributes (provided by ~exato~)
@ -104,15 +111,11 @@ And these are text objects added by this module:
| Ex Command | Description |
|-----------------------+--------------------------------------------------------------------------------------|
| ~:@~ | Apply macro on selected lines |
| ~:ag[!] REGEXP~ | Perform a project search with ag |
| ~:agcwd[!] REGEXP~ | Perform a project search with ag from the current directory |
| ~:al[ign][!] REGEXP~ | Align text to the first match of REGEXP. If BANG, align all matches on each line |
| ~:cp[!] NEWPATH~ | Copy the current file to NEWPATH |
| ~:dash QUERY~ | Look up QUERY (or the symbol at point) in dash docsets |
| ~:dehtml [INPUT]~ | HTML decode selected text / inserts result if INPUT is given |
| ~:enhtml [INPUT]~ | HTML encode selected text / inserts result if INPUT is given |
| ~:grep[!]~ | Perform a project search with git-grep |
| ~:grepcwd[!]~ | Perform a project search with git-grep from the current directory |
| ~:iedit REGEXP~ | Invoke iedit on all matches for REGEXP |
| ~:k[ill]all[!]~ | Kill all buffers (if BANG, affect buffer across workspaces) |
| ~:k[ill]b~ | Kill all buried buffers |
@ -128,8 +131,6 @@ And these are text objects added by this module:
| ~:repl~ | Open a REPL and/or copy the current selection to it |
| ~:retab~ | Convert indentation to the default within the selection |
| ~:rev[erse]~ | Reverse the selected lines |
| ~:rg[!]~ | Perform a project search with ripgrep |
| ~:rgcwd[!]~ | Perform a project search with ripgrep from the current directory |
| ~:rm[!] [PATH]~ | Delete the current buffer's file and buffer |
| ~:tcd[!]~ | Send =cd X= to tmux. X = the project root if BANG, X = ~default-directory~ otherwise |
@ -138,7 +139,7 @@ And these are text objects added by this module:
You must do two things to remove Evil:
1. Remove =:editor evil= from =~/.doom.d/init.el=,
2. Run ~doom refresh~ to clean up lingering dependencies and refresh your
2. Run ~doom sync~ to clean up lingering dependencies and regenerate your
autoloads files.
3. [OPTIONAL] You may want to assign new values to ~doom-leader-alt-key~ and
~doom-localleader-alt-key~. These are bound to =C-c= and =C-c l= by default.
@ -174,3 +175,23 @@ To disable evil-snipe on s/S, you can either:
added to =$DOOMDIR/packages.el=, but this will also disable incremental
highlighting for the f/F/t/T motions keys.
3. Or use =cl= and =cc=, respectively; they do the same thing.
** Restoring old Y behavior (yank the whole line)
Doom changes the behavior of the =Y= key in normal mode to yank-to-EOL
(equivalent to =y$=). This was to make it consistent with the =C= and =D=
capital operators, and because it was redundant with =yy=, which is easier to
type than =y$=.
If you prefer the old behavior, it can be reversed with:
#+BEGIN_SRC elisp
;; add to ~/.doom.d/config.el
(setq! evil-want-Y-yank-to-eol nil)
#+END_SRC
** Disabling cursor movement when exiting insert mode
Vim (and evil) move the cursor one character back when exiting insert mode. If
you prefer that it didn't, set:
#+BEGIN_SRC elisp
;; add to ~/.doom.d/config.el
(setq evil-move-cursor-back nil)
#+END_SRC

View file

@ -15,76 +15,66 @@ support for most vim file modifiers, as well as:
See http://vimdoc.sourceforge.net/htmldoc/cmdline.html#filename-modifiers for
more information on modifiers."
(let* (case-fold-search
(regexp (concat "\\(?:^\\|[^\\\\]\\)"
"\\([#%]\\)"
"\\(\\(?::\\(?:[PphtreS~.]\\|g?s[^:\t\n ]+\\)\\)*\\)"))
(matches
(cl-loop with i = 0
while (and (< i (length file-name))
(string-match regexp file-name i))
do (setq i (1+ (match-beginning 0)))
and collect
(cl-loop for j to (/ (length (match-data)) 2)
collect (match-string j file-name)))))
(dolist (match matches)
(let ((flags (split-string (car (cdr (cdr match))) ":" t))
(path (and buffer-file-name
(pcase (car (cdr match))
("%" (file-relative-name buffer-file-name))
("#" (save-excursion (other-window 1) (file-relative-name buffer-file-name))))))
flag global)
(if (not path)
(setq path "")
(while flags
(setq flag (pop flags))
(when (string-suffix-p "\\" flag)
(setq flag (concat flag (pop flags))))
(when (string-prefix-p "gs" flag)
(setq global t
flag (substring flag 1)))
(setq path
(or (pcase (substring flag 0 1)
("p" (expand-file-name path))
("~" (concat "~/" (file-relative-name path "~")))
("." (file-relative-name path default-directory))
("t" (file-name-nondirectory (directory-file-name path)))
("r" (file-name-sans-extension path))
("e" (file-name-extension path))
("S" (shell-quote-argument path))
("h"
(let ((parent (file-name-directory (expand-file-name path))))
(unless (equal (file-truename path)
(file-truename parent))
(if (file-name-absolute-p path)
(directory-file-name parent)
(file-relative-name parent)))))
("s"
(if (featurep 'evil)
(when-let (args (evil-delimited-arguments (substring flag 1) 2))
(let ((pattern (evil-transform-vim-style-regexp (car args)))
(replace (cadr args)))
(replace-regexp-in-string
(if global pattern (concat "\\(" pattern "\\).*\\'"))
(evil-transform-vim-style-regexp replace) path t t
(unless global 1))))
path))
("P"
(let ((project-root (doom-project-root (file-name-directory (expand-file-name path)))))
(unless project-root
(user-error "Not in a project"))
(abbreviate-file-name project-root)))
(_ path))
"")))
;; strip trailing slash, if applicable
(when (and (not (string= path "")) (equal (substring path -1) "/"))
(setq path (substring path 0 -1))))
(setq file-name
(replace-regexp-in-string
(format "\\(?:^\\|[^\\\\]\\)\\(%s\\)"
(regexp-quote (string-trim-left (car match))))
path file-name t t 1))))
(replace-regexp-in-string regexp "\\1" file-name t)))
(let (case-fold-search)
(with-temp-buffer
(save-excursion (insert file-name))
(while (re-search-forward "\\(^\\|[^\\\\]\\)\\(\\([%#]\\)\\(:\\([PphtreS~.]\\|g?s\\)\\)*\\)" nil t)
(catch 'continue
(unless buffer-file-name
(replace-match (match-string 1) t t nil 2)
(throw 'continue t))
(let ((beg (match-beginning 2))
(end (match-end 3))
(path (pcase (match-string 3)
("%" (file-relative-name buffer-file-name))
("#" (and (other-buffer)
(buffer-file-name (other-buffer)))))))
(save-match-data
(goto-char beg)
(while (re-search-forward ":\\([PphtreS~.]\\|g?s\\)" (+ (point) 3) t)
(let* ((modifier (match-string 1))
(global (string-prefix-p "gs" modifier)))
(when global
(setq modifier (substring modifier 1)))
(setq end (match-end 1)
path
(or (when path
(pcase (substring modifier 0 1)
("p" (expand-file-name path))
("~" (concat "~/" (file-relative-name path "~")))
("." (file-relative-name path default-directory))
("t" (file-name-nondirectory (directory-file-name path)))
("r" (file-name-sans-extension path))
("e" (file-name-extension path))
("S" (shell-quote-argument path))
("h"
(let ((parent (file-name-directory (expand-file-name path))))
(unless (file-equal-p path parent)
(if (file-name-absolute-p path)
(directory-file-name parent)
(file-relative-name parent)))))
("s"
(if (featurep 'evil)
(when-let (args (evil-delimited-arguments (substring modifier 1) 2))
(let ((pattern (evil-transform-vim-style-regexp (car args)))
(replace (cadr args)))
(replace-regexp-in-string
(if global pattern (concat "\\(" pattern "\\).*\\'"))
(evil-transform-vim-style-regexp replace) path t t
(unless global 1))))
path))
("P"
(let ((project-root (doom-project-root (file-name-directory (expand-file-name path)))))
(unless project-root
(user-error "Not in a project"))
(abbreviate-file-name project-root)))))
""))
;; strip trailing slash, if applicable
(or (string-empty-p path)
(not (equal (substring path -1) "/"))
(setq path (substring path 0 -1))))))
(replace-match path t t nil 2))))
(replace-regexp-in-string "\\\\\\([#%]\\)" "\\1" (buffer-string) t))))
(defun +evil--insert-newline (&optional above _noextranewline)
(let ((pos (save-excursion (beginning-of-line-text) (point)))
@ -158,9 +148,9 @@ more information on modifiers."
;; HACK This ping-ponging between the destination and source windows is to
;; update the window focus history, so that, if you close either split
;; afterwards you won't be sent to some random window.
(let* ((doom-inhibit-switch-window-hooks t)
(origwin (selected-window))
(win (select-window (split-window origwin count 'below))))
(let ((doom-inhibit-switch-window-hooks t)
(origwin (selected-window)))
(select-window (split-window origwin count 'below))
(unless evil-split-window-below
(select-window origwin))
(run-hooks 'doom-switch-window-hook))
@ -177,9 +167,9 @@ more information on modifiers."
;; HACK This ping-ponging between the destination and source windows is to
;; update the window focus history, so that, if you close either split
;; afterwards you won't be sent to some random window.
(let* ((doom-inhibit-switch-window-hooks t)
(origwin (selected-window))
(win (select-window (split-window origwin count 'right))))
(let ((doom-inhibit-switch-window-hooks t)
(origwin (selected-window)))
(select-window (split-window origwin count 'right))
(unless evil-vsplit-window-right
(select-window origwin))
(run-hooks 'doom-switch-window-hook))

View file

@ -31,11 +31,12 @@
(evil-visual-restore))
;;;###autoload
(defun +evil/paste-preserve-register ()
"Call `evil-paste-after' without overwriting the clipboard (by writing to the
0 register instead). This allows you to paste the same text again afterwards."
(defun +evil/alt-paste ()
"Call `evil-paste-after' but invert `evil-kill-on-visual-paste'.
By default, this replaces the selection with what's in the clipboard without
replacing its contents."
(interactive)
(let ((evil-this-register ?0))
(let ((evil-kill-on-visual-paste (not evil-kill-on-visual-paste)))
(call-interactively #'evil-paste-after)))
(defun +evil--window-swap (direction)
@ -75,28 +76,35 @@ the only window, use evil-window-move-* (e.g. `evil-window-move-far-left')."
(select-window that-window))))
;;;###autoload
(defun +evil/window-move-left () "See `+evil--window-swap'" (interactive) (+evil--window-swap 'left))
(defun +evil/window-move-left ()
"Swap windows to the left."
(interactive) (+evil--window-swap 'left))
;;;###autoload
(defun +evil/window-move-right () "See `+evil--window-swap'" (interactive) (+evil--window-swap 'right))
(defun +evil/window-move-right ()
"Swap windows to the right"
(interactive) (+evil--window-swap 'right))
;;;###autoload
(defun +evil/window-move-up () "See `+evil--window-swap'" (interactive) (+evil--window-swap 'up))
(defun +evil/window-move-up ()
"Swap windows upward."
(interactive) (+evil--window-swap 'up))
;;;###autoload
(defun +evil/window-move-down () "See `+evil--window-swap'" (interactive) (+evil--window-swap 'down))
(defun +evil/window-move-down ()
"Swap windows downward."
(interactive) (+evil--window-swap 'down))
;;;###autoload
(defun +evil/easymotion ()
"Invoke and lazy-load `evil-easymotion' without compromising which-key
integration."
(interactive)
(defun +evil/easymotion (&optional state keymap)
"Invoke `evil-easymotion' lazily without compromising which-key integration."
(interactive (list 'motion 'global))
(let ((prefix (this-command-keys)))
(evil-define-key* 'motion 'global prefix nil)
(evilem-default-keybindings (key-description prefix))
(require 'evil-easymotion)
(evil-define-key* state keymap prefix evilem-map)
(setq prefix-arg current-prefix-arg
unread-command-events
(mapcar (lambda (e) (cons t e))
(vconcat (when evil-this-operator
(where-is-internal evil-this-operator
evil-normal-state-map
nil
t))
prefix)))))
@ -149,7 +157,7 @@ Widens narrowed buffers first. If BANG, use indirect buffer clones instead."
(doom/narrow-buffer-indirectly beg end)))
;;;###autoload (autoload '+evil:yank-unindented "editor/evil/autoload/evil" nil t)
(evil-define-operator +evil:yank-unindented (beg end type register yank-handler)
(evil-define-operator +evil:yank-unindented (beg end _type _register _yank-handler)
"Saves the (reindented) characters in motion into the kill-ring."
:move-point nil
:repeat nil

View file

@ -110,10 +110,11 @@ If BANG is non-nil, open compilation output in a comint buffer.
If BANG, then run ARGUMENTS as a full command. This command understands vim file
modifiers (like %:p:h). See `+evil-resolve-vim-path-a' for details."
(interactive "<sh><!>")
(+evil:compile (format "make %s"
(evil-ex-replace-special-filenames
arguments))
bang))
(let ((compile-command "make"))
(+evil:compile (if (stringp arguments)
(evil-ex-replace-special-filenames arguments)
"")
bang)))
;;;###autoload (autoload '+evil:compile "editor/evil/autoload/ex" nil t)
(evil-define-command +evil:compile (arguments &optional bang)
@ -168,10 +169,11 @@ function and open its documentation with `helpful-function'. Otherwise, it will
search for it with `apropos'.
If QUERY is empty, this runs the equivalent of 'M-x apropos'. If BANG is
non-nil, a search is preformed against Doom's manual (wiht `doom/help-search')."
non-nil, a search is preformed against Doom's manual (with
`doom/help-search-headings')."
(interactive "<!><a>")
(if bang
(doom/help-search query)
(doom/help-search-headings query)
(save-match-data
(cond ((or (null query) (string-empty-p (string-trim query)))
(call-interactively

View file

@ -1,13 +1,43 @@
;;; editor/evil/autoload/textobjects.el -*- lexical-binding: t; -*-
;;;###autoload (autoload '+evil:whole-buffer-txtobj "editor/evil/autoload/textobjects" nil nil)
(evil-define-text-object +evil:whole-buffer-txtobj (_count &optional _beg _end type)
(evil-define-text-object +evil:whole-buffer-txtobj (count &optional _beg _end type)
"Text object to select the whole buffer."
(evil-range (point-min) (point-max) type))
;;;###autoload (autoload '+evil:defun-txtobj "editor/evil/autoload/textobjects" nil nil)
(evil-define-text-object +evil:defun-txtobj (_count &optional _beg _end type)
(evil-define-text-object +evil:defun-txtobj (count &optional _beg _end type)
"Text object to select the whole buffer."
(cl-destructuring-bind (beg . end)
(bounds-of-thing-at-point 'defun)
(evil-range beg end type)))
;;;###autoload (autoload '+evil:inner-url-txtobj "editor/evil/autoload/textobjects" nil nil)
(evil-define-text-object +evil:inner-url-txtobj (count &optional _beg _end type)
"Text object to select the inner url at point.
This excludes the protocol and querystring."
(cl-destructuring-bind (beg . end)
(bounds-of-thing-at-point 'url)
(evil-range
(save-excursion
(goto-char beg)
(re-search-forward "://" end t))
(save-excursion
(goto-char end)
(- (if-let (pos (re-search-backward "[?#]" beg t))
pos
end)
(if (evil-visual-state-p)
1
0)))
type)))
;;;###autoload (autoload '+evil:outer-url-txtobj "editor/evil/autoload/textobjects" nil nil)
(evil-define-text-object +evil:outer-url-txtobj (count &optional _beg _end type)
"Text object to select the whole url at point."
(cl-destructuring-bind (beg . end)
(bounds-of-thing-at-point 'url)
(evil-range
beg (- end (if (evil-visual-state-p) 1 0))
type)))

View file

@ -21,8 +21,10 @@ directives. By default, this only recognizes C directives.")
;; Set these defaults before `evil'; use `defvar' so they can be changed prior
;; to loading.
(defvar evil-want-C-i-jump (or (daemonp) (display-graphic-p)))
(defvar evil-want-C-u-scroll t)
(defvar evil-want-C-u-scroll t) ; moved the universal arg to <leader> u
(defvar evil-want-C-u-delete t)
(defvar evil-want-C-w-scroll t)
(defvar evil-want-C-w-delete t)
(defvar evil-want-Y-yank-to-eol t)
(defvar evil-want-abbrev-expand-on-insert-exit nil)
@ -31,15 +33,10 @@ directives. By default, this only recognizes C directives.")
:demand t
:preface
(setq evil-want-visual-char-semi-exclusive t
evil-magic t
evil-echo-state t
evil-indent-convert-tabs t
evil-ex-search-vim-style-regexp t
evil-ex-substitute-global t
evil-ex-visual-char-range t ; column range for ex commands
evil-insert-skip-empty-lines t
evil-mode-line-format 'nil
evil-respect-visual-line-mode t
;; more vim-like behavior
evil-symbol-word-search t
;; cursor appearance
@ -49,7 +46,15 @@ directives. By default, this only recognizes C directives.")
evil-insert-state-cursor 'bar
evil-visual-state-cursor 'hollow
;; must be set before evil/evil-collection is loaded
evil-want-keybinding (not (featurep! +everywhere)))
evil-want-keybinding (not (featurep! +everywhere))
;; Only do highlighting in selected window so that Emacs has less work
;; to do highlighting them all.
evil-ex-interactive-search-highlight 'selected-window)
;; Slow this down from 0.02 to prevent blocking in large or folded buffers
;; like magit while incrementally highlighting matches.
(setq-hook! 'magit-mode-hook evil-ex-hl-update-delay 0.2)
(setq-hook! 'so-long-minor-mode-hook evil-ex-hl-update-delay 0.25)
:config
(evil-select-search-module 'evil-search-module 'evil-search)
@ -121,17 +126,26 @@ directives. By default, this only recognizes C directives.")
(count-lines (point-min) (point-max))
(buffer-size)))))
;; 'gq' moves the cursor to the beginning of selection. Disable this, since
;; it's more disruptive than helpful.
;; HACK '=' moves the cursor to the beginning of selection. Disable this,
;; since it's more disruptive than helpful.
(defadvice! +evil--dont-move-cursor-a (orig-fn &rest args)
:around #'evil-indent
(save-excursion (apply orig-fn args)))
;; In evil, registers 2-9 are buffer-local. In vim, they're global, so...
(defadvice! +evil--make-numbered-markers-global-a (arg)
;; REVIEW In evil, registers 2-9 are buffer-local. In vim, they're global,
;; so... Perhaps this should be PRed upstream?
(defadvice! +evil--make-numbered-markers-global-a (char)
:after-until #'evil-global-marker-p
(and (>= char ?2) (<= char ?9)))
;; REVIEW Fix #2493: dir-locals cannot target fundamental-mode when evil-mode
;; is active. See https://github.com/hlissner/doom-emacs/issues/2493.
;; Revert this if this is ever fixed upstream.
(defadvice! +evil--fix-local-vars-a (&rest _)
:before #'turn-on-evil-mode
(when (eq major-mode 'fundamental-mode)
(hack-local-variables)))
;; Make ESC (from normal mode) the universal escaper. See `doom-escape-hook'.
(advice-add #'evil-force-normal-state :after #'+evil-escape-a)
@ -154,8 +168,10 @@ directives. By default, this only recognizes C directives.")
;; Recenter screen after most searches
(dolist (fn '(evil-visualstar/begin-search-forward
evil-visualstar/begin-search-backward
evil-ex-search-word-forward
evil-ex-search-word-backward
evil-ex-search-word-backward
evil-ex-search-next
evil-ex-search-previous
evil-ex-search-forward
evil-ex-search-backward))
(advice-add fn :after #'doom-recenter-a))
@ -218,10 +234,10 @@ directives. By default, this only recognizes C directives.")
:hook (org-mode . embrace-org-mode-hook)
:hook ((ruby-mode enh-ruby-mode) . embrace-ruby-mode-hook)
:hook (emacs-lisp-mode . embrace-emacs-lisp-mode-hook)
:hook ((lisp-mode emacs-lisp-mode clojure-mode racket-mode)
:hook ((lisp-mode emacs-lisp-mode clojure-mode racket-mode hy-mode)
. +evil-embrace-lisp-mode-hook-h)
:hook ((org-mode LaTeX-mode) . +evil-embrace-latex-mode-hook-h)
:hook ((c++-mode rust-mode rustic-mode csharp-mode java-mode swift-mode typescript-mode)
:hook ((c++-mode rustic-mode csharp-mode java-mode swift-mode typescript-mode)
. +evil-embrace-angle-bracket-modes-hook-h)
:init
(after! evil-surround
@ -233,6 +249,8 @@ directives. By default, this only recognizes C directives.")
(embrace-add-pair-regexp ?l "\\[a-z]+{" "}" #'+evil--embrace-latex))
(defun +evil-embrace-lisp-mode-hook-h ()
;; Avoid `embrace-add-pair-regexp' because it would overwrite the default
;; `f' rule, which we want for other modes
(push (cons ?f (make-embrace-pair-struct
:key ?f
:read-function #'+evil--embrace-elisp-fn
@ -241,14 +259,11 @@ directives. By default, this only recognizes C directives.")
embrace--pairs-list))
(defun +evil-embrace-angle-bracket-modes-hook-h ()
(set (make-local-variable 'evil-embrace-evil-surround-keys)
(delq ?< evil-embrace-evil-surround-keys))
(push (cons ?< (make-embrace-pair-struct
:key ?<
:read-function #'+evil--embrace-angle-brackets
:left-regexp "\\[a-z]+<"
:right-regexp ">"))
embrace--pairs-list))
(let ((var (make-local-variable 'evil-embrace-evil-surround-keys)))
(set var (delq ?< evil-embrace-evil-surround-keys))
(set var (delq ?> evil-embrace-evil-surround-keys)))
(embrace-add-pair-regexp ?< "\\_<[a-z0-9-_]+<" ">" #'+evil--embrace-angle-brackets)
(embrace-add-pair ?> "<" ">"))
;; Add escaped-sequence support to embrace
(setf (alist-get ?\\ (default-value 'embrace--pairs-list))
@ -285,6 +300,10 @@ directives. By default, this only recognizes C directives.")
t))))
(use-package! evil-quick-diff
:commands (evil-quick-diff evil-quick-diff-cancel))
(use-package! evil-nerd-commenter
:commands (evilnc-comment-operator
evilnc-inner-comment
@ -386,11 +405,11 @@ To change these keys see `+evil-repeat-keys'."
;; `evil-collection'
(when (featurep! +everywhere)
(setq evil-collection-company-use-tng (featurep! :completion company +tng))
(unless doom-reloading-p
(load! "+everywhere"))
(setq evil-collection-company-use-tng (featurep! :completion company +tng))
;; Don't let evil-collection interfere with certain keys
(appendq! evil-collection-key-blacklist
(append (when (featurep! :tools lookup)
@ -402,7 +421,7 @@ To change these keys see `+evil-repeat-keys'."
(defadvice! +evil-collection-disable-blacklist-a (orig-fn)
:around #'evil-collection-vterm-toggle-send-escape ; allow binding to ESC
(let (evil-collection-key-blacklist)
(apply orig-fn))))
(funcall-interactively orig-fn))))
;; Keybinds that have no Emacs+evil analogues (i.e. don't exist):
;; zq - mark word at point as good word
@ -440,6 +459,9 @@ To change these keys see `+evil-repeat-keys'."
:n "gT" #'+workspace:switch-previous
:n "]w" #'+workspace/switch-right
:n "[w" #'+workspace/switch-left)
(:when (featurep! :ui tabs)
:n "gt" #'centaur-tabs-forward
:n "gT" #'centaur-tabs-backward)
;; custom vim-unmpaired-esque keys
:m "]#" #'+evil/next-preproc-directive
@ -461,7 +483,7 @@ To change these keys see `+evil-repeat-keys'."
:n "[o" #'+evil/insert-newline-above
:n "]o" #'+evil/insert-newline-below
:n "gp" #'+evil/reselect-paste
:v "gp" #'+evil/paste-preserve-register
:v "gp" #'+evil/alt-paste
:nv "g@" #'+evil:apply-macro
:nv "gc" #'evilnc-comment-operator
:nv "gx" #'evil-exchange
@ -494,7 +516,7 @@ To change these keys see `+evil-repeat-keys'."
:n "gr" #'elfeed-search-update--force
:n "gR" #'elfeed-search-fetch))
:nv "z=" #'flyspell-correct-word-generic
:nv "z=" #'flyspell-correct-at-point
;; custom evil keybinds
:nv "zn" #'+evil:narrow-buffer
:n "zN" #'doom/widen-indirectly-narrowed-buffer
@ -540,18 +562,19 @@ To change these keys see `+evil-repeat-keys'."
:textobj "i" #'evil-indent-plus-i-indent #'evil-indent-plus-a-indent
:textobj "j" #'evil-indent-plus-i-indent-up-down #'evil-indent-plus-a-indent-up-down
:textobj "k" #'evil-indent-plus-i-indent-up #'evil-indent-plus-a-indent-up
:textobj "u" #'+evil:inner-url-txtobj #'+evil:outer-url-txtobj
:textobj "x" #'evil-inner-xml-attr #'evil-outer-xml-attr
;; evil-easymotion
;; evil-easymotion (see `+evil/easymotion')
(:after evil-easymotion
:map evilem-map
"a" (evilem-create #'evil-forward-arg)
"A" (evilem-create #'evil-backward-arg)
"s" #'evil-avy-goto-char-2
"SPC" (λ!! #'evil-avy-goto-char-timer t)
"/" #'evil-avy-goto-char-timer)
(:map evilem-map
"a" (evilem-create #'evil-forward-arg)
"A" (evilem-create #'evil-backward-arg)
"s" #'evil-avy-goto-char-2
"SPC" (λ!! #'evil-avy-goto-char-timer t)
"/" #'evil-avy-goto-char-timer))
;; evil-snipe
;; evil-snipe
(:after evil-snipe
:map evil-snipe-parent-transient-map
"C-;" (λ! (require 'evil-easymotion)
@ -566,6 +589,12 @@ To change these keys see `+evil-repeat-keys'."
:o "s" #'evil-surround-edit
:o "S" #'evil-Surround-edit
;; evil-lion
:n "gl" #'evil-lion-left
:n "gL" #'evil-lion-right
:v "gl" #'evil-lion-left
:v "gL" #'evil-lion-right
;; Omni-completion
(:when (featurep! :completion company)
(:prefix "C-x"

View file

@ -1,21 +1,27 @@
;; -*- no-byte-compile: t; -*-
;;; editor/evil/packages.el
(package! evil)
(package! evil-args)
(package! evil-easymotion)
(package! evil-embrace)
(package! evil-escape)
(package! evil-exchange)
(package! evil-indent-plus)
(package! evil-nerd-commenter)
(package! evil-numbers :recipe (:host github :repo "janpath/evil-numbers"))
(package! evil-snipe)
(package! evil-surround)
(package! evil-textobj-anyblock)
(package! evil-traces)
(package! evil-visualstar)
(package! exato)
(package! evil :pin "7c42ba4de0")
(package! evil-args :pin "758ad5ae54")
(package! evil-easymotion :pin "79c13ed3bc")
(package! evil-embrace :pin "4379adea03")
(package! evil-escape :pin "f4e9116bfb")
(package! evil-exchange :pin "3030e21ee1")
(package! evil-indent-plus :pin "0c7501e6ef")
(package! evil-lion :pin "6b03593f5d")
(package! evil-nerd-commenter :pin "fa40dab8d2")
(package! evil-numbers
:recipe (:host github :repo "janpath/evil-numbers")
:pin "d988041c1f")
(package! evil-snipe :pin "3ec8adfd49")
(package! evil-surround :pin "9b0b17f06c")
(package! evil-textobj-anyblock :pin "ff00980f06")
(package! evil-traces :pin "bc25cae9fa")
(package! evil-visualstar :pin "06c053d8f7")
(package! exato :pin "88266fa7fc")
(package! evil-quick-diff
:recipe (:host github :repo "rgrinberg/evil-quick-diff")
:pin "69c883720b")
;;
(when (featurep! +everywhere)
@ -25,4 +31,4 @@
(package! neotree)
(autoload 'neotree-make-executor "neotree" nil nil 'macro))
(package! evil-collection))
(package! evil-collection :pin "e6a4ba695e"))

View file

@ -1,7 +1,7 @@
;; -*- no-byte-compile: t; -*-
;;; editor/evil/test/test-evil.el
(describe "feature/evil"
(describe "editor/evil"
:var (resv project-root)
(require! :editor evil)

View file

@ -4,21 +4,21 @@
#+STARTUP: inlineimages
* Table of Contents :TOC_2:noexport:
- [[Description][Description]]
- [[Module Flags][Module Flags]]
- [[Plugins][Plugins]]
- [[Prerequisites][Prerequisites]]
- [[Usage][Usage]]
- [[Inserting OSS licenses][Inserting OSS licenses]]
- [[Configuration][Configuration]]
- [[Registering a new file template][Registering a new file template]]
- [[Changing existing file templates][Changing existing file templates]]
- [[Adding new OSS licenses][Adding new OSS licenses]]
- [[Troubleshooting][Troubleshooting]]
- [[Appendix][Appendix]]
- [[API][API]]
- [[Commands][Commands]]
- [[Variables][Variables]]
- [[#description][Description]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#prerequisites][Prerequisites]]
- [[#usage][Usage]]
- [[#inserting-oss-licenses][Inserting OSS licenses]]
- [[#configuration][Configuration]]
- [[#registering-a-new-file-template][Registering a new file template]]
- [[#changing-existing-file-templates][Changing existing file templates]]
- [[#adding-new-oss-licenses][Adding new OSS licenses]]
- [[#troubleshooting][Troubleshooting]]
- [[#appendix][Appendix]]
- [[#api][API]]
- [[#commands][Commands]]
- [[#variables][Variables]]
* Description
This module adds file templates for blank files, powered by yasnippet.
@ -49,8 +49,12 @@ for comment headers in code.
#+end_quote
* Configuration
** TODO Registering a new file template
** TODO Changing existing file templates
** Registering a new file template
Look into the documentation of ~set-file-template!~ and ~set-file-templates!~.
** Changing existing file templates
Simply register a new template (using ~set-file-template!~) that matches the same
file. The new template would be pushed to the top of ~+file-template-alist~ and
thus would take priority while searching for a template to insert.
** Adding new OSS licenses
The ~+file-templates/insert-license~ command searches for snippets under
~text-mode~ that are named ~__license-ABC~, where ABC is the short name of the

View file

@ -41,7 +41,7 @@ these properties:
;;;###autodef
(defun set-file-templates! (&rest templates)
"Like `set-file-templates!', but can register multiple file templates at once.
"Like `set-file-template!', but can register multiple file templates at once.
\(fn &rest (PRED &key WHEN TRIGGER MODE PROJECT IGNORE))"
(defer-until! (boundp '+file-templates-alist)
@ -100,6 +100,8 @@ evil is loaded and enabled)."
"Insert a license file template into the current file."
(interactive)
(require 'yasnippet)
(unless (gethash 'text-mode yas--tables)
(yas-reload-all t))
(let ((templates
(let (yas-choose-tables-first ; avoid prompts
yas-choose-keys-first)

View file

@ -9,7 +9,7 @@
don't have a :trigger property in `+file-templates-alist'.")
(defvar +file-templates-alist
`(;; General
'(;; General
(gitignore-mode)
(dockerfile-mode)
("/docker-compose\\.yml$" :mode yaml-mode)
@ -29,7 +29,7 @@ don't have a :trigger property in `+file-templates-alist'.")
:trigger "__doom-module"
:mode emacs-lisp-mode)
("-test\\.el$" :mode emacs-ert-mode)
(emacs-lisp-mode :trigger "__initfile")
(emacs-lisp-mode :trigger "__package")
(snippet-mode)
;; C/C++
("/main\\.c\\(?:c\\|pp\\)$" :trigger "__main.cpp" :mode c++-mode)
@ -118,11 +118,14 @@ information.")
"Return t if RULE applies to the current buffer."
(let ((pred (car rule))
(plist (cdr rule)))
(and (cond ((symbolp pred) (eq major-mode pred))
((and (stringp pred) buffer-file-name)
(string-match-p pred buffer-file-name))
((not (plist-member plist :when)) t)
((funcall (plist-get plist :when) buffer-file-name)))
(and (or (and (symbolp pred)
(eq major-mode pred))
(and (stringp pred)
(stringp buffer-file-name)
(string-match-p pred buffer-file-name)
(or (not (plist-member plist :when))
(funcall (plist-get plist :when)
buffer-file-name))))
rule)))
(defun +file-templates-check-h ()
@ -134,10 +137,7 @@ must be non-read-only, empty, and there must be a rule in
(bobp) (eobp)
(not (member (substring (buffer-name) 0 1) '("*" " ")))
(not (file-exists-p buffer-file-name))
;; Prevent file-templates from breaking org-capture when target file
;; doesn't exist and has a file template.
(or (not (fboundp 'org-capture-get))
(not (org-capture-get :new-buffer)))
(not (buffer-modified-p))
(when-let (rule (cl-find-if #'+file-template-p +file-templates-alist))
(apply #'+file-templates--expand rule))))
@ -156,4 +156,4 @@ must be non-read-only, empty, and there must be a rule in
(yas-reload-all)))
;;
(add-hook 'find-file-hook #'+file-templates-check-h)
(add-hook 'doom-switch-buffer-hook #'+file-templates-check-h)

View file

@ -1,5 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; editor/file-templates/packages.el
(package! yasnippet)
(package! yasnippet :pin "3bf9a3b1af")

View file

@ -1,6 +0,0 @@
;;; `(file-name-nondirectory buffer-file-name)`${1: --- ${2:description}} -*- lexical-binding: t; -*-
$0
(provide '`(file-name-base buffer-file-name)`)
;;; `(file-name-nondirectory buffer-file-name)` ends here

View file

@ -0,0 +1,25 @@
;;; `(file-name-nondirectory buffer-file-name)`${1: --- ${2:description}} -*- lexical-binding: t; -*-
;;
;; Copyright (C) `(format-time-string "%Y")` `user-full-name`
;;
;; Author: `user-full-name` <http://github/`user-login-name`>
;; Maintainer: `user-full-name` <`user-mail-address`>
;; Created: `(format-time-string "%B %d, %Y")`
;; Modified: `(format-time-string "%B %d, %Y")`
;; Version: 0.0.1
;; Keywords:
;; Homepage: https://github.com/`user-login-name`/`(file-name-base buffer-file-name)`
;; Package-Requires: ((emacs `emacs-version`) (cl-lib "0.5"))
;;
;; This file is not part of GNU Emacs.
;;
;;; Commentary:
;;
;; $2
;;
;;; Code:
`%`$0
(provide '`(file-name-base buffer-file-name)`)
;;; `(file-name-nondirectory buffer-file-name)` ends here

View file

@ -20,5 +20,12 @@ tmp/
'("*.class"
"build"))
((string= type-ignore "js")
'("*.tern-port")))
'("*.tern-port"
"node_modules/"
"npm-debug.log*"
"yarn-debug.log*"
"yarn-error.log*"
"*.tsbuildinfo"
".npm"
".eslintcache")))
"\n"))`

View file

@ -1,5 +1,5 @@
# -*- mode: snippet -*-
# name: Doom module readme
# name: Doom module readme
# --
#+TITLE: ${1:`(if (string-match "modules/\\([^/]+\\)/\\([^/]+\\)/.+" buffer-file-name)
(format "%s/%s"
@ -8,35 +8,63 @@
"")`}
#+DATE: `(format (format-time-string "%B %%s, %Y") (string-to-number (format-time-string "%d")))`
#+SINCE: ${2:{replace with next tagged release version}}
#+STARTUP: inlineimages
#+STARTUP: inlineimages nofold
* Table of Contents :TOC_3:noexport:
* Description
${3:A summary of what this module does.}
${3:# A summary of what this module does.}
+ If possible, include a brief list of feature highlights here
+ Like code completion, syntax checking or available snippets
+ Include links to packages & external things where possible
** Maintainers
+ @username_linked_to_gihub (Author)
+ @username_linked_to_gihub
+ @username_linked_to_gihub
# If this module has no maintainers, then...
This module has no dedicated maintainers.
** Module Flags
+ =+flag1= A short description of what this flag does and what it might need
when enabled.
+ =+flag2= A short description of what this flag does and what it might need
when enabled.
+ =+flag3= A short description of what this flag does and what it might need
when enabled.
# If this module has no flags, then...
This module provides no flags.
** Plugins
{A list of linked plugins}
# A list of linked plugins
+ [[https://orgmode.org/][org-plus-contrib]]
+ [[https://github.com/sabof/org-bullets][org-bullets]]
+ [[https://github.com/TobiasZawada/org-yt][org-yt]]
+ [[https://github.com/sebastiencs/company-box][company-box]]* (=+childframe=)
+ =:lang crystal=
+ [[https://github.com/brantou/ob-crystal][ob-crystal]]
+ =:lang go=
+ [[https://github.com/pope/ob-go][ob-go]]
+ =+present=
+ [[https://github.com/anler/centered-window-mode][centered-window]]
+ [[https://github.com/takaxp/org-tree-slide][org-tree-slide]]
+ [[https://gitlab.com/oer/org-re-reveal][org-re-reveal]]
** Hacks
{A list of internal modifications to included packages}
# A list of internal modifications to included packages; omit if unneeded
* Prerequisites
This module has no prereqisites.
* Features
An in-depth list of features, how to use them, and their dependencies.
# An in-depth list of features, how to use them, and their dependencies.
* Configuration
How to configure this module, including common problems and how to address them.
# How to configure this module, including common problems and how to address them.
* Troubleshooting
Common issues and their solution, or places to look for help.
# Common issues and their solution, or places to look for help.
$0

View file

@ -27,7 +27,10 @@
(save-excursion
(ignore-errors
(or (hs-looking-at-block-start-p)
(hs-find-block-beginning)))))
(hs-find-block-beginning)
(unless (eolp)
(end-of-line)
(+fold--hideshow-fold-p))))))
(defun +fold--invisible-points (count)
(let (points)

View file

@ -29,7 +29,7 @@
hs-set-up-overlay #'+fold-hideshow-set-up-overlay-fn)
(defadvice! +fold--hideshow-ensure-mode-a (&rest _)
"Ensure `hs-minor-mode' is enabled."
"Ensure `hs-minor-mode' is enabled when we need it, no sooner or later."
:before '(hs-toggle-hiding hs-hide-block hs-hide-level hs-show-all hs-hide-all)
(unless (bound-and-true-p hs-minor-mode)
(hs-minor-mode +1)))

View file

@ -1,5 +1,8 @@
;; -*- no-byte-compile: t; -*-
;;; editor/fold/packages.el
(package! hideshow :built-in t)
(package! vimish-fold :pin "d3248a41a7")
(when (featurep! :editor evil)
(package! evil-vimish-fold))
(package! evil-vimish-fold :pin "b6e0e6b91b"))

View file

@ -95,7 +95,7 @@ Stolen shamelessly from go-mode"
(require 'format-all)
(let* ((fmtlist (mapcar #'symbol-name (hash-table-keys format-all--format-table)))
(fmt (completing-read "Formatter: " fmtlist)))
(if fmt (cons (intern fmt) t))))
(if fmt (intern fmt))))
;;;###autoload
(defun +format-probe-a (orig-fn)
@ -131,15 +131,19 @@ See `+format/buffer' for the interactive version of this function, and
;; like `gofmt') widen the buffer, in order to only format a region of
;; text, we must make a copy of the buffer to apply formatting to.
(let ((output (buffer-substring-no-properties (point-min) (point-max)))
(origin-buffer-file-name (buffer-file-name (buffer-base-buffer)))
(origin-default-directory default-directory))
(origin-buffer (or (buffer-base-buffer) (current-buffer))))
(with-temp-buffer
(with-silent-modifications
(insert output)
;; Ensure this temp buffer _seems_ as much like the origin
;; buffer as possible.
(setq default-directory origin-default-directory
buffer-file-name origin-buffer-file-name)
(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)
;; 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.
(when preserve-indent-p

View file

@ -67,7 +67,7 @@
(doom-log "formatter (arglist) %s" args)
(if ,(and (or ok-statuses error-regexp) t)
(apply #'format-all--buffer-hard
',ok-statuses ,error-regexp
',ok-statuses ,error-regexp nil
(reverse args))
(apply #'format-all--buffer-easy (reverse args)))))

View file

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

View file

@ -1,4 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; editor/god/packages.el
(package! god-mode)
(package! god-mode :pin "344167ed9b")

View file

@ -1,5 +1,15 @@
#+TITLE: :editor lispy
#+TITLE: editor/lispy
#+DATE: October 27, 2018
#+SINCE: v2.0
#+STARTUP: inlineimages
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#prerequisites][Prerequisites]]
- [[#troubleshooting][Troubleshooting]]
- [[#mouse-wheel-and-wrapadditional-wrap-key-themes-in-tty-emacs-2573][Mouse wheel and =wrap=/=additional-wrap= key themes in TTY Emacs (#2573)]]
* Description
This module adds [[https://github.com/noctuid/lispyville][lispy]] key functionality in Lisp languages.
This includes:
@ -24,13 +34,19 @@ The default key themes that are set are as follows:
(prettify insert)
(atom-movement normal visual)
slurp/barf-lispy
(wrap normal insert)
additional
additional-insert
(additional-wrap normal insert)
(escape insert)))
additional-insert))
#+END_SRC
See noctuid's [[https://github.com/noctuid/lispyville/blob/master/README.org][README]] for more info on specific keybindings (starting [[https://github.com/noctuid/lispyville#operators-key-theme][here]]) of
each key theme. Think of ~lispyville-set-key-theme~ as adding
~parinfer-extensions~ via ~(setq parinfer-extensions '(blah blah blah))~.
* Prerequisites
This module has no prerequisites.
* Troubleshooting
** Mouse wheel and =wrap=/=additional-wrap= key themes in TTY Emacs ([[https://github.com/hlissner/doom-emacs/issues/2573][#2573]])
lispyville binds =M-[= to ~lispyville-wrap-brackets~ when the =wrap= or
=additional-wrap= key theme are enabled. In terminal Emacs, this is the key
Emacs receives when you scroll with your mouse wheel.

View file

@ -7,11 +7,13 @@
(racket-mode . lispy-mode)
(hy-mode . lispy-mode)
(lfe-mode . lispy-mode)
(dune-mode . lispy-mode)
(clojure-mode . lispy-mode))
:config
(setq lispy-close-quotes-at-end-p t)
(add-hook 'lispy-mode-hook #'turn-off-smartparens-mode))
(use-package! lispyville
:when (featurep! :editor evil)
:hook (lispy-mode . lispyville-mode)
@ -22,8 +24,5 @@
(prettify insert)
(atom-movement normal visual)
slurp/barf-lispy
(wrap normal insert)
additional
additional-insert
(additional-wrap normal insert)
(escape insert))))
additional-insert)))

View file

@ -1,7 +1,6 @@
;; -*- no-byte-compile: t; -*-
;;; editor/lispyville/packages.el
(package! lispy)
(package! lispy :pin "d6b19fe2c3")
(when (featurep! :editor evil)
(package! lispyville))
(package! lispyville :pin "56198f1c44"))

View file

@ -51,39 +51,41 @@ pauses cursors."
(evil-define-command +multiple-cursors:evil-mc (beg end type pattern &optional flags bang)
"Create mc cursors at each match of PATTERN within BEG and END.
This leaves the cursor at the final match. If BANG, then treat PATTERN as
literal. PATTERN is a delimited regexp (the same that :g or :s uses)."
:move-point nil
This leaves the cursor where the final cursor would be. If BANG, then treat
PATTERN as literal. PATTERN is a delimited regexp (the same that :g or :s uses).
FLAGS can be g and/or i; which mean the same thing they do in
`evil-ex-substitute'."
:evil-mc t
(interactive "<R><//!><!>")
(unless (and (stringp pattern)
(not (string-empty-p pattern)))
(user-error "A regexp pattern is required"))
(require 'evil-mc)
(setq evil-mc-pattern
(cons (evil-ex-make-search-pattern
(if bang (regexp-quote pattern) pattern))
(list beg end type)))
(evil-with-restriction beg end
(let ((point (point)))
(save-excursion
(goto-char (point-min))
(while (eq (evil-ex-find-next (evil-mc-get-pattern) 'forward t) t)
(goto-char (1- (point)))
(when (/= point (point))
(evil-mc-run-cursors-before)
(evil-mc-make-cursor-at-pos (point)))
(goto-char
(if (memq ?g flags)
(line-beginning-position 2)
(1+ (point))))))))
(evil-exit-visual-state)
(evil-mc-goto-cursor
(if (= (evil-visual-direction) 1)
(evil-mc-find-last-cursor)
(evil-mc-find-first-cursor))
nil)
(evil-mc-undo-cursor-at-pos (point))
(if (evil-mc-has-cursors-p)
(evil-mc-print-cursors-info "Created")
(evil-mc-message "No cursors were created")))
(let ((m (evil-ex-make-pattern
(if bang (regexp-quote pattern) pattern)
(cond ((memq ?i flags) 'insensitive)
((memq ?I flags) 'sensitive)
((not +multiple-cursors-evil-mc-ex-case)
evil-ex-search-case)
(t +multiple-cursors-evil-mc-ex-case))
(or (and +multiple-cursors-evil-mc-ex-global
(not (memq ?g flags)))
(and (not +multiple-cursors-evil-mc-ex-global)
(memq ?g flags))))))
(evil-mc-run-cursors-before)
(setq evil-mc-pattern (cons m (list beg end type)))
(evil-with-restriction beg end
(goto-char beg)
(while (eq (evil-ex-find-next m 'forward t) t)
(evil-mc-make-cursor-at-pos (1- (point)))
(unless (evil-ex-pattern-whole-line m)
(goto-char (line-beginning-position 2)))))
(evil-mc-goto-cursor
(if (= (evil-visual-direction) 1)
(evil-mc-find-last-cursor)
(evil-mc-find-first-cursor))
nil)
(evil-mc-undo-cursor-at-pos (1- (point)))
(if (evil-mc-has-cursors-p)
(evil-mc-print-cursors-info "Created")
(evil-mc-message "No cursors were created"))))

View file

@ -1,5 +1,15 @@
;;; editor/multiple-cursors/config.el -*- lexical-binding: t; -*-
(defvar +multiple-cursors-evil-mc-ex-global t
"TODO")
(defvar +multiple-cursors-evil-mc-ex-case nil
"TODO")
;;
;;; Packages
(use-package! evil-multiedit
:when (featurep! :editor evil)
:defer t
@ -57,13 +67,16 @@
(company-complete-common . evil-mc-execute-default-complete)
(doom/backward-to-bol-or-indent . evil-mc-execute-default-call)
(doom/forward-to-last-non-comment-or-eol . evil-mc-execute-default-call)
(doom/backward-kill-to-bol-and-indent . evil-mc-execute-default-call)
(evil-delete-back-to-indentation . evil-mc-execute-default-call)
;; Have evil-mc work with explicit `evil-escape' (on C-g)
(evil-escape . evil-mc-execute-default-evil-normal-state)
;; Add `evil-org' support
(evil-org-delete . evil-mc-execute-default-evil-delete)
(evil-org-delete-char . evil-mc-execute-default-evil-delete)
(evil-org-delete-backward-char . evil-mc-execute-default-evil-delete)))
(evil-org-delete-backward-char . evil-mc-execute-default-evil-delete)
;; `evil-numbers'
(evil-numbers/inc-at-pt-incremental)
(evil-numbers/dec-at-pt-incremental)))
(cl-pushnew `(,(car fn) (:default . ,(or (cdr fn) #'evil-mc-execute-default-call-with-count)))
evil-mc-custom-known-commands
:test #'eq

View file

@ -1,9 +1,9 @@
;; -*- no-byte-compile: t; -*-
;;; editor/multiple-cursors/packages.el
(cond ((featurep! :editor evil)
(package! evil-multiedit)
(package! evil-mc))
((package! multiple-cursors)))
(cond
((featurep! :editor evil)
(package! evil-multiedit :pin "c3d43b1a65")
(package! evil-mc :pin "007d471e26"))
((package! multiple-cursors :pin "b880554d04")))

View file

@ -1,4 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; editor/objed/packages.el
(package! objed)
(package! objed :pin "8dc17701d1")

View file

@ -1,7 +1,12 @@
;;; editor/parinfer/config.el -*- lexical-binding: t; -*-
(use-package! parinfer
:hook ((emacs-lisp-mode clojure-mode scheme-mode lisp-mode) . parinfer-mode)
:hook ((emacs-lisp-mode
clojure-mode
scheme-mode
lisp-mode
racket-mode
hy-mode) . parinfer-mode)
:init
(setq parinfer-extensions
'(defaults

View file

@ -11,4 +11,4 @@
;; separate session:
(autoload 'evil-define-key "evil-core" nil nil 'macro))
(package! parinfer)
(package! parinfer :pin "eaad857ae4")

View file

@ -1,4 +1,6 @@
;; -*- no-byte-compile: t; -*-
;;; editor/rotate-text/packages.el
(package! rotate-text :recipe (:host github :repo "debug-ito/rotate-text.el"))
(package! rotate-text
:recipe (:host github :repo "debug-ito/rotate-text.el")
:pin "48f193697d")

View file

@ -16,6 +16,9 @@
yas-new-snippet
yas-visit-snippet-file)
:init
;; Remove default ~/.emacs.d/snippets
(defvar yas-snippet-dirs nil)
;; Ensure `yas-reload-all' is called as late as possible. Other modules could
;; have additional configuration for yasnippet. For example, file-templates.
(add-transient-hook! 'yas-minor-mode-hook (yas-reload-all))
@ -28,17 +31,17 @@
:config
(setq yas-verbosity (if doom-debug-mode 3 0)
yas-also-auto-indent-first-line t
;; Remove default ~/.emacs.d/snippets
yas-snippet-dirs (delete yas--default-user-snippets-dir
yas-snippet-dirs))
yas-also-auto-indent-first-line t)
(add-to-list 'load-path +snippets-dir)
;; default snippets library, if available
(require 'doom-snippets nil t)
;; Allow private snippets in DOOMDIR/snippets
(add-to-list 'yas-snippet-dirs '+snippets-dir nil #'eq)
(add-to-list 'yas-snippet-dirs '+snippets-dir)
;; In case `+snippets-dir' and `doom-snippets-dir' are the same
(advice-add #'yas-snippet-dirs :filter-return #'delete-dups)
;; Remove GUI dropdown prompt (prefer ivy/helm)
(delq! 'yas-dropdown-prompt yas-prompt-functions)

View file

@ -1,10 +1,10 @@
;; -*- no-byte-compile: t; -*-
;;; editor/snippets/packages.el
(package! yasnippet)
(package! auto-yasnippet)
(package! yasnippet :pin "3bf9a3b1af")
(package! auto-yasnippet :pin "db9e0dd433")
(package! doom-snippets
:recipe (:host github
:repo "hlissner/doom-snippets"
:files ("*.el" "*")))
:files ("*.el" "*"))
:pin "2781b782a3")

View file

@ -6,6 +6,7 @@
(defvar +word-wrap--enable-visual-line-mode nil)
(defvar +word-wrap--major-mode-indent-var nil)
(defvar adaptive-wrap-extra-indent)
(defun +word-wrap--adjust-extra-indent-a (orig-fn beg end)
"Contextually adjust extra word-wrap indentation."
(let ((adaptive-wrap-extra-indent (+word-wrap--calc-extra-indent beg)))

View file

@ -1,4 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; editor/word-wrap/packages.el
(package! adaptive-wrap)
(package! adaptive-wrap :pin "1810c0ee8d")

View file

@ -6,3 +6,10 @@
(interactive)
(mapc #'kill-buffer (doom-buffers-in-mode 'dired-mode))
(message "Killed all dired buffers"))
;;;###autoload
(defun +dired-enable-git-info-h ()
"Enable `dired-git-info-mode' in git repos."
(and (not (file-remote-p default-directory))
(locate-dominating-file "." ".git")
(dired-git-info-mode 1)))

View file

@ -3,24 +3,25 @@
(use-package! dired
:commands dired-jump
:init
(setq ;; Always copy/delete recursively
(setq dired-auto-revert-buffer t ; don't prompt to revert; just do it
dired-dwim-target t ; suggest a target for moving/copying intelligently
dired-hide-details-hide-symlink-targets nil
;; Always copy/delete recursively
dired-recursive-copies 'always
dired-recursive-deletes 'top
;; Instantly revert Dired buffers on re-visiting them, with no message.
;; (A message is shown if insta-revert is either disabled or determined
;; dynamically by setting this variable to a function.)
dired-auto-revert-buffer t
;; Auto refresh dired, but be quiet about it
dired-hide-details-hide-symlink-targets nil
;; make dired suggest a target for moving/copying intelligently
dired-dwim-target t
;; files
;; Where to store image caches
image-dired-dir (concat doom-cache-dir "image-dired/")
image-dired-db-file (concat image-dired-dir "db.el")
image-dired-gallery-dir (concat image-dired-dir "gallery/")
image-dired-temp-image-file (concat image-dired-dir "temp-image")
image-dired-temp-rotate-image-file (concat image-dired-dir "temp-rotate-image"))
image-dired-temp-rotate-image-file (concat image-dired-dir "temp-rotate-image")
;; Screens are larger nowadays, we can afford slightly larger thumbnails
image-dired-thumb-size 150)
:config
(set-popup-rule! "^\\*image-dired"
:slot 20 :size 0.8 :select t :quit nil :ttl 0)
(set-evil-initial-state! 'image-dired-display-image-mode 'emacs)
(let ((args (list "-aBhl" "--group-directories-first")))
(when IS-BSD
;; Use GNU ls as `gls' from `coreutils' if available. Add `(setq
@ -64,7 +65,7 @@ only variant that supports --group-directories-first."
(use-package! diff-hl
:hook (dired-mode . diff-hl-dired-mode)
:hook (dired-mode . diff-hl-dired-mode-unless-remote)
:hook (magit-post-refresh . diff-hl-magit-post-refresh)
:config
;; use margin instead of fringe
@ -74,10 +75,7 @@ only variant that supports --group-directories-first."
(use-package! ranger
:when (featurep! +ranger)
:after dired
:init
;; set up image-dired to allow picture resize
(setq image-dired-dir (concat doom-cache-dir "image-dir")
ranger-override-dired t)
:init (setq ranger-override-dired t)
:config
(unless (file-directory-p image-dired-dir)
(make-directory image-dired-dir))
@ -161,10 +159,36 @@ we have to clean it up ourselves."
("\\.\\(?:mp4\\|mkv\\|avi\\|flv\\|rm\\|rmvb\\|ogv\\)\\(?:\\.part\\)?\\'" ,cmd)
("\\.\\(?:mp3\\|flac\\)\\'" ,cmd)
("\\.html?\\'" ,cmd)
("\\.md\\'" ,cmd)))))
("\\.md\\'" ,cmd))))
(map! :map dired-mode-map
:localleader
"h" #'dired-omit-mode))
(use-package! fd-dired
:when (executable-find doom-projectile-fd-binary)
:defer t
:init (advice-add #'find-dired :override #'fd-dired))
:init
(global-set-key [remap find-dired] #'fd-dired)
(set-popup-rule! "^\\*F\\(?:d\\|ind\\)\\*$" :ignore t))
;;;###package dired-git-info
(map! :after dired
:map (dired-mode-map ranger-mode-map)
:ng ")" #'dired-git-info-mode)
(after! wdired
;; Temporarily disable `dired-git-info-mode' when entering wdired, due to
;; reported incompatibilities.
(defvar +dired--git-info-p nil)
(defadvice! +dired--disable-git-info-a (&rest _)
:before #'wdired-change-to-wdired-mode
(setq +dired--git-info-p (bound-and-true-p dired-git-info-mode))
(when +dired--git-info-p
(dired-git-info-mode -1)))
(defadvice! +dired--reactivate-git-info-a (&rest _)
:after '(wdired-exit
wdired-abort-changes
wdired-finish-edit)
(when +dired--git-info-p
(dired-git-info-mode +1))))

View file

@ -1,11 +1,12 @@
;; -*- no-byte-compile: t; -*-
;;; emacs/dired/packages.el
(package! diredfl)
(package! diff-hl)
(package! dired-rsync)
(package! diredfl :pin "83567d00af")
(package! dired-git-info :pin "b47f2b0c3a")
(package! diff-hl :pin "fb9eb1cd3c")
(package! dired-rsync :pin "698294cbd4")
(when (featurep! +ranger)
(package! ranger))
(package! ranger :pin "af6f781a60"))
(when (featurep! +icons)
(package! all-the-icons-dired))
(package! fd-dired)
(package! all-the-icons-dired :pin "980b7747d6"))
(package! fd-dired :pin "fd4c3f490b")

View file

@ -39,8 +39,25 @@
:header-mouse-map ibuffer-size-header-map)
(file-size-human-readable (buffer-size)))
(when (featurep! :ui workspaces)
(define-ibuffer-filter workspace-buffers
"Filter for workspace buffers"
(:reader
(+workspace-get (read-string "workspace name: ")) :description "workspace")
(memq buf (+workspace-buffer-list qualifier)))
(defun +ibuffer/workspace (workspace-name)
"Open an ibuffer window for a workspace"
(ibuffer nil (format "%s buffers" workspace-name)
(list (cons 'workspace-buffers (+workspace-get workspace-name)))))
(defun +ibuffer-current-workspace ()
"Open an ibuffer window for the current workspace"
(interactive)
(+ibuffer/workspace (+workspace-current-name))))
(when (featurep! :completion ivy)
(defadvice! +ibuffer-use-counsel-maybe-a (file &optional wildcards)
(defadvice! +ibuffer-use-counsel-maybe-a (_file &optional _wildcards)
"Use `counsel-find-file' instead of `find-file'."
:override #'ibuffer-find-file
(interactive)

View file

@ -1,5 +1,5 @@
;; -*- no-byte-compile: t; -*-
;;; emacs/ibuffer/packages.el
(package! ibuffer-projectile)
(package! ibuffer-vc)
(package! ibuffer-projectile :pin "7649621414")
(package! ibuffer-vc :pin "64cb03887b")

View file

@ -1,8 +0,0 @@
;;; emacs/vc/autoload/evil.el -*- lexical-binding: t; -*-
;;;###if (featurep! :editor evil)
;;;###autoload (autoload '+vc:git-browse "emacs/vc/autoload/evil" nil t)
(evil-define-command +vc:git-browse (bang)
"Ex interface to `+vc/git-browse-region-or-line'."
(interactive "<!>")
(+vc/git-browse-region-or-line bang))

View file

@ -1,45 +1,34 @@
;;; emacs/vc/autoload/vc.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +vc-git-root-url ()
"Return the root git repo URL for the current file."
(require 'git-link)
(let* ((remote (git-link--select-remote))
(remote-url (git-link--remote-url remote))
(remote-info (if remote-url (git-link--parse-remote remote-url))))
(if remote-info
(format "https://%s/%s" (car remote-info) (cadr remote-info))
(error "Remote `%s' is unknown or contains an unsupported URL" remote))))
(defvar git-link-open-in-browser)
(defvar git-link-use-commit)
;;;###autoload
(defun +vc/git-browse-region-or-line (&optional arg)
"Open the website for the current line of this version controlled file.
Uses the currently checked out branch. If prefix ARG, then use 'master' branch.
If an url can't be ascertained, opens the repository's root."
(interactive "P")
(require 'git-link)
(let ((git-link-default-branch (if arg "master" git-link-default-branch))
current-prefix-arg ; don't propagate to `git-link'
git-link-use-commit)
(cl-destructuring-bind (beg end)
(if buffer-file-name (git-link--get-region))
(let ((git-link-open-in-browser t))
(git-link (git-link--select-remote) beg end)))))
(autoload 'browse-at-remote-get-url "browse-at-remote")
(autoload 'browse-at-remote--file-url "browse-at-remote")
;;;###autoload
(defun +vc-update-header-line-a (revision)
"Show revision details in the header-line, instead of the minibuffer.
(defun +vc/browse-at-remote-kill-file-or-region ()
"Copy the current file's remote URL to your clipboard.
If a selection is active, highlight them. Otherwise omits the #L<N> suffix in
the URL."
(interactive)
(let ((url (browse-at-remote-get-url)))
(kill-new url)
(message "Copied to clipboard: %S" url)))
Sometimes I forget `git-timemachine' is enabled in a buffer. Putting revision
info in the `header-line-format' is a good indication."
(let* ((date-relative (nth 3 revision))
(date-full (nth 4 revision))
(author (if git-timemachine-show-author (concat (nth 6 revision) ": ") ""))
(sha-or-subject (if (eq git-timemachine-minibuffer-detail 'commit) (car revision) (nth 5 revision))))
(setq header-line-format
(format "%s%s [%s (%s)]"
(propertize author 'face 'git-timemachine-minibuffer-author-face)
(propertize sha-or-subject 'face 'git-timemachine-minibuffer-detail-face)
date-full date-relative))))
(defun +vc--remote-homepage ()
(or (let ((url (browse-at-remote--remote-ref)))
(cdr (browse-at-remote--get-url-from-remote (car url))))
(user-error "Can't find homepage for current project")))
;;;###autoload
(defun +vc/browse-at-remote-homepage ()
"Open homepage for current project in browser."
(interactive)
(browse-url (+vc--remote-homepage)))
;;;###autoload
(defun +vc/browse-at-remote-kill-homepage ()
"Copy homepage URL of current project to clipboard."
(interactive)
(let ((url (+vc--remote-homepage)))
(kill-new url)
(message "Copied to clipboard: %S" url)))

View file

@ -4,11 +4,6 @@
(setenv "GIT_ASKPASS" "git-gui--askpass"))
;;;###package vc
(setq vc-make-backup-files nil
vc-follow-symlinks t)
(after! vc-annotate
(set-popup-rules!
'(("^\\vc-d" :select nil) ; *vc-diff*
@ -21,14 +16,27 @@
(define-key vc-annotate-mode-map [remap quit-window] #'kill-current-buffer))
(after! git-timemachine
;; Sometimes I forget `git-timemachine' is enabled in a buffer, so instead of
;; showing revision details in the minibuffer, show them in
;; `header-line-format', which has better visibility.
(setq git-timemachine-show-minibuffer-details t)
(advice-add #'git-timemachine--show-minibuffer-details
:override #'+vc-update-header-line-a)
(defadvice! +vc-update-header-line-a (revision)
"Show revision details in the header-line, instead of the minibuffer.
Sometimes I forget `git-timemachine' is enabled in a buffer. Putting revision
info in the `header-line-format' is a good indication."
:override #'git-timemachine--show-minibuffer-details
(let* ((date-relative (nth 3 revision))
(date-full (nth 4 revision))
(author (if git-timemachine-show-author (concat (nth 6 revision) ": ") ""))
(sha-or-subject (if (eq git-timemachine-minibuffer-detail 'commit) (car revision) (nth 5 revision))))
(setq header-line-format
(format "%s%s [%s (%s)]"
(propertize author 'face 'git-timemachine-minibuffer-author-face)
(propertize sha-or-subject 'face 'git-timemachine-minibuffer-detail-face)
date-full date-relative))))
(after! evil
;; rehash evil keybindings so they are recognized
@ -40,9 +48,6 @@
(map! :map git-timemachine-mode-map
:n "C-p" #'git-timemachine-show-previous-revision
:n "C-n" #'git-timemachine-show-next-revision
:n "[[" #'git-timemachine-show-previous-revision
:n "]]" #'git-timemachine-show-next-revision
:n "q" #'git-timemachine-quit
:n "gb" #'git-timemachine-blame
:n "gtc" #'git-timemachine-show-commit))
@ -60,9 +65,18 @@
(setq-hook! 'git-commit-mode-hook fill-column 72)
(add-hook! 'git-commit-setup-hook
(defun +vc-start-in-insert-state-maybe ()
(defun +vc-start-in-insert-state-maybe-h ()
"Start git-commit-mode in insert state if in a blank commit message,
otherwise in default state."
(when (and (bound-and-true-p evil-mode)
(bobp) (eolp))
(evil-insert-state)))))
;; HACK `browse-at-remote' produces urls with `nil' in them, when the repo
;; detached. This creates broken links. I think it is more sensible to at
;; least refer to master in those case.
(defadvice! +vc--fallback-to-master-branch-a ()
"Return 'master' in detached state."
:after-until #'browse-at-remote--get-local-branch
"master")

View file

@ -5,7 +5,7 @@
(package! vc-annotate :built-in t)
(package! smerge-mode :built-in t)
(package! git-link)
(package! git-timemachine)
(package! gitconfig-mode)
(package! gitignore-mode)
(package! browse-at-remote :pin "aeee6bf38f")
(package! git-timemachine :pin "391eb61050")
(package! gitconfig-mode :pin "55468314a5")
(package! gitignore-mode :pin "55468314a5")

View file

@ -43,19 +43,27 @@ This module requires:
** MacOS
#+BEGIN_SRC sh
brew install mu --with-emacs
brew install mu
# And one of the following
brew install isync # mbsync
brew install offlineimap
#+END_SRC
** Arch Linux
Run one of the following commands.
#+BEGIN_SRC sh
sudo pacman --noconfirm --needed -S mu
# And one of the following
sudo pacman -S isync # mbsync
sudo pacman -S offlineimap
#+END_SRC
Install ~mu~, which is not available in the main repositories but in the AUR, by
using for example the AUR helper ~yay~.
#+BEGIN_SRC sh
yay -S mu
#+END_SRC
** NixOS
#+BEGIN_SRC nix
environment.systemPackages = with pkgs; [
@ -69,11 +77,13 @@ environment.systemPackages = with pkgs; [
[[https://github.com/Emiller88/dotfiles/blob/master/modules/shell/mail.nix][An example of setting up mbsync with home-manager]]
** openSUSE
Remove ~#~ in ~#sync_program=offlineimap~ to choose ~offlineimap~ instead of
~mbsync~.
Remove ~#~ in ~#sync_program=offlineimap~ to choose ~offlineimap~ instead of ~mbsync~.
#+BEGIN_SRC sh :dir /sudo::
sync_program=isync # mbsync
#sync_program=offlineimap
sudo zypper install maildir-utils $sync_programm
#+END_SRC

View file

@ -44,6 +44,7 @@ default/fallback account."
(defvar +mu4e-workspace-name "*mu4e*"
"TODO")
(defvar +mu4e--old-wconf nil)
(add-hook 'mu4e-main-mode-hook #'+mu4e-init-h)
@ -52,7 +53,11 @@ default/fallback account."
"Start email client."
(interactive)
(require 'mu4e)
(+workspace-switch +mu4e-workspace-name t)
(if (featurep! :ui workspaces)
(+workspace-switch +mu4e-workspace-name t)
(setq +mu4e--old-wconf (current-window-configuration))
(delete-other-windows)
(switch-to-buffer (doom-fallback-buffer)))
(mu4e~start 'mu4e~main-view)
;; (save-selected-window
;; (prolusion-mail-show))
@ -74,5 +79,10 @@ default/fallback account."
(defun +mu4e-kill-mu4e-h ()
;; (prolusion-mail-hide)
(when (+workspace-exists-p +mu4e-workspace-name)
(+workspace/delete +mu4e-workspace-name)))
(cond
((and (featurep! :ui workspaces) (+workspace-exists-p +mu4e-workspace-name))
(+workspace/delete +mu4e-workspace-name))
(+mu4e--old-wconf
(set-window-configuration +mu4e--old-wconf)
(setq +mu4e--old-wconf nil))))

View file

@ -91,23 +91,12 @@
(defadvice! +mu4e--refresh-current-view-a (&rest _)
:after #'mu4e-mark-execute-all (mu4e-headers-rerun-search))
(when (featurep! :tools flyspell)
(add-hook 'mu4e-compose-mode-hook #'flyspell-mode))
;; Wrap text in messages
(setq-hook! 'mu4e-view-mode-hook truncate-lines nil)
(when (fboundp 'imagemagick-register-types)
(imagemagick-register-types))
(set-evil-initial-state!
'(mu4e-main-mode
mu4e-view-mode
mu4e-headers-mode
mu4e-compose-mode
mu4e~update-mail-mode)
'normal)
(map! :localleader
:map mu4e-compose-mode-map
:desc "send and exit" "s" #'message-send-and-exit
@ -166,9 +155,9 @@
:action #'+mu4e--mark-seen)
;; Refile will be my "archive" function.
(alist-get 'refile mu4e-marks)
(list :char '("d" . "")
:prompt "dtrash"
:dyn-target (lambda (_target msg) (mu4e-get-trash-folder msg))
(list :char '("r" . "")
:prompt "rrefile"
:dyn-target (lambda (_target msg) (mu4e-get-refile-folder msg))
:action #'+mu4e--mark-seen))
;; This hook correctly modifies gmail flags on emails when they are marked.

View file

@ -1,4 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; email/mu4e/packages.el
(package! mu4e-maildirs-extension)
(package! mu4e-maildirs-extension :pin "3ef4c48516")

View file

@ -11,6 +11,10 @@
(defvar +notmuch-mail-folder "~/.mail/account.gmail"
"Where your email folder is located (for use with gmailieer).")
;;
;;; Packages
(after! notmuch
(set-company-backend! 'notmuch-message-mode
'(notmuch-company :with company-ispell company-yasnippet))
@ -58,18 +62,17 @@
notmuch-search-mode-hook)
#'hide-mode-line-mode)
(map!
:localleader
:map (notmuch-search-mode-map notmuch-tree-mode-map notmuch-show-mode-map)
:desc "compose email" "c" #'+notmuch/compose
:desc "fetch new email" "u" #'+notmuch/update
:desc "quit notmuch" "q" #'+notmuch/quit
:map notmuch-search-mode-map
:desc "mark as deleted" "d" #'+notmuch/search-delete
:desc "mark as spam" "s" #'+notmuch/search-spam
:map notmuch-tree-mode-map
:desc "mark as deleted" "d" #'+notmuch/tree-delete
:desc "mark as spam" "s" #'+notmuch/tree-spam))
(map! :localleader
:map (notmuch-search-mode-map notmuch-tree-mode-map notmuch-show-mode-map)
:desc "Compose email" "c" #'+notmuch/compose
:desc "Fetch new email" "u" #'+notmuch/update
:desc "Quit notmuch" "q" #'+notmuch/quit
:map notmuch-search-mode-map
:desc "Mark as deleted" "d" #'+notmuch/search-delete
:desc "Mark as spam" "s" #'+notmuch/search-spam
:map notmuch-tree-mode-map
:desc "Mark as deleted" "d" #'+notmuch/tree-delete
:desc "Mark as spam" "s" #'+notmuch/tree-spam))
(use-package! org-mime
@ -82,6 +85,7 @@
:commands counsel-notmuch
:after notmuch)
(use-package! helm-notmuch
:when (featurep! :completion helm)
:commands helm-notmuch

View file

@ -1,9 +1,9 @@
;; -*- no-byte-compile: t; -*-
;;; email/notmuch/packages.el
(package! notmuch)
(package! org-mime)
(package! notmuch :pin "aba7fb375b")
(package! org-mime :pin "b189976217")
(when (featurep! :completion ivy)
(package! counsel-notmuch))
(package! counsel-notmuch :pin "a4a1562935"))
(when (featurep! :completion helm)
(package! helm-notmuch))
(package! helm-notmuch :pin "97a01497e0"))

Some files were not shown because too many files have changed in this diff Show more