mirror of
https://gitlab.com/dwt1/dotfiles.git
synced 2026-04-21 18:40:26 +10:00
Updating Doom Emacs.
This commit is contained in:
@@ -62,5 +62,5 @@ To control what org files ~clfw:org-create-source~ will use, ~let~-bind
|
||||
The [[https://github.com/kiwanami/emacs-calfw][kiwanami/emacs-calfw]] project readme contains more examples.
|
||||
|
||||
** Synchronizing Org and Google Calendar
|
||||
The [[https://github.com/myuhe/org-gcal.el][myuhe/org-gcal.el]] project README contains more detailed instructions on how
|
||||
The [[https://github.com/kidd/org-gcal.el][kidd/org-gcal.el]] project README contains more detailed instructions on how
|
||||
to link your calendar with Google calendars.
|
||||
|
||||
@@ -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)))
|
||||
|
||||
|
||||
@@ -42,10 +42,10 @@
|
||||
org-gcal-fetch
|
||||
org-gcal-post-at-point
|
||||
org-gcal-delete-at-point)
|
||||
:init
|
||||
(defvar org-gcal-dir (concat doom-cache-dir "org-gcal/"))
|
||||
(defvar org-gcal-token-file (concat org-gcal-dir "token.gpg"))
|
||||
:config
|
||||
;; hack to avoid the deferred.el error
|
||||
(defun org-gcal--notify (title mes)
|
||||
(message "org-gcal::%s - %s" title mes)))
|
||||
|
||||
|
||||
;; (use-package! alert)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; app/calendar/packages.el
|
||||
|
||||
(package! calfw)
|
||||
(package! calfw-org)
|
||||
(package! org-gcal)
|
||||
(package! calfw :pin "03abce97620a4a7f7ec5f911e669da9031ab9088")
|
||||
(package! calfw-org :pin "03abce97620a4a7f7ec5f911e669da9031ab9088")
|
||||
(package! org-gcal :pin "744505832b34e07b44a5d97d8720b2d7492d7fc9")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -3,15 +3,18 @@
|
||||
(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)))
|
||||
(require 'circe)
|
||||
(delete-other-windows)
|
||||
(switch-to-buffer (doom-fallback-buffer))
|
||||
t)))
|
||||
(if (not (member (window-buffer) buffers))
|
||||
(if buffers
|
||||
(ignore (switch-to-buffer (car buffers)))
|
||||
(require 'circe)
|
||||
(delete-other-windows)
|
||||
(switch-to-buffer (doom-fallback-buffer))
|
||||
t)
|
||||
(user-error "IRC buffer is already active and selected"))))
|
||||
|
||||
;;;###autoload
|
||||
(defun =irc (&optional inhibit-workspace)
|
||||
@@ -20,17 +23,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 +50,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 +92,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 +105,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
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -48,7 +48,6 @@ playback.")
|
||||
|
||||
(use-package! circe
|
||||
:commands circe circe-server-buffers
|
||||
:init (setq circe-network-defaults nil)
|
||||
:config
|
||||
(setq circe-default-quit-message nil
|
||||
circe-default-part-message nil
|
||||
@@ -93,6 +92,26 @@ 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)
|
||||
|
||||
;; HACK Fix #1862: circe hangs on TLS connections when using OpenSSL versions
|
||||
;; > 1.1.0, where tls.el does not correctly determine the end of the info
|
||||
;; block. This fixes proposed in jorgenschaefer/circe#340
|
||||
(setq-hook! 'circe-mode-hook
|
||||
tls-end-of-info
|
||||
(concat "\\("
|
||||
;; `openssl s_client' regexp. See ssl/ssl_txt.c lines 219-220.
|
||||
;; According to apps/s_client.c line 1515 `---' is always the last
|
||||
;; line that is printed by s_client before the real data.
|
||||
"^ Verify return code: .+\n\\(\\|^ Extended master secret: .+\n\\)\\(\\|^ Max Early Data: .+\n\\)---\n\\|"
|
||||
;; `gnutls' regexp. See src/cli.c lines 721-.
|
||||
"^- Simple Client Mode:\n"
|
||||
"\\(\n\\|" ; ignore blank lines
|
||||
;; According to GnuTLS v2.1.5 src/cli.c lines 640-650 and 705-715 in
|
||||
;; `main' the handshake will start after this message. If the
|
||||
;; handshake fails, the programs will abort.
|
||||
"^\\*\\*\\* Starting TLS handshake\n\\)*"
|
||||
"\\)"))
|
||||
|
||||
(defadvice! +irc--circe-run-disconnect-hook-a (&rest _)
|
||||
"Runs `+irc-disconnect-hook' after circe disconnects."
|
||||
@@ -175,7 +194,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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; app/irc/packages.el
|
||||
|
||||
(package! circe)
|
||||
(package! circe-notifications)
|
||||
(package! circe :pin "e5bf5f89741a9c43aa406491e94dd8d58c302fb4")
|
||||
(package! circe-notifications :pin "291149ac12877bbd062da993479d3533a26862b0")
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
;;; app/regex/autoload/export.el
|
||||
|
||||
;;;###autoload
|
||||
(defun +regex/export () (interactive)) ; TODO +regex/export
|
||||
|
||||
|
||||
;;
|
||||
(defun +regex-export-python ()) ; import (re|regex)
|
||||
|
||||
(defun +regex-export-php ()) ; preg_(match(_all)?|replace)
|
||||
|
||||
(defun +regex-export-ruby ()) ; %r[.+]
|
||||
|
||||
(defun +regex-export-js ()) ; /.+/
|
||||
@@ -1,272 +0,0 @@
|
||||
;;; app/regex/autoload/regex.el
|
||||
|
||||
(defvar +regex--text-buffer nil)
|
||||
(defvar +regex--text-replace-buffer nil)
|
||||
(defvar +regex--expr-buffer nil)
|
||||
(defvar +regex--expr-replace-buffer nil)
|
||||
(defvar +regex--groups-buffer nil)
|
||||
(defvar +regex--replace-buffer nil)
|
||||
|
||||
;;
|
||||
(defface +regex-match-0-face
|
||||
`((t (:foreground "Black" :background ,(doom-color 'magenta) :bold t)))
|
||||
"TODO"
|
||||
:group 'faces)
|
||||
|
||||
(defface +regex-match-1-face
|
||||
`((t (:foreground "Black" :background ,(doom-color 'blue) :bold t)))
|
||||
"TODO"
|
||||
:group 'faces)
|
||||
|
||||
(defface +regex-match-2-face
|
||||
`((t (:foreground "Black" :background ,(doom-color 'green) :bold t)))
|
||||
"TODO"
|
||||
:group 'faces)
|
||||
|
||||
(defvar +regex-faces
|
||||
'(+regex-match-0-face +regex-match-1-face +regex-match-2-face)
|
||||
"TODO")
|
||||
|
||||
;;
|
||||
(defvar +regex-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map "\C-c\C-c" #'+regex-update-buffers)
|
||||
(define-key map "\C-c\C-r" #'=regex/replace)
|
||||
(define-key map "\C-c\C-k" #'+regex/quit)
|
||||
(define-key map [remap kill-current-buffer] #'+regex/quit)
|
||||
(define-key map [remap kill-buffer] #'+regex/quit)
|
||||
map)
|
||||
"TODO")
|
||||
|
||||
;;;###autoload
|
||||
(define-minor-mode +regex-mode
|
||||
"TODO"
|
||||
:init-value nil
|
||||
:global nil
|
||||
:lighter ""
|
||||
:keymap +regex-mode-map
|
||||
(if +regex-mode
|
||||
(add-hook 'after-change-functions #'+regex-update-buffers nil t)
|
||||
(remove-hook 'after-change-functions #'+regex-update-buffers t)))
|
||||
|
||||
;;;###autoload
|
||||
(defun =regex (&optional dummy-text)
|
||||
"Start the Regex IDE."
|
||||
(interactive "P")
|
||||
(unless (buffer-live-p +regex--expr-buffer)
|
||||
(condition-case ex
|
||||
(progn
|
||||
(setq +regex--expr-buffer (get-buffer-create "*doom-regex*")
|
||||
+regex--text-buffer (if dummy-text (get-buffer-create "*doom-regex-text*") (current-buffer))
|
||||
+regex--groups-buffer (get-buffer-create "*doom-regex-groups*"))
|
||||
(when dummy-text
|
||||
(+workspace-switch +regex-workspace-name t)
|
||||
(switch-to-buffer +regex--text-buffer)
|
||||
(with-current-buffer +regex--text-buffer
|
||||
(insert +regex-dummy-text)))
|
||||
(pop-to-buffer +regex--groups-buffer)
|
||||
(pop-to-buffer +regex--expr-buffer)
|
||||
(with-current-buffer +regex--expr-buffer
|
||||
(conf-mode)
|
||||
(rainbow-delimiters-mode +1)
|
||||
(doom/toggle-line-numbers +1)
|
||||
(setq-local require-final-newline nil)
|
||||
(+regex-mode +1)
|
||||
(text-scale-set 3)))
|
||||
('error
|
||||
(+regex/quit)
|
||||
(error "Failed to open the Regexp IDE: %s" ex)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun =regex/replace ()
|
||||
(interactive)
|
||||
(unless (buffer-live-p +regex--replace-buffer)
|
||||
(let (text)
|
||||
(=regex t)
|
||||
(with-selected-window (get-buffer-window +regex--text-buffer)
|
||||
(setq text (buffer-string))
|
||||
(select-window (split-window-right))
|
||||
(switch-to-buffer (get-buffer-create "*doom-regex-text-repl*"))
|
||||
(erase-buffer)
|
||||
(insert text)
|
||||
(read-only-mode +1)
|
||||
(setq +regex--text-replace-buffer (current-buffer)))
|
||||
(with-current-buffer +regex--expr-buffer
|
||||
(select-window (split-window-right))
|
||||
(switch-to-buffer (get-buffer-create "*doom-regex-repl*"))
|
||||
(conf-mode)
|
||||
(rainbow-delimiters-mode +1)
|
||||
(doom/toggle-line-numbers -1)
|
||||
(setq-local require-final-newline nil)
|
||||
(setq mode-line-format nil
|
||||
+regex--expr-replace-buffer (current-buffer))
|
||||
(+regex-mode +1)
|
||||
(text-scale-set 3)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +regex/quit ()
|
||||
"TODO"
|
||||
(interactive)
|
||||
(when (and +regex--text-buffer (buffer-live-p +regex--text-buffer))
|
||||
(with-current-buffer +regex--text-buffer
|
||||
(+regex-mode -1)
|
||||
(remove-overlays nil nil 'category '+regex))
|
||||
(when (equal (buffer-name +regex--text-buffer) "*doom-regex-text*")
|
||||
(kill-buffer +regex--text-buffer)))
|
||||
(when (equal (+workspace-current-name) +regex-workspace-name)
|
||||
(+workspace/delete +regex-workspace-name))
|
||||
(mapc (lambda (bufname)
|
||||
(let ((buf (symbol-value bufname)))
|
||||
(when (and buf (buffer-live-p buf))
|
||||
(kill-buffer buf)
|
||||
(set bufname nil))))
|
||||
(list '+regex--text-replace-buffer
|
||||
'+regex--expr-replace-buffer
|
||||
'+regex--expr-buffer
|
||||
'+regex--groups-buffer
|
||||
'+regex--replace-buffer)))
|
||||
|
||||
(defun +regex--expr ()
|
||||
(when (buffer-live-p +regex--expr-buffer)
|
||||
(with-current-buffer +regex--expr-buffer
|
||||
(string-trim (buffer-string)))))
|
||||
|
||||
(defun +regex--expr-replace ()
|
||||
(when (buffer-live-p +regex--expr-replace-buffer)
|
||||
(with-current-buffer +regex--expr-replace-buffer
|
||||
(string-trim (buffer-string)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +regex-update-buffers (&optional beg end len)
|
||||
(interactive)
|
||||
(let* ((inhibit-read-only t)
|
||||
(regex (or (+regex--expr) ""))
|
||||
(replace (or (+regex--expr-replace) ""))
|
||||
(str (or (with-current-buffer +regex--text-buffer (buffer-string)) "")))
|
||||
(with-current-buffer +regex--groups-buffer
|
||||
(erase-buffer))
|
||||
(with-current-buffer +regex--text-buffer
|
||||
(remove-overlays nil nil 'category '+regex)
|
||||
(when (> (length regex) 0)
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(pcase +regex-default-backend
|
||||
('emacs (+regex-backend-emacs regex replace str))
|
||||
('perl (+regex-backend-perl regex replace str))))))
|
||||
(with-current-buffer +regex--groups-buffer
|
||||
(goto-char (point-min)))))
|
||||
|
||||
|
||||
;; --- backends ---------------------------
|
||||
|
||||
(defun +regex--render-perl (regex text)
|
||||
"From <https://github.com/jwiegley/regex-tool>"
|
||||
(with-temp-buffer
|
||||
(insert (format "@lines = <DATA>;
|
||||
$line = join(\"\", @lines);
|
||||
print \"(\";
|
||||
while ($line =~ m/%s/gm) {
|
||||
print \"(\", length($`), \" \", length($&), \" \";
|
||||
for $i (1 .. 20) {
|
||||
if ($$i) {
|
||||
my $group = $$i;
|
||||
$group =~ s/([\\\\\"])/\\\\\\1/g;
|
||||
print \"(\", $i, \" . \\\"\", $group, \"\\\") \";
|
||||
}
|
||||
}
|
||||
print \")\";
|
||||
}
|
||||
print \")\";
|
||||
__DATA__
|
||||
%s" (replace-regexp-in-string "/" "\\/" regex nil t) text))
|
||||
(call-process-region (point-min) (point-max) "perl" t t)
|
||||
(goto-char (point-min))
|
||||
(read (current-buffer))))
|
||||
|
||||
(defun +regex--replace-perl (regex replace text)
|
||||
(unless (or (string-empty-p regex)
|
||||
(string-empty-p replace)
|
||||
(string-empty-p text))
|
||||
(with-temp-buffer
|
||||
(insert (format "@lines = <DATA>;
|
||||
$line = join(\"\", @lines);
|
||||
$line =~ s/%s/%s/gm;
|
||||
print $line;
|
||||
__DATA__
|
||||
%s" (replace-regexp-in-string "/" "\\/" regex nil t) (replace-regexp-in-string "/" "\\/" replace nil t) text))
|
||||
(call-process-region (point-min) (point-max) "perl" t t)
|
||||
(buffer-string))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +regex-backend-perl (regex replace str)
|
||||
"TODO"
|
||||
(cl-assert (stringp regex))
|
||||
(cl-assert (stringp replace))
|
||||
(cl-assert (stringp str))
|
||||
(let ((i 0)
|
||||
(results (+regex--render-perl regex str)))
|
||||
(when (buffer-live-p +regex--text-replace-buffer)
|
||||
(let ((replace (+regex--replace-perl regex replace str)))
|
||||
(with-current-buffer +regex--text-replace-buffer
|
||||
(erase-buffer)
|
||||
(insert
|
||||
(if (and (listp results)
|
||||
replace
|
||||
(not (string-empty-p replace)))
|
||||
replace
|
||||
str)))))
|
||||
(dolist (result (if (listp results) results))
|
||||
(let* ((offset (nth 0 result))
|
||||
(length (nth 1 result))
|
||||
(matches (nthcdr 2 result))
|
||||
(ov (make-overlay (1+ offset) (+ offset length 1))))
|
||||
(overlay-put ov 'face (nth (mod i 3) +regex-faces))
|
||||
(overlay-put ov 'category '+regex)
|
||||
(cl-incf i)
|
||||
(let* ((match-zero (buffer-substring (1+ offset) (+ offset length 1)))
|
||||
(line (format "Match: %s\n" (propertize match-zero 'face 'font-lock-string-face))))
|
||||
(with-current-buffer +regex--groups-buffer
|
||||
(insert line)))
|
||||
(dolist (match matches)
|
||||
(with-current-buffer +regex--groups-buffer
|
||||
(goto-char (point-max))
|
||||
(insert (format "Group %d: %s\n"
|
||||
(propertize (car match) 'face 'font-lock-constant-face)
|
||||
(propertize (cdr match) 'face 'font-lock-string-face)))))
|
||||
(with-current-buffer +regex--groups-buffer
|
||||
(insert ?\n))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +regex-backend-emacs (regex replace str)
|
||||
"TODO"
|
||||
(cl-assert (stringp regex))
|
||||
(cl-assert (stringp replace))
|
||||
(cl-assert (stringp str))
|
||||
(let ((i 0)
|
||||
pos)
|
||||
(when (buffer-live-p +regex--text-replace-buffer)
|
||||
(with-current-buffer +regex--text-replace-buffer
|
||||
(erase-buffer)
|
||||
(insert str)
|
||||
(when (and (listp results) (string-empty-p replace))
|
||||
(replace-regexp regex replace))))
|
||||
(while (and (setq pos (point))
|
||||
(re-search-forward regex nil t))
|
||||
(if (= (point) pos)
|
||||
(forward-char 1)
|
||||
(let ((ov (make-overlay (match-beginning 0) (match-end 0))))
|
||||
(overlay-put ov 'face (nth (mod i 3) +regex-faces))
|
||||
(overlay-put ov 'category '+regex))
|
||||
(cl-incf i)
|
||||
(dotimes (i 10)
|
||||
(when-let (text (match-string i))
|
||||
(save-match-data
|
||||
(with-current-buffer +regex--groups-buffer
|
||||
(goto-char (point-max))
|
||||
(insert
|
||||
(format "Group %d: %s\n"
|
||||
(propertize i 'face 'font-lock-constant-face)
|
||||
(propertize text 'face 'font-lock-string-face)))))))
|
||||
(with-current-buffer +regex--groups-buffer
|
||||
(insert ?\n))))))
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
;;; app/regex/config.el
|
||||
|
||||
;; Often, I find myself writing regular expressions that could terrify seasoned
|
||||
;; programmers (or little children). To hone my regex fu, I need a regex
|
||||
;; playground. Sure, there's regexr.com, but don't be silly, that's not Emacs.
|
||||
;;
|
||||
;; Sadly, the Emacs' regex syntax is niche and lacks support for a few
|
||||
;; questionably useful features, like lookaround assertions, conditionals, case
|
||||
;; modifiers or backreferences, among others. No, I want PCRE. I am going to
|
||||
;; have my cake and eat it too, damn it!
|
||||
;;
|
||||
;; Workflow:
|
||||
;; + Invoke `=regex' (if opened with C-u, opens in separate workspace with a
|
||||
;; dummy text buffer).
|
||||
;; + A regex window will popup up. Any matches will be highlighted in the
|
||||
;; original buffer.
|
||||
;; + C-c C-k to close it
|
||||
;; + TODO C-c C-e to export to various langauges
|
||||
;;
|
||||
;; WARNING: THIS IS A WORK IN PROGRESS
|
||||
|
||||
(defvar +regex-workspace-name "*regex*"
|
||||
"TODO")
|
||||
|
||||
(defvar +regex-default-backend 'perl
|
||||
"The backend used to process regular expressions.
|
||||
The `emacs' backend handles regular expressions directly.
|
||||
The `perl' backend talks to a perl subprocess to do the handling.")
|
||||
|
||||
(defvar +regex-dummy-text
|
||||
"Welcome to DOOM Emacs, proudly hosted by the demons of hell!
|
||||
|
||||
Edit the Expression & Text to see matches. Roll over matches or the expression
|
||||
for details. Undo mistakes with ctrl-z. Save Favorites & Share expressions with
|
||||
friends or the Community. Explore your results with Tools. A full Reference &
|
||||
Help is available in the Library, or watch the video Tutorial.
|
||||
|
||||
Sample text for testing:
|
||||
abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
0123456789 _+-.,!@#$%^&*();\/|<>\"'
|
||||
12345 -98.7 3.141 .6180 9,000 +42
|
||||
555.123.4567 +1-(800)-555-2468
|
||||
foo@demo.net bar.ba@test.co.uk
|
||||
www.demo.com http://foo.co.uk/
|
||||
http://regexr.com/foo.html?q=bar
|
||||
https://mediatemple.net"
|
||||
"TODO")
|
||||
|
||||
(set-popup-rules!
|
||||
'(("^\\*doom-regex\\*$" :size 4 :quit nil)
|
||||
("^\\*doom-regex-groups" :side 'left :size 28 :select nil :quit nil)))
|
||||
@@ -70,7 +70,7 @@
|
||||
(let ((search-buffers (doom-buffers-in-mode 'elfeed-search-mode))
|
||||
(show-buffers (doom-buffers-in-mode 'elfeed-show-mode))
|
||||
kill-buffer-query-functions)
|
||||
(dolist (file +rss-elfeed-files)
|
||||
(dolist (file (bound-and-true-p rmh-elfeed-org-files))
|
||||
(when-let (buf (get-file-buffer (expand-file-name file org-directory)))
|
||||
(kill-buffer buf)))
|
||||
(dolist (b search-buffers)
|
||||
@@ -101,10 +101,9 @@
|
||||
;;;###autoload
|
||||
(defun +rss-put-sliced-image-fn (spec alt &optional flags)
|
||||
"TODO"
|
||||
(cl-letf (((symbol-function #'insert-image)
|
||||
(lambda (image &optional alt _area _slice)
|
||||
(let ((height (cdr (image-size image t))))
|
||||
(insert-sliced-image image alt nil (max 1 (/ height 20.0)) 1)))))
|
||||
(letf! (defun insert-image (image &optional alt _area _slice)
|
||||
(let ((height (cdr (image-size image t))))
|
||||
(insert-sliced-image image alt nil (max 1 (/ height 20.0)) 1)))
|
||||
(shr-put-image spec alt flags)))
|
||||
|
||||
;;;###autoload
|
||||
|
||||
@@ -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.")
|
||||
|
||||
@@ -21,10 +17,11 @@ easier to scroll through.")
|
||||
|
||||
(use-package! elfeed
|
||||
:commands elfeed
|
||||
:init
|
||||
(setq elfeed-db-directory (concat doom-local-dir "elfeed/db/")
|
||||
elfeed-enclosure-default-dir (concat doom-local-dir "elfeed/enclosures/"))
|
||||
:config
|
||||
(setq elfeed-search-filter "@2-week-ago "
|
||||
elfeed-db-directory (concat doom-local-dir "elfeed/db/")
|
||||
elfeed-enclosure-default-dir (concat doom-local-dir "elfeed/enclosures/")
|
||||
elfeed-show-entry-switch #'pop-to-buffer
|
||||
elfeed-show-entry-delete #'+rss/delete-pane
|
||||
shr-max-image-proportion 0.8)
|
||||
@@ -67,8 +64,11 @@ easier to scroll through.")
|
||||
(use-package! elfeed-org
|
||||
:when (featurep! +org)
|
||||
:after elfeed
|
||||
:preface
|
||||
(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)))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; app/rss/packages.el
|
||||
|
||||
(package! elfeed)
|
||||
(package! elfeed-org)
|
||||
(package! elfeed :pin "d0405e63863e54a01200740a6717ac875eceabc1")
|
||||
(package! elfeed-org :pin "77b6bbf222487809813de260447d31c4c59902c9")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; app/twitter/packages.el
|
||||
|
||||
(package! twittering-mode)
|
||||
(package! avy)
|
||||
(package! twittering-mode :pin "114891e8fdb4f06b1326a6cf795e49c205cf9e29")
|
||||
(package! avy :pin "509471bad0e8094b8639729ec39ca141fae7d4bd")
|
||||
|
||||
@@ -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~
|
||||
@@ -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-h ()
|
||||
"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-h ()
|
||||
(display-line-numbers-mode (if +write-mode +1 -1)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +write-init-mixed-pitch-h ()
|
||||
(mixed-pitch-mode (if +write-mode +1 -1)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +write-init-visual-fill-column-h ()
|
||||
(visual-fill-column-mode (if +write-mode +1 -1)))
|
||||
|
||||
;;;###autoload
|
||||
(add-hook! '+write-mode-hook
|
||||
#'(flyspell-mode
|
||||
visual-line-mode
|
||||
+write-init-mixed-pitch-h
|
||||
+write-init-visual-fill-column-h
|
||||
+write-init-line-numbers-h
|
||||
+write-init-org-mode-h))
|
||||
@@ -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))))
|
||||
@@ -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")))
|
||||
@@ -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)
|
||||
@@ -116,7 +116,7 @@ There is no guarantee your language mode will have completion support.
|
||||
|
||||
Some, like ~lua-mode~, don't have completion support in Emacs at all. Others may
|
||||
requires additional setup to get code completion working. For instance,
|
||||
~go-mode~ requires ~guru~ to be installed on your system, and ~enh-ruby-mode~
|
||||
~go-mode~ requires ~guru~ to be installed on your system, and ~ruby-mode~
|
||||
requires that you have a Robe server running (~M-x robe-start~).
|
||||
|
||||
Check the relevant module's documentation for this kind of information.
|
||||
|
||||
@@ -67,11 +67,10 @@ Examples:
|
||||
;;;###autoload
|
||||
(defun +company-init-backends-h ()
|
||||
"Set `company-backends' for the current buffer."
|
||||
(if (not company-mode)
|
||||
(remove-hook 'change-major-mode-after-body-hook #'+company-init-backends-h 'local)
|
||||
(unless (eq major-mode 'fundamental-mode)
|
||||
(setq-local company-backends (+company--backends)))
|
||||
(add-hook 'change-major-mode-after-body-hook #'+company-init-backends-h nil 'local)))
|
||||
(or (memq major-mode '(fundamental-mode special-mode))
|
||||
buffer-read-only
|
||||
(doom-temp-buffer-p (or (buffer-base-buffer) (current-buffer)))
|
||||
(setq-local company-backends (+company--backends))))
|
||||
|
||||
(put '+company-init-backends-h 'permanent-local-hook t)
|
||||
|
||||
|
||||
@@ -2,25 +2,49 @@
|
||||
|
||||
(use-package! company
|
||||
:commands company-complete-common company-manual-begin company-grab-line
|
||||
:after-call pre-command-hook after-find-file
|
||||
:hook (doom-first-input . global-company-mode)
|
||||
:init
|
||||
(setq company-minimum-prefix-length 2
|
||||
(setq company-idle-delay 0.25
|
||||
company-minimum-prefix-length 2
|
||||
company-tooltip-limit 14
|
||||
company-dabbrev-downcase nil
|
||||
company-dabbrev-ignore-case nil
|
||||
company-dabbrev-code-other-buffers t
|
||||
company-tooltip-align-annotations t
|
||||
company-require-match 'never
|
||||
company-global-modes
|
||||
'(not erc-mode message-mode help-mode gud-mode eshell-mode)
|
||||
company-backends '(company-capf)
|
||||
company-frontends
|
||||
'(company-pseudo-tooltip-frontend
|
||||
company-echo-metadata-frontend))
|
||||
'(not erc-mode message-mode help-mode gud-mode)
|
||||
company-frontends '(company-pseudo-tooltip-frontend
|
||||
company-echo-metadata-frontend)
|
||||
|
||||
;; Buffer-local backends will be computed when loading a major mode, so
|
||||
;; only specify a global default here.
|
||||
company-backends '(company-capf)
|
||||
|
||||
;; Company overrides `company-active-map' based on
|
||||
;; `company-auto-complete-chars'; no magic please!
|
||||
company-auto-complete-chars nil
|
||||
|
||||
;; Only search the current buffer for `company-dabbrev' (a backend that
|
||||
;; suggests text your open buffers). This prevents Company from causing
|
||||
;; lag once you have a lot of buffers open.
|
||||
company-dabbrev-other-buffers nil
|
||||
;; Make `company-dabbrev' fully case-sensitive, to improve UX with
|
||||
;; domain-specific words with particular casing.
|
||||
company-dabbrev-ignore-case nil
|
||||
company-dabbrev-downcase nil)
|
||||
|
||||
:config
|
||||
(when (featurep! :editor evil)
|
||||
(add-hook 'company-mode-hook #'evil-normalize-keymaps)
|
||||
|
||||
(unless (featurep! +childframe)
|
||||
;; Don't persist company popups when switching back to normal mode.
|
||||
;; `company-box' aborts on mode switch so it doesn't need this.
|
||||
(add-hook! 'evil-normal-state-entry-hook
|
||||
(defun +company-abort-h ()
|
||||
;; HACK `company-abort' doesn't no-op if company isn't active; causing
|
||||
;; unwanted side-effects, like the suppression of messages in the
|
||||
;; echo-area.
|
||||
;; REVIEW Revisit this to refactor; shouldn't be necessary!
|
||||
(when company-candidates
|
||||
(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'.
|
||||
@@ -28,8 +52,7 @@
|
||||
:before #'company-begin-backend
|
||||
(company-abort)))
|
||||
|
||||
(add-hook 'company-mode-hook #'+company-init-backends-h)
|
||||
(global-company-mode +1))
|
||||
(add-hook 'after-change-major-mode-hook #'+company-init-backends-h 'append))
|
||||
|
||||
|
||||
(use-package! company-tng
|
||||
@@ -49,8 +72,7 @@
|
||||
;; Packages
|
||||
|
||||
(after! company-files
|
||||
(pushnew! company-files--regexps
|
||||
"file:\\(\\(?:\\.\\{1,2\\}/\\|~/\\|/\\)[^\]\n]*\\)"))
|
||||
(add-to-list 'company-files--regexps "file:\\(\\(?:\\.\\{1,2\\}/\\|~/\\|/\\)[^\]\n]*\\)"))
|
||||
|
||||
|
||||
(use-package! company-prescient
|
||||
@@ -70,47 +92,44 @@
|
||||
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))))
|
||||
(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--yasnippet-fn (candidate)
|
||||
(when (get-text-property 0 'yas-annotation candidate)
|
||||
'Yasnippet))
|
||||
(delq! 'company-echo-metadata-frontend company-frontends)
|
||||
|
||||
(defun +company-box-icons--elisp-fn (candidate)
|
||||
(when (derived-mode-p 'emacs-lisp-mode)
|
||||
@@ -118,7 +137,14 @@
|
||||
(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
|
||||
(letf! ((#'display-buffer-in-side-window #'ignore))
|
||||
(apply orig-fn args))))
|
||||
|
||||
|
||||
(use-package! company-dict
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; completion/company/packages.el
|
||||
|
||||
(package! company)
|
||||
(package! company-dict)
|
||||
(package! company-prescient)
|
||||
(package! company :pin "6333fc4ebbbf4d28e834de8715561e984f149ecb")
|
||||
(package! company-dict :pin "cd7b8394f6014c57897f65d335d6b2bd65dab1f4")
|
||||
(package! company-prescient :pin "0f4a89bdec61395138d968a38d375e63ccfbed63")
|
||||
(when (featurep! +childframe)
|
||||
(package! company-box))
|
||||
(package! company-box :pin "3814fcb14e92f4b85b19e664e216a7c8d5c7144d"))
|
||||
|
||||
@@ -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
|
||||
@@ -52,10 +52,13 @@ workspace."
|
||||
(unless (executable-find "rg")
|
||||
(user-error "Couldn't find ripgrep in your PATH"))
|
||||
(require 'helm-rg)
|
||||
(let ((helm-rg-default-directory (or in (doom-project-root) default-directory))
|
||||
(let ((this-command 'helm-rg)
|
||||
(helm-rg-default-directory (or in (doom-project-root) default-directory))
|
||||
(helm-rg-default-extra-args
|
||||
(delq nil (list (when all-files "-z -uu")
|
||||
(unless recursive "--maxdepth 1")))))
|
||||
(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)))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -23,8 +23,7 @@ be negative.")
|
||||
;;; Packages
|
||||
|
||||
(use-package! helm-mode
|
||||
:defer t
|
||||
:after-call pre-command-hook
|
||||
:hook (doom-first-input . helm-mode)
|
||||
:init
|
||||
(map! [remap apropos] #'helm-apropos
|
||||
[remap find-library] #'helm-locate-library
|
||||
@@ -43,7 +42,6 @@ be negative.")
|
||||
[remap recentf-open-files] #'helm-recentf
|
||||
[remap yank-pop] #'helm-show-kill-ring)
|
||||
:config
|
||||
(helm-mode +1)
|
||||
;; helm is too heavy for `find-file-at-point'
|
||||
(add-to-list 'helm-completing-read-handlers-alist (cons #'find-file-at-point nil)))
|
||||
|
||||
@@ -57,8 +55,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,38 +69,37 @@ 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-apropos-fuzzy-match fuzzy
|
||||
helm-apropos-fuzzy-match fuzzy
|
||||
(setq helm-apropos-fuzzy-match fuzzy
|
||||
helm-bookmark-show-location fuzzy
|
||||
helm-buffers-fuzzy-matching fuzzy
|
||||
helm-completion-in-region-fuzzy-match fuzzy
|
||||
helm-completion-in-region-fuzzy-match fuzzy
|
||||
helm-ff-fuzzy-matching fuzzy
|
||||
helm-file-cache-fuzzy-match fuzzy
|
||||
helm-flx-for-helm-locate fuzzy
|
||||
helm-imenu-fuzzy-match fuzzy
|
||||
helm-lisp-fuzzy-completion fuzzy
|
||||
helm-locate-fuzzy-match fuzzy
|
||||
helm-mode-fuzzy-match fuzzy
|
||||
helm-projectile-fuzzy-match fuzzy
|
||||
helm-recentf-fuzzy-match fuzzy
|
||||
helm-semantic-fuzzy-match fuzzy))
|
||||
helm-semantic-fuzzy-match fuzzy)
|
||||
;; Make sure that we have helm-multi-matching or fuzzy matching,
|
||||
;; (as prescribed by the fuzzy flag) also in the following cases:
|
||||
;; - helmized commands that use `completion-at-point' and similar functions
|
||||
;; - native commands that fall back to `completion-styles' like `helm-M-x'
|
||||
(push (if EMACS27+
|
||||
(if fuzzy 'flex 'helm)
|
||||
(if fuzzy 'helm-flex 'helm))
|
||||
completion-styles))
|
||||
|
||||
:config
|
||||
(set-popup-rule! "^\\*helm" :vslot -100 :size 0.22 :ttl nil)
|
||||
|
||||
;; HACK Doom doesn't support these commands, which invite the user to install
|
||||
;; the package via ELPA. Force them to use +helm/* instead, because they work
|
||||
;; out of the box.
|
||||
(advice-add #'helm-projectile-rg :override #'+helm/project-search)
|
||||
(advice-add #'helm-projectile-ag :override #'+helm/project-search)
|
||||
(advice-add #'helm-projectile-grep :override #'+helm/project-search)
|
||||
|
||||
;; Hide the modeline
|
||||
;; Hide the modeline in helm windows as it serves little purpose.
|
||||
(defun +helm--hide-mode-line (&rest _)
|
||||
(with-current-buffer (helm-buffer-get)
|
||||
(unless helm-mode-line-string
|
||||
@@ -113,11 +108,13 @@ 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)))
|
||||
|
||||
|
||||
(use-package! helm-flx
|
||||
:when (featurep! +fuzzy)
|
||||
:hook (helm-mode . helm-flx-mode)
|
||||
@@ -131,7 +128,7 @@ be negative.")
|
||||
"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-c C-c" (cmd! (helm-rg--bounce-dump) (kill-current-buffer))
|
||||
"C-x C-c" #'helm-rg--bounce-dump-current-file
|
||||
"C-c C-k" #'kill-current-buffer))
|
||||
|
||||
@@ -183,3 +180,7 @@ be negative.")
|
||||
(lambda (buf &optional _resume) (pop-to-buffer buf)))
|
||||
(global-set-key [remap swiper] #'swiper-helm)
|
||||
(add-to-list 'swiper-font-lock-exclude #'+doom-dashboard-mode nil #'eq))
|
||||
|
||||
|
||||
(use-package! helm-descbinds
|
||||
:hook (helm-mode . helm-descbinds-mode))
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; completion/helm/packages.el
|
||||
|
||||
(package! helm)
|
||||
(package! helm-rg)
|
||||
(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 "b6db9fb47a8900704394e63b795f4a54cb4701a8")
|
||||
(package! helm-rg :pin "785a80fe5cc87e27c5ea3d00a70049028d9e2847")
|
||||
(package! helm-c-yasnippet :pin "65ca732b510bfc31636708aebcfe4d2d845b59b0")
|
||||
(package! helm-company :pin "6eb5c2d730a60e394e005b47c1db018697094dde")
|
||||
(package! helm-describe-modes
|
||||
:recipe (:host github :repo "emacs-helm/helm-describe-modes")
|
||||
:pin "11fb36af119b784539d31c6160002de1957408aa")
|
||||
(package! helm-projectile :pin "5328b74dddcee8d1913803ca8167868831a07463")
|
||||
(package! swiper-helm :pin "93fb6db87bc6a5967898b5fd3286954cc72a0008")
|
||||
(when (featurep! +fuzzy)
|
||||
(package! helm-flx))
|
||||
(package! helm-flx :pin "6640fac5cb16bee73c95b8ed1248a4e5e113690e"))
|
||||
(when (featurep! +childframe)
|
||||
(package! posframe))
|
||||
(package! posframe :pin "093b29a53cbeda6d637ccc9ef4dfc47123e79b9e"))
|
||||
(when (featurep! :lang org)
|
||||
(package! helm-org))
|
||||
(package! helm-org :pin "b7a18dfc17e8b933956d61d68c435eee03a96c24"))
|
||||
(package! helm-descbinds :pin "b72515982396b6e336ad7beb6767e95a80fca192")
|
||||
|
||||
@@ -1,59 +1,62 @@
|
||||
;;; completion/ido/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defun +ido-init-h ()
|
||||
(setq ido-ignore-buffers
|
||||
'("\\` " "^\\*ESS\\*" "^\\*Messages\\*" "^\\*Help\\*" "^\\*Buffer"
|
||||
"^\\*.*Completions\\*$" "^\\*Ediff" "^\\*tramp" "^\\*cvs-"
|
||||
"_region_" " output\\*$" "^TAGS$" "^\*Ido")
|
||||
ido-use-faces nil
|
||||
ido-confirm-unique-completion t
|
||||
ido-case-fold t
|
||||
ido-enable-tramp-completion nil
|
||||
ido-enable-flex-matching t
|
||||
ido-create-new-buffer 'always
|
||||
ido-enable-tramp-completion t
|
||||
ido-enable-last-directory-history t
|
||||
ido-save-directory-list-file (concat doom-cache-dir "ido.last"))
|
||||
(defvar ido-mode-hook nil
|
||||
"List of hooks to run when `ido-mode' is activated.")
|
||||
|
||||
(unless (member "\\`.DS_Store$" ido-ignore-files)
|
||||
(push "\\`.DS_Store$" ido-ignore-files)
|
||||
(push "Icon\\?$" ido-ignore-files))
|
||||
|
||||
(define-key! (ido-common-completion-map ido-completion-map ido-file-completion-map)
|
||||
"\C-n" #'ido-next-match
|
||||
"\C-p" #'ido-prev-match
|
||||
"\C-w" #'ido-delete-backward-word-updir
|
||||
;; Go to $HOME with ~
|
||||
"~" (λ! (if (looking-back "/" (point-min))
|
||||
(insert "~/")
|
||||
(call-interactively #'self-insert-command))))
|
||||
|
||||
(defadvice! +ido--sort-mtime-a ()
|
||||
"Sort ido filelist by mtime instead of alphabetically."
|
||||
:override #'ido-sort-mtime
|
||||
(setq ido-temp-list
|
||||
(sort ido-temp-list
|
||||
(lambda (a b)
|
||||
(time-less-p
|
||||
(sixth (file-attributes (concat ido-current-directory b)))
|
||||
(sixth (file-attributes (concat ido-current-directory a)))))))
|
||||
(ido-to-end ;; move . files to end (again)
|
||||
(cl-loop for x in ido-temp-list
|
||||
if (char-equal (string-to-char x) ?.)
|
||||
collect x)))
|
||||
(add-hook! '(ido-make-file-list-hook ido-make-dir-list-hook)
|
||||
#'ido-sort-mtime)
|
||||
|
||||
;;
|
||||
(ido-mode 1)
|
||||
(ido-everywhere 1)
|
||||
(ido-ubiquitous-mode 1)
|
||||
(ido-vertical-mode 1)
|
||||
(flx-ido-mode +1)
|
||||
(crm-custom-mode +1)
|
||||
|
||||
;;
|
||||
(remove-hook 'ido-setup-hook #'+ido-init-h))
|
||||
|
||||
;;
|
||||
(add-hook 'ido-setup-hook #'+ido-init-h)
|
||||
;;; Packages
|
||||
|
||||
(use-package! ido
|
||||
:hook (doom-first-input . ido-mode)
|
||||
:hook (ido-mode . ido-everywhere)
|
||||
:hook (ido-mode . ido-ubiquitous-mode)
|
||||
:preface
|
||||
;; HACK `ido' is a really old package. It defines `ido-mode' manually and
|
||||
;; doesn't define a hook, so we define one for it, so we can use it!
|
||||
(defadvice! +ido-run-hooks-a (&rest _)
|
||||
:after #'ido-mode
|
||||
(run-hooks 'ido-mode-hook))
|
||||
:init
|
||||
(setq ido-save-directory-list-file (concat doom-cache-dir "ido.last"))
|
||||
:config
|
||||
(pushnew! ido-ignore-files "\\`.DS_Store$" "Icon\\?$")
|
||||
(setq ido-ignore-buffers
|
||||
'("\\` " "^\\*ESS\\*" "^\\*Messages\\*" "^\\*[Hh]elp" "^\\*Buffer"
|
||||
"^\\*.*Completions\\*$" "^\\*Ediff" "^\\*tramp" "^\\*cvs-" "_region_"
|
||||
" output\\*$" "^TAGS$" "^\*Ido")
|
||||
ido-auto-merge-work-directories-length -1
|
||||
ido-confirm-unique-completion t
|
||||
ido-case-fold t
|
||||
ido-create-new-buffer 'always
|
||||
ido-enable-flex-matching t)
|
||||
|
||||
(map! :map (ido-common-completion-map ido-file-completion-map)
|
||||
"C-w" #'ido-delete-backward-word-updir
|
||||
:map (ido-common-completion-map ido-file-dir-completion-map)
|
||||
"C-n" #'ido-next-match
|
||||
"C-p" #'ido-prev-match
|
||||
[down] #'ido-next-match
|
||||
[up] #'ido-prev-match
|
||||
:map ido-file-completion-map
|
||||
;; Go to $HOME with ~
|
||||
"~" (cmd! (if (looking-back "/" (point-min))
|
||||
(insert "~/")
|
||||
(call-interactively #'self-insert-command)))))
|
||||
|
||||
|
||||
(use-package! ido-vertical-mode
|
||||
:hook (ido-mode . ido-vertical-mode)
|
||||
:config (setq ido-vertical-show-count t))
|
||||
|
||||
|
||||
(use-package! ido-sort-mtime
|
||||
:hook (ido-mode . ido-sort-mtime-mode))
|
||||
|
||||
|
||||
(use-package! crm-custom
|
||||
:hook (ido-mode . crm-custom-mode))
|
||||
|
||||
|
||||
(use-package! flx-ido
|
||||
:hook (ido-mode . flx-ido-mode))
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
;; -*- 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 "17f5c9cb2af18aa6f52910ff4a5a63591261ced5")
|
||||
(package! ido-completing-read+ :pin "98d3a6e56b1d3652da7b47f49f76d77f82ea80ba")
|
||||
(package! ido-sort-mtime :pin "f638ff0c922af862f5211779f2311a27fde428eb")
|
||||
(package! ido-vertical-mode :pin "16c4c1a112796ee0bcf401ea39d3e2643a89feaf")
|
||||
(package! crm-custom :pin "f1aaccf64306a5f99d9bf7ba815d7ea41c15518d")
|
||||
|
||||
@@ -136,7 +136,7 @@ These keybindings are available while a search is active:
|
||||
| =C-c C-o= | Open a buffer with your search results |
|
||||
| =C-c C-e= | Open a writable buffer of your search results |
|
||||
| =C-SPC= | Preview the current candidate |
|
||||
| =M-RET= | Open the selected candidate in other-window |
|
||||
| =C-RET= | Open the selected candidate in other-window |
|
||||
|
||||
Changes to the resulting wgrep buffer (opened by =C-c C-e=) can be committed
|
||||
with =C-c C-c= and aborted with =C-c C-k= (alternatively =ZZ= and =ZQ=, for evil
|
||||
|
||||
@@ -13,16 +13,6 @@
|
||||
(and (not (eq buffer (current-buffer)))
|
||||
(+workspace-contains-buffer-p buffer))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy-standard-search (str)
|
||||
"TODO"
|
||||
(funcall +ivy-standard-search-fn str))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy-alternative-search (str)
|
||||
"TODO"
|
||||
(funcall +ivy-alternative-search-fn str))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy-rich-buffer-name (candidate)
|
||||
"Display the buffer name.
|
||||
@@ -188,7 +178,7 @@ If ARG (universal argument), open selection in other-window."
|
||||
(user-error "%S doesn't support wgrep" caller)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy-yas-prompt (prompt choices &optional display-fn)
|
||||
(defun +ivy-yas-prompt-fn (prompt choices &optional display-fn)
|
||||
(yas-completing-prompt prompt choices display-fn #'ivy-completing-read))
|
||||
|
||||
;;;###autoload
|
||||
@@ -217,28 +207,33 @@ If ARG (universal argument), open selection in other-window."
|
||||
;;;###autoload
|
||||
(defun +ivy/projectile-find-file ()
|
||||
"A more sensible `counsel-projectile-find-file', which will revert to
|
||||
`counsel-find-file' if invoked from $HOME, `counsel-file-jump' if invoked from a
|
||||
non-project, `projectile-find-file' if in a big project (more than
|
||||
`counsel-find-file' if invoked from $HOME or /, `counsel-file-jump' if invoked
|
||||
from a non-project, `projectile-find-file' if in a big project (more than
|
||||
`ivy-sort-max-size' files), or `counsel-projectile-find-file' otherwise.
|
||||
|
||||
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 "~")
|
||||
(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
|
||||
@@ -252,36 +247,34 @@ 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)
|
||||
|
||||
@@ -14,33 +14,31 @@ When 'everything, also preview virtual buffers")
|
||||
"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.
|
||||
This uses the standard search algorithm ivy uses (or a variant of it).")
|
||||
|
||||
(defvar +ivy-alternative-search-fn
|
||||
(cond ((featurep! +prescient) #'ivy-prescient-re-builder)
|
||||
((featurep! +fuzzy) #'ivy--regex-fuzzy)
|
||||
;; Ignore order for non-fuzzy searches by default
|
||||
(#'ivy--regex-ignore-order))
|
||||
"Function to use for fuzzy search commands.
|
||||
This uses a search algorithm other than ivy's default.")
|
||||
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
|
||||
(use-package! ivy
|
||||
:after-call pre-command-hook
|
||||
:hook (doom-first-input . ivy-mode)
|
||||
:init
|
||||
(setq ivy-re-builders-alist
|
||||
`((counsel-rg . +ivy-standard-search)
|
||||
(swiper . +ivy-standard-search)
|
||||
(swiper-isearch . +ivy-standard-search)
|
||||
(t . +ivy-alternative-search)))
|
||||
(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
|
||||
@@ -90,7 +88,7 @@ This uses a search algorithm other than ivy's default.")
|
||||
(setq +ivy--origin nil)))
|
||||
|
||||
(after! yasnippet
|
||||
(add-hook 'yas-prompt-functions #'+ivy-yas-prompt))
|
||||
(add-hook 'yas-prompt-functions #'+ivy-yas-prompt-fn))
|
||||
|
||||
(defadvice! +ivy--inhibit-completion-in-region-a (orig-fn &rest args)
|
||||
"`ivy-completion-in-region' struggles with completing certain
|
||||
@@ -99,19 +97,11 @@ 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)
|
||||
|
||||
(ivy-mode +1)
|
||||
|
||||
(use-package! ivy-hydra
|
||||
:commands (ivy-dispatching-done ivy--matcher-desc ivy-hydra/body)
|
||||
:init
|
||||
(define-key! ivy-minibuffer-map
|
||||
"C-o" #'ivy-dispatching-done
|
||||
"M-o" #'hydra-ivy/body)
|
||||
:config
|
||||
;; ivy-hydra rebinds this, so we have to do so again
|
||||
(define-key ivy-minibuffer-map (kbd "M-o") #'hydra-ivy/body)))
|
||||
(define-key! ivy-minibuffer-map
|
||||
[remap doom/delete-backward-word] #'ivy-backward-kill-word
|
||||
"C-c C-e" #'+ivy/woccur
|
||||
"C-o" #'ivy-dispatching-done
|
||||
"M-o" #'hydra-ivy/body))
|
||||
|
||||
|
||||
(use-package! ivy-rich
|
||||
@@ -122,15 +112,27 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
|
||||
(when (featurep! +icons)
|
||||
(cl-pushnew '(+ivy-rich-buffer-icon)
|
||||
(cadr (plist-get ivy-rich-display-transformers-list
|
||||
'ivy-switch-buffer))))
|
||||
'ivy-switch-buffer))
|
||||
:test #'equal))
|
||||
|
||||
;; Include variable value in `counsel-describe-variable'
|
||||
;; Enahnce the appearance of a couple counsel commands
|
||||
(plist-put! ivy-rich-display-transformers-list
|
||||
'counsel-describe-variable
|
||||
'(:columns
|
||||
((counsel-describe-variable-transformer (:width 40)) ; the original transformer
|
||||
(+ivy-rich-describe-variable-transformer (:width 50))
|
||||
(ivy-rich-counsel-variable-docstring (:face font-lock-doc-face)))))
|
||||
(+ivy-rich-describe-variable-transformer (:width 50)) ; display variable value
|
||||
(ivy-rich-counsel-variable-docstring (:face font-lock-doc-face))))
|
||||
'counsel-M-x
|
||||
'(:columns
|
||||
((counsel-M-x-transformer (:width 60))
|
||||
(ivy-rich-counsel-function-docstring (:face font-lock-doc-face))))
|
||||
;; Apply switch buffer transformers to `counsel-projectile-switch-to-buffer' as well
|
||||
'counsel-projectile-switch-to-buffer
|
||||
(plist-get ivy-rich-display-transformers-list 'ivy-switch-buffer)
|
||||
'counsel-bookmark
|
||||
'(:columns
|
||||
((ivy-rich-candidate (:width 0.5))
|
||||
(ivy-rich-bookmark-filename (:width 60)))))
|
||||
|
||||
;; Remove built-in coloring of buffer list; we do our own
|
||||
(setq ivy-switch-buffer-faces-alist nil)
|
||||
@@ -138,15 +140,9 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
|
||||
|
||||
;; Highlight buffers differently based on whether they're in the same project
|
||||
;; as the current project or not.
|
||||
(let* ((plist (plist-get ivy-rich-display-transformers-list 'ivy-switch-buffer))
|
||||
(switch-buffer-alist (assq 'ivy-rich-candidate (plist-get plist :columns))))
|
||||
(when switch-buffer-alist
|
||||
(setcar switch-buffer-alist '+ivy-rich-buffer-name)))
|
||||
|
||||
;; Apply switch buffer transformers to `counsel-projectile-switch-to-buffer' as well
|
||||
(plist-put! ivy-rich-display-transformers-list
|
||||
'counsel-projectile-switch-to-buffer
|
||||
(plist-get ivy-rich-display-transformers-list 'ivy-switch-buffer))
|
||||
(when-let* ((plist (plist-get ivy-rich-display-transformers-list 'ivy-switch-buffer))
|
||||
(switch-buffer-alist (assq 'ivy-rich-candidate (plist-get plist :columns))))
|
||||
(setcar switch-buffer-alist '+ivy-rich-buffer-name))
|
||||
|
||||
(ivy-rich-mode +1))
|
||||
|
||||
@@ -161,9 +157,10 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
|
||||
|
||||
(all-the-icons-ivy-setup)
|
||||
(after! counsel-projectile
|
||||
(let ((all-the-icons-ivy-file-commands '(counsel-projectile
|
||||
counsel-projectile-find-file
|
||||
counsel-projectile-find-dir)))
|
||||
(let ((all-the-icons-ivy-file-commands
|
||||
'(counsel-projectile
|
||||
counsel-projectile-find-file
|
||||
counsel-projectile-find-dir)))
|
||||
(all-the-icons-ivy-setup))))
|
||||
|
||||
|
||||
@@ -173,62 +170,69 @@ 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-goto] #'counsel-org-goto
|
||||
[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))))))
|
||||
;; REVIEW Counsel allows `counsel-rg-base-command' to be a string or list.
|
||||
;; This backwards compatibility complicates things for Doom. Simpler to
|
||||
;; just force it to always be a list.
|
||||
(when (stringp counsel-rg-base-command)
|
||||
(setq counsel-rg-base-command (split-string counsel-rg-base-command)))
|
||||
|
||||
;; REVIEW Fix #3215: prevents mingw on Windows throwing an error trying to
|
||||
;; expand / to an absolute path. Remove this when it is fixed upstream
|
||||
;; in counsel.
|
||||
(when (and (memq system-type '(windows-nt ms-dos))
|
||||
(listp counsel-rg-base-command)
|
||||
(member "--path-separator" counsel-rg-base-command))
|
||||
(setf (cadr (member "--path-separator" counsel-rg-base-command))
|
||||
"//"))
|
||||
|
||||
;; 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)
|
||||
(add-hook 'counsel-grep-post-action-hook #'recenter)
|
||||
(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)
|
||||
@@ -236,33 +240,69 @@ 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, since it doesn't need
|
||||
;; any additional setup.
|
||||
;; `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)
|
||||
|
||||
;; Configure `counsel-find-file'
|
||||
;; `counsel-find-file'
|
||||
(setq counsel-find-file-ignore-regexp "\\(?:^[#.]\\)\\|\\(?:[#~]$\\)\\|\\(?:^Icon?\\)")
|
||||
(ivy-add-actions
|
||||
'counsel-find-file
|
||||
'(("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")))
|
||||
(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)
|
||||
(append (list doom-projectile-fd-binary
|
||||
"--color=never" "-E" ".git"
|
||||
"--type" "file" "--type" "symlink" "--follow")
|
||||
(if IS-WINDOWS '("--path-separator=/"))))
|
||||
((executable-find "rg")
|
||||
(append (list "rg" "--files" "--follow" "--color=never" "--hidden" "--no-messages")
|
||||
(cl-loop for dir in projectile-globally-ignored-directories
|
||||
collect "--glob"
|
||||
collect (concat "!" dir))
|
||||
(if IS-WINDOWS (list "--path-separator" "/"))))
|
||||
((cons find-program args)))
|
||||
(unless (listp args)
|
||||
(user-error "`counsel-file-jump-args' is a list now, please customize accordingly."))
|
||||
(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
|
||||
@@ -284,7 +324,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)
|
||||
|
||||
(when (featurep! +prescient)
|
||||
(setq counsel-projectile-sort-files t)))
|
||||
|
||||
|
||||
(use-package! wgrep
|
||||
@@ -311,7 +354,9 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
|
||||
;; posframe.
|
||||
(dolist (fn '(swiper counsel-rg counsel-grep counsel-git-grep))
|
||||
(setf (alist-get fn ivy-posframe-display-functions-alist)
|
||||
#'ivy-display-function-fallback)))
|
||||
#'ivy-display-function-fallback))
|
||||
|
||||
(add-hook 'doom-reload-hook #'posframe-delete-all))
|
||||
|
||||
|
||||
(use-package! flx
|
||||
@@ -322,24 +367,26 @@ evil-ex-specific constructs, so we disable it solely in evil-ex."
|
||||
|
||||
|
||||
(use-package! ivy-prescient
|
||||
:hook (ivy-mode . ivy-prescient-mode)
|
||||
:when (featurep! +prescient)
|
||||
:hook (ivy-mode . ivy-prescient-mode)
|
||||
:hook (ivy-prescient-mode . prescient-persist-mode)
|
||||
:init
|
||||
(setq prescient-filter-method
|
||||
(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)
|
||||
|
||||
'(literal regexp initialism)))
|
||||
:config
|
||||
(setq ivy-prescient-sort-commands
|
||||
'(:not swiper swiper-isearch ivy-switch-buffer counsel-grep
|
||||
counsel-git-grep counsel-ag counsel-rg counsel-imenu
|
||||
counsel-yank-pop counsel-recentf counsel-buffer-or-recentf)
|
||||
ivy-prescient-retain-classic-highlighting t)
|
||||
(defun +ivy-prescient-non-fuzzy (str)
|
||||
(let ((prescient-filter-method '(literal regexp)))
|
||||
(ivy-prescient-re-builder str)))
|
||||
|
||||
;; NOTE prescient config duplicated with `company'
|
||||
(setq prescient-save-file (concat doom-cache-dir "prescient-save.el"))
|
||||
(prescient-persist-mode +1))
|
||||
(setq prescient-save-file (concat doom-cache-dir "prescient-save.el")))
|
||||
|
||||
|
||||
;;;###package swiper
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; completion/ivy/packages.el
|
||||
|
||||
(package! amx)
|
||||
(package! swiper :pin "544e7de63a4543a74596c5d95efa0bb9da25791e")
|
||||
(package! ivy)
|
||||
(package! counsel)
|
||||
(package! counsel-projectile)
|
||||
(package! swiper)
|
||||
(package! ivy-hydra)
|
||||
(package! ivy-rich)
|
||||
(package! wgrep)
|
||||
(package! counsel)
|
||||
|
||||
(package! amx :pin "7fb7b874291e0cdeb1f0acb18564a686ec86788d")
|
||||
(package! counsel-projectile :pin "77392cbbc42e98fc137b43f1db1b111ba6e2dd75")
|
||||
(package! ivy-rich :pin "10970130b41c6ef9570893cdab8dfbe720e2b1a9")
|
||||
(package! wgrep :pin "f0ef9bfa44db503cdb2f83fcfbd2fa4e2382ef1f")
|
||||
|
||||
(if (featurep! +prescient)
|
||||
(package! ivy-prescient)
|
||||
(package! ivy-prescient :pin "3ab7605d997fb8337bf5ded2ad960b98ac0e1fd7")
|
||||
(when (featurep! +fuzzy)
|
||||
(package! flx)))
|
||||
(package! flx :pin "17f5c9cb2af18aa6f52910ff4a5a63591261ced5")))
|
||||
|
||||
(when (featurep! +childframe)
|
||||
(package! ivy-posframe))
|
||||
(package! ivy-posframe :pin "44749562a9e68bd43ccaa225b31311476fab1251"))
|
||||
|
||||
(when (featurep! +icons)
|
||||
(package! all-the-icons-ivy))
|
||||
(package! all-the-icons-ivy :pin "a70cbfa1effe36efc946a823a580cec686d5e88d"))
|
||||
|
||||
@@ -25,221 +25,390 @@
|
||||
(: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! :checkers syntax)
|
||||
:desc "List errors" "x" #'flycheck-list-errors)
|
||||
(:when (and (featurep! :tools lsp) (not (featurep! :tools lsp +eglot)))
|
||||
:desc "LSP Code actions" "a" #'lsp-execute-code-action
|
||||
:desc "LSP Organize imports" "i" #'lsp-organize-imports
|
||||
:desc "LSP Rename" "r" #'lsp-rename
|
||||
(:after lsp-mode
|
||||
:desc "LSP" "l" lsp-command-map)
|
||||
(: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))
|
||||
(:when (featurep! :tools lsp +eglot)
|
||||
:desc "LSP Execute code action" "a" #'eglot-code-actions
|
||||
:desc "LSP Format buffer/region" "F" #'eglot-format
|
||||
:desc "LSP Rename" "r" #'eglot-rename
|
||||
:desc "LSP Find declaration" "j" #'eglot-find-declaration
|
||||
:desc "LSP Find implementation" "J" #'eglot-find-implementation))
|
||||
|
||||
;;; <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 "Find file in private config" "C" #'doom/find-file-in-private-config
|
||||
:desc "Find directory" "d" #'dired
|
||||
: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 "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)
|
||||
(:when (featurep! :tools editorconfig)
|
||||
:desc "Open project editorconfig" "c" #'editorconfig-find-current-editorconfig)
|
||||
:desc "Copy this file" "C" #'doom/copy-this-file
|
||||
: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" "f" #'find-file
|
||||
:desc "Find file from here" "F" #'+default/find-file-under-here
|
||||
:desc "Locate file" "l" #'locate
|
||||
:desc "Rename/move this file" "m" #'doom/move-this-file
|
||||
:desc "Find file in 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" "u" #'doom/sudo-this-file
|
||||
:desc "Sudo find file" "U" #'doom/sudo-find-file
|
||||
:desc "Yank filename" "y" #'+default/yank-buffer-filename
|
||||
:desc "Open scratch buffer" "x" #'doom/open-scratch-buffer
|
||||
:desc "Switch to scratch buffer" "X" #'doom/switch-to-scratch-buffer)
|
||||
|
||||
;;; <leader> g --- lookup
|
||||
(:when (featurep! :tools lookup)
|
||||
(:prefix-map ("g" . "lookup")
|
||||
"k" #'+lookup/documentation
|
||||
"d" #'+lookup/definition
|
||||
"D" #'+lookup/references
|
||||
"f" #'+lookup/file
|
||||
"o" #'+lookup/online-select
|
||||
"i" #'+lookup/in-docsets
|
||||
"I" #'+lookup/in-all-docsets))
|
||||
;;; <leader> r --- remote
|
||||
(:when (featurep! :tools upload)
|
||||
(:prefix-map ("r" . "remote")
|
||||
:desc "Browse remote" "b" #'ssh-deploy-browse-remote-base-handler
|
||||
:desc "Browse relative" "B" #'ssh-deploy-browse-remote-handler
|
||||
:desc "Download remote" "d" #'ssh-deploy-download-handler
|
||||
:desc "Delete local & remote" "D" #'ssh-deploy-delete-handler
|
||||
:desc "Eshell base terminal" "e" #'ssh-deploy-remote-terminal-eshell-base-handler
|
||||
:desc "Eshell relative terminal" "E" #'ssh-deploy-remote-terminal-eshell-handler
|
||||
:desc "Move/rename local & remote" "m" #'ssh-deploy-rename-handler
|
||||
:desc "Open this file on remote" "o" #'ssh-deploy-open-remote-file-handler
|
||||
:desc "Run deploy script" "s" #'ssh-deploy-run-deploy-script-handler
|
||||
:desc "Upload local" "u" #'ssh-deploy-upload-handler
|
||||
:desc "Upload local (force)" "U" #'ssh-deploy-upload-handler-forced
|
||||
:desc "Diff local & remote" "x" #'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 project for symbol" "." #'+default/search-project-for-symbol-at-point
|
||||
: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" #'+lookup/file
|
||||
: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 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 "Search buffer" "s" #'swiper-isearch
|
||||
: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> i --- insert
|
||||
(:prefix-map ("i" . "insert")
|
||||
:desc "Current file name" "f" #'+default/insert-file-path
|
||||
:desc "Current file path" "F" (cmd!! #'+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
|
||||
(:when (featurep! :tools biblio)
|
||||
:desc "Bibliographic entries" "b"
|
||||
(cond ((featurep! :completion ivy) #'ivy-bibtex)
|
||||
((featurep! :completion helm) #'helm-bibtex)))
|
||||
|
||||
:desc "Toggle org-clock" "c" #'+org/toggle-clock
|
||||
:desc "Cancel org-clock" "C" #'org-clock-cancel
|
||||
:desc "Open deft" "d" #'deft
|
||||
(:when (featurep! :lang org +noter)
|
||||
:desc "Org noter" "e" #'org-noter)
|
||||
|
||||
:desc "Find file in notes" "f" #'+default/find-in-notes
|
||||
:desc "Browse notes" "F" #'+default/browse-notes
|
||||
:desc "Org store link" "l" #'org-store-link
|
||||
: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))
|
||||
(:when (featurep! :lang org +roam)
|
||||
(:prefix ("r" . "roam")
|
||||
:desc "Switch to buffer" "b" #'org-roam-switch-to-buffer
|
||||
:desc "Org Roam Capture" "c" #'org-roam-capture
|
||||
:desc "Find file" "f" #'org-roam-find-file
|
||||
:desc "Show graph" "g" #'org-roam-graph
|
||||
:desc "Insert" "i" #'org-roam-insert
|
||||
:desc "Org Roam" "r" #'org-roam
|
||||
(:prefix ("d" . "by date")
|
||||
:desc "Arbitrary date" "d" #'org-roam-dailies-date
|
||||
:desc "Today" "t" #'org-roam-dailies-today
|
||||
:desc "Tomorrow" "m" #'org-roam-dailies-tomorrow
|
||||
:desc "Yesterday" "y" #'org-roam-dailies-yesterday))))
|
||||
|
||||
;;; <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
|
||||
:desc "Open in iTerm" "i" #'+macos/open-in-iterm)
|
||||
(:when (featurep! :tools docker)
|
||||
:desc "Docker" "D" #'docker)
|
||||
(:when (featurep! :email mu4e)
|
||||
:desc "mu4e" "m" #'=mu4e)
|
||||
(:when (featurep! :email notmuch)
|
||||
:desc "notmuch" "m" #'=notmuch)
|
||||
(:when (featurep! :email wanderlust)
|
||||
:desc "wanderlust" "m" #'=wanderlust))
|
||||
|
||||
;;; <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> p --- project
|
||||
(:prefix ("p" . "project")
|
||||
:desc "Find file in other project" "F" #'doom/find-file-in-other-project
|
||||
:desc "Search project" "s" #'+default/search-project
|
||||
:desc "List project tasks" "t" #'magit-todos-list
|
||||
:desc "Open project scratch buffer" "x" #'doom/open-project-scratch-buffer
|
||||
:desc "Switch to project scratch buffer" "X" #'doom/switch-to-project-scratch-buffer
|
||||
;; later expanded by projectile
|
||||
(:prefix ("4" . "in other window"))
|
||||
(:prefix ("5" . "in other frame")))
|
||||
:desc "Search project for symbol" "." #'+default/search-project-for-symbol-at-point
|
||||
:desc "Find file in other project" "F" #'doom/find-file-in-other-project
|
||||
:desc "Search project" "s" #'+default/search-project
|
||||
:desc "List project todos" "t" #'magit-todos-list
|
||||
:desc "Open project scratch buffer" "x" #'doom/open-project-scratch-buffer
|
||||
:desc "Switch to project scratch buffer" "X" #'doom/switch-to-project-scratch-buffer
|
||||
(:when (and (featurep! :tools taskrunner)
|
||||
(or (featurep! :completion ivy)
|
||||
(featurep! :completion helm)))
|
||||
:desc "List project tasks" "z" #'+taskrunner/project-tasks)
|
||||
;; later expanded by projectile
|
||||
(:prefix ("4" . "in other window"))
|
||||
(:prefix ("5" . "in other frame")))
|
||||
|
||||
;;; <leader> q --- quit/restart
|
||||
(:prefix-map ("q" . "quit/restart")
|
||||
: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 "Restart & restore Emacs" "r" #'doom/restart-and-restore
|
||||
:desc "Restart Emacs" "R" #'doom/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
|
||||
: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)
|
||||
|
||||
;;; <leader> & --- snippets
|
||||
(:prefix-map ("&" . "snippets")
|
||||
:desc "New snippet" "n" #'yas-new-snippet
|
||||
:desc "Insert snippet" "i" #'yas-insert-snippet
|
||||
:desc "Find global snippet" "/" #'yas-visit-snippet-file
|
||||
:desc "Reload snippets" "r" #'yas-reload-all
|
||||
:desc "Create Temp Template" "c" #'aya-create
|
||||
:desc "Use Temp Template" "e" #'aya-expand)
|
||||
:desc "New snippet" "n" #'yas-new-snippet
|
||||
:desc "Insert snippet" "i" #'yas-insert-snippet
|
||||
:desc "Find global snippet" "/" #'yas-visit-snippet-file
|
||||
:desc "Reload snippets" "r" #'yas-reload-all
|
||||
: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! :checkers syntax)
|
||||
:desc "Flycheck" "f" #'flycheck-mode)
|
||||
(:when (featurep! :ui indent-guides)
|
||||
:desc "Indent guides" "i" #'highlight-indent-guides-mode)
|
||||
(:when (featurep! :ui minimap)
|
||||
:desc "Minimap mode" "m" #'minimap-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! :checkers spell)
|
||||
: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
|
||||
:desc "Git time machine" "t" #'git-timemachine-toggle
|
||||
:desc "Jump to next hunk" "n" #'git-gutter:next-hunk
|
||||
:desc "Jump to previous hunk" "p" #'git-gutter:previous-hunk)
|
||||
(:when (featurep! :tools magit)
|
||||
:desc "Magit dispatch" "/" #'magit-dispatch
|
||||
:desc "Forge dispatch" "'" #'forge-dispatch
|
||||
: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 fetch" "F" #'magit-fetch
|
||||
:desc "Magit buffer log" "L" #'magit-log
|
||||
:desc "Git stage file" "S" #'magit-stage-file
|
||||
:desc "Git unstage file" "U" #'magit-unstage-file
|
||||
(:prefix ("f" . "find")
|
||||
:desc "Find file" "f" #'magit-find-file
|
||||
:desc "Find gitconfig file" "g" #'magit-find-git-config-file
|
||||
:desc "Find commit" "c" #'magit-show-commit
|
||||
:desc "Find issue" "i" #'forge-visit-issue
|
||||
:desc "Find pull request" "p" #'forge-visit-pullreq)
|
||||
(:prefix ("o" . "open in browser")
|
||||
: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
|
||||
:desc "Browse a pull request" "p" #'forge-browse-pullreq
|
||||
:desc "Browse issues" "I" #'forge-browse-issues
|
||||
:desc "Browse pull requests" "P" #'forge-browse-pullreqs)
|
||||
(:prefix ("l" . "list")
|
||||
(:when (featurep! :tools gist)
|
||||
:desc "List gists" "g" #'+gist:list)
|
||||
:desc "List repositories" "r" #'magit-list-repositories
|
||||
:desc "List submodules" "s" #'magit-list-submodules
|
||||
:desc "List issues" "i" #'forge-list-issues
|
||||
:desc "List pull requests" "p" #'forge-list-pullreqs
|
||||
:desc "List notifications" "n" #'forge-list-notifications)
|
||||
(:prefix ("c" . "create")
|
||||
:desc "Initialize repo" "r" #'magit-init
|
||||
:desc "Clone repo" "R" #'magit-clone
|
||||
:desc "Commit" "c" #'magit-commit-create
|
||||
:desc "Fixup" "f" #'magit-commit-fixup
|
||||
:desc "Issue" "i" #'forge-create-issue
|
||||
:desc "Pull request" "p" #'forge-create-pullreq)))
|
||||
:desc "Git revert file" "R" #'vc-revert
|
||||
:desc "Kill link to remote" "y" #'browse-at-remote-kill
|
||||
: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
|
||||
:desc "Git time machine" "t" #'git-timemachine-toggle
|
||||
:desc "Jump to next hunk" "n" #'git-gutter:next-hunk
|
||||
:desc "Jump to previous hunk" "p" #'git-gutter:previous-hunk)
|
||||
(:when (featurep! :tools magit)
|
||||
:desc "Magit dispatch" "/" #'magit-dispatch
|
||||
:desc "Forge dispatch" "'" #'forge-dispatch
|
||||
:desc "Magit status" "g" #'magit-status
|
||||
:desc "Magit status here" "G" #'magit-status-here
|
||||
:desc "Magit file delete" "x" #'magit-file-delete
|
||||
:desc "Magit blame" "B" #'magit-blame-addition
|
||||
: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
|
||||
:desc "Git unstage file" "U" #'magit-unstage-file
|
||||
(:prefix ("f" . "find")
|
||||
:desc "Find file" "f" #'magit-find-file
|
||||
:desc "Find gitconfig file" "g" #'magit-find-git-config-file
|
||||
:desc "Find commit" "c" #'magit-show-commit
|
||||
:desc "Find issue" "i" #'forge-visit-issue
|
||||
:desc "Find pull request" "p" #'forge-visit-pullreq)
|
||||
(:prefix ("o" . "open in browser")
|
||||
:desc "Browse file or region" "." #'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
|
||||
:desc "Browse a pull request" "p" #'forge-browse-pullreq
|
||||
:desc "Browse issues" "I" #'forge-browse-issues
|
||||
:desc "Browse pull requests" "P" #'forge-browse-pullreqs)
|
||||
(:prefix ("l" . "list")
|
||||
(:when (featurep! :tools gist)
|
||||
:desc "List gists" "g" #'gist-list)
|
||||
:desc "List repositories" "r" #'magit-list-repositories
|
||||
:desc "List submodules" "s" #'magit-list-submodules
|
||||
:desc "List issues" "i" #'forge-list-issues
|
||||
:desc "List pull requests" "p" #'forge-list-pullreqs
|
||||
:desc "List notifications" "n" #'forge-list-notifications)
|
||||
(:prefix ("c" . "create")
|
||||
:desc "Initialize repo" "r" #'magit-init
|
||||
:desc "Clone repo" "R" #'magit-clone
|
||||
:desc "Commit" "c" #'magit-commit-create
|
||||
:desc "Fixup" "f" #'magit-commit-fixup
|
||||
:desc "Issue" "i" #'forge-create-issue
|
||||
:desc "Pull request" "p" #'forge-create-pullreq)))
|
||||
|
||||
;;; <leader> w --- workspaces/windows
|
||||
(:prefix-map ("w" . "workspaces/windows")
|
||||
:desc "Autosave session" "a" #'doom/quicksave-session
|
||||
:desc "Display workspaces" "d" #'+workspace/display
|
||||
:desc "Rename workspace" "r" #'+workspace/rename
|
||||
:desc "Create workspace" "c" #'+workspace/new
|
||||
:desc "Delete workspace" "k" #'+workspace/delete
|
||||
:desc "Save session" "s" #'doom/save-session
|
||||
:desc "Save workspace" "S" #'+workspace/save
|
||||
:desc "Load session" "l" #'doom/load-session
|
||||
:desc "Load last autosaved session" "L" #'doom/quickload-session
|
||||
:desc "Switch to other workspace" "o" #'+workspace/other
|
||||
:desc "Undo window config" "u" #'winner-undo
|
||||
:desc "Redo window config" "U" #'winner-redo
|
||||
:desc "Switch to left workspace" "p" #'+workspace/switch-left
|
||||
:desc "Switch to right workspace" "n" #'+workspace/switch-right
|
||||
:desc "Switch to" "w" #'+workspace/switch-to
|
||||
:desc "Switch to workspace 1" "1" #'+workspace/switch-to-0
|
||||
:desc "Switch to workspace 2" "2" #'+workspace/switch-to-1
|
||||
:desc "Switch to workspace 3" "3" #'+workspace/switch-to-2
|
||||
:desc "Switch to workspace 4" "4" #'+workspace/switch-to-3
|
||||
:desc "Switch to workspace 5" "5" #'+workspace/switch-to-4
|
||||
:desc "Switch to workspace 6" "6" #'+workspace/switch-to-5
|
||||
:desc "Switch to workspace 7" "7" #'+workspace/switch-to-6
|
||||
:desc "Switch to workspace 8" "8" #'+workspace/switch-to-7
|
||||
:desc "Switch to workspace 9" "9" #'+workspace/switch-to-8
|
||||
:desc "Switch to last workspace" "0" #'+workspace/switch-to-final)
|
||||
:desc "Autosave session" "a" #'doom/quicksave-session
|
||||
:desc "Display workspaces" "d" #'+workspace/display
|
||||
:desc "Rename workspace" "r" #'+workspace/rename
|
||||
:desc "Create workspace" "c" #'+workspace/new
|
||||
:desc "Delete workspace" "k" #'+workspace/delete
|
||||
:desc "Save session" "s" #'doom/save-session
|
||||
:desc "Save workspace" "S" #'+workspace/save
|
||||
:desc "Load session" "l" #'doom/load-session
|
||||
:desc "Load last autosaved session" "L" #'doom/quickload-session
|
||||
:desc "Switch to other workspace" "o" #'+workspace/other
|
||||
:desc "Undo window config" "u" #'winner-undo
|
||||
:desc "Redo window config" "U" #'winner-redo
|
||||
:desc "Switch to left workspace" "p" #'+workspace/switch-left
|
||||
:desc "Switch to right workspace" "n" #'+workspace/switch-right
|
||||
:desc "Switch to" "w" #'+workspace/switch-to
|
||||
:desc "Switch to workspace 1" "1" #'+workspace/switch-to-0
|
||||
:desc "Switch to workspace 2" "2" #'+workspace/switch-to-1
|
||||
:desc "Switch to workspace 3" "3" #'+workspace/switch-to-2
|
||||
:desc "Switch to workspace 4" "4" #'+workspace/switch-to-3
|
||||
:desc "Switch to workspace 5" "5" #'+workspace/switch-to-4
|
||||
:desc "Switch to workspace 6" "6" #'+workspace/switch-to-5
|
||||
:desc "Switch to workspace 7" "7" #'+workspace/switch-to-6
|
||||
:desc "Switch to workspace 8" "8" #'+workspace/switch-to-7
|
||||
:desc "Switch to workspace 9" "9" #'+workspace/switch-to-8
|
||||
:desc "Switch to last workspace" "0" #'+workspace/switch-to-final)
|
||||
|
||||
;;; <leader> m --- multiple cursors
|
||||
(:when (featurep! :editor multiple-cursors)
|
||||
(:prefix-map ("m" . "multiple cursors")
|
||||
:desc "Edit lines" "l" #'mc/edit-lines
|
||||
:desc "Mark next" "n" #'mc/mark-next-like-this
|
||||
:desc "Unmark next" "N" #'mc/unmark-next-like-this
|
||||
:desc "Mark previous" "p" #'mc/mark-previous-like-this
|
||||
:desc "Unmark previous" "P" #'mc/unmark-previous-like-this
|
||||
:desc "Mark all" "t" #'mc/mark-all-like-this
|
||||
:desc "Mark all DWIM" "m" #'mc/mark-all-like-this-dwim
|
||||
:desc "Edit line endings" "e" #'mc/edit-ends-of-lines
|
||||
:desc "Edit line starts" "a" #'mc/edit-beginnings-of-lines
|
||||
:desc "Mark tag" "s" #'mc/mark-sgml-tag-pair
|
||||
:desc "Mark in defun" "d" #'mc/mark-all-like-this-in-defun
|
||||
:desc "Add cursor w/mouse" "<mouse-1>" #'mc/add-cursor-on-click))
|
||||
(:prefix-map ("m" . "multiple-cursors")
|
||||
:desc "Edit lines" "l" #'mc/edit-lines
|
||||
:desc "Mark next" "n" #'mc/mark-next-like-this
|
||||
:desc "Unmark next" "N" #'mc/unmark-next-like-this
|
||||
:desc "Mark previous" "p" #'mc/mark-previous-like-this
|
||||
:desc "Unmark previous" "P" #'mc/unmark-previous-like-this
|
||||
:desc "Mark all" "t" #'mc/mark-all-like-this
|
||||
:desc "Mark all DWIM" "m" #'mc/mark-all-like-this-dwim
|
||||
:desc "Edit line endings" "e" #'mc/edit-ends-of-lines
|
||||
:desc "Edit line starts" "a" #'mc/edit-beginnings-of-lines
|
||||
:desc "Mark tag" "s" #'mc/mark-sgml-tag-pair
|
||||
:desc "Mark in defun" "d" #'mc/mark-all-like-this-in-defun
|
||||
:desc "Add cursor w/mouse" "<mouse-1>" #'mc/add-cursor-on-click))
|
||||
|
||||
;; APPs
|
||||
;;; <leader> M --- mu4e
|
||||
(:when (featurep! :email mu4e)
|
||||
(:prefix-map ("M" . "mu4e")
|
||||
:desc "Open email app" "M" #'=mu4e
|
||||
:desc "Compose email" "c" #'+mu4e/compose))
|
||||
(:prefix-map ("M" . "mu4e")
|
||||
:desc "Open email app" "M" #'=mu4e
|
||||
:desc "Compose email" "c" #'+mu4e/compose))
|
||||
|
||||
;;; <leader> I --- IRC
|
||||
(:when (featurep! :app irc)
|
||||
(:prefix-map ("I" . "irc")
|
||||
:desc "Open irc app" "I" #'=irc
|
||||
:desc "Next unread buffer" "a" #'tracking-next-buffer
|
||||
:desc "Quit irc" "q" #'+irc/quit
|
||||
:desc "Reconnect all" "r" #'circe-reconnect-all
|
||||
:desc "Send message" "s" #'+irc/send-message
|
||||
(:when (featurep! :completion ivy)
|
||||
:desc "Jump to channel" "j" #'irc/ivy-jump-to-channel)))
|
||||
(:prefix-map ("I" . "irc")
|
||||
:desc "Open irc app" "I" #'=irc
|
||||
:desc "Next unread buffer" "a" #'tracking-next-buffer
|
||||
:desc "Quit irc" "q" #'+irc/quit
|
||||
:desc "Reconnect all" "r" #'circe-reconnect-all
|
||||
:desc "Send message" "s" #'+irc/send-message
|
||||
(:when (featurep! :completion ivy)
|
||||
:desc "Jump to channel" "j" #'+irc/ivy-jump-to-channel)))
|
||||
|
||||
;;; <leader> T --- twitter
|
||||
(:when (featurep! :app twitter)
|
||||
(:prefix-map ("T" . "twitter")
|
||||
:desc "Open twitter app" "T" #'=twitter
|
||||
:desc "Quit twitter" "q" #'+twitter/quit
|
||||
:desc "Rerender twits" "r" #'+twitter/rerender-all
|
||||
:desc "Ace link" "l" #'+twitter/ace-link)))
|
||||
(:prefix-map ("T" . "twitter")
|
||||
:desc "Open twitter app" "T" #'=twitter
|
||||
:desc "Quit twitter" "q" #'+twitter/quit
|
||||
:desc "Rerender twits" "r" #'+twitter/rerender-all
|
||||
:desc "Ace link" "l" #'+twitter/ace-link)))
|
||||
|
||||
|
||||
;;
|
||||
@@ -250,7 +419,7 @@
|
||||
;;; Text scaling
|
||||
[C-mouse-4] #'text-scale-increase
|
||||
[C-mouse-5] #'text-scale-decrease
|
||||
[C-down-mouse-2] (λ! (text-scale-set 0))
|
||||
[C-down-mouse-2] (cmd! (text-scale-set 0))
|
||||
"M-+" #'doom/reset-font-size
|
||||
"M-=" #'doom/increase-font-size
|
||||
"M--" #'doom/decrease-font-size
|
||||
@@ -272,12 +441,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 C-b" #'ibuffer-list-buffers
|
||||
"C-x B" #'switch-to-buffer
|
||||
"C-x 4 B" #'switch-to-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
|
||||
"C-x K" #'doom/kill-this-buffer-in-all-windows
|
||||
|
||||
;;; company-mode
|
||||
@@ -291,14 +463,14 @@
|
||||
"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
|
||||
:map company-search-map
|
||||
"C-n" #'company-search-repeat-forward
|
||||
"C-p" #'company-search-repeat-backward
|
||||
"C-s" (λ! (company-search-abort) (company-filter-candidates)))
|
||||
"C-s" (cmd! (company-search-abort) (company-filter-candidates)))
|
||||
|
||||
;;; ein notebooks
|
||||
(:after ein:notebook-multilang
|
||||
@@ -319,22 +491,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)
|
||||
@@ -377,10 +549,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
|
||||
@@ -399,14 +567,4 @@
|
||||
;;; treemacs
|
||||
(:when (featurep! :ui treemacs)
|
||||
"<f9>" #'+treemacs/toggle
|
||||
"<C-f9>" #'+treemacs/find-file)
|
||||
|
||||
;;; yasnippet
|
||||
(:after yasnippet
|
||||
:map yas-keymap ; keymap while editing an inserted snippet
|
||||
"C-e" #'+snippets/goto-end-of-field
|
||||
"C-a" #'+snippets/goto-start-of-field
|
||||
"<S-tab>" #'yas-prev-field
|
||||
"<M-backspace>" #'+snippets/delete-to-start-of-field
|
||||
[backspace] #'+snippets/delete-backward-char
|
||||
[delete] #'+snippets/delete-forward-char-or-field))
|
||||
"<C-f9>" #'treemacs-find-file))
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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,275 +36,11 @@ 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)
|
||||
#'lsp-format-region
|
||||
#'lsp-format-buffer)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +default/restart-server ()
|
||||
"Restart the Emacs server."
|
||||
(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)))))
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
;;; config/default/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +default-want-RET-continue-comments t
|
||||
"If non-nil, RET will continue commented lines.")
|
||||
|
||||
(defvar +default-minibuffer-maps
|
||||
`(minibuffer-local-map
|
||||
minibuffer-local-ns-map
|
||||
minibuffer-local-completion-map
|
||||
minibuffer-local-must-match-map
|
||||
minibuffer-local-isearch-map
|
||||
read-expression-map
|
||||
,@(cond ((featurep! :completion ivy)
|
||||
'(ivy-minibuffer-map
|
||||
ivy-switch-buffer-map))
|
||||
((featurep! :completion helm)
|
||||
'(helm-map
|
||||
helm-ag-map
|
||||
helm-read-file-map))))
|
||||
(append '(minibuffer-local-map
|
||||
minibuffer-local-ns-map
|
||||
minibuffer-local-completion-map
|
||||
minibuffer-local-must-match-map
|
||||
minibuffer-local-isearch-map
|
||||
read-expression-map)
|
||||
(cond ((featurep! :completion ivy)
|
||||
'(ivy-minibuffer-map
|
||||
ivy-switch-buffer-map))
|
||||
((featurep! :completion helm)
|
||||
'(helm-map
|
||||
helm-ag-map
|
||||
helm-read-file-map))))
|
||||
"A list of all the keymaps used for the minibuffer.")
|
||||
|
||||
|
||||
@@ -23,20 +26,32 @@
|
||||
;;;###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.
|
||||
(set (if EMACS27+
|
||||
'epg-pinentry-mode
|
||||
'epa-pinentry-mode) ; DEPRECATED `epa-pinentry-mode'
|
||||
'loopback)
|
||||
;; Default to the first secret key available in your keyring.
|
||||
(setq-default
|
||||
epa-file-encrypt-to
|
||||
(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 +77,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 +86,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)))
|
||||
@@ -97,10 +107,13 @@
|
||||
(sp-local-pair sp-lisp-modes "(" ")" :unless '(:rem sp-point-before-same-p))
|
||||
|
||||
;; Major-mode specific fixes
|
||||
(sp-local-pair '(ruby-mode enh-ruby-mode) "{" "}"
|
||||
(sp-local-pair 'ruby-mode "{" "}"
|
||||
:pre-handlers '(:rem sp-ruby-pre-handler)
|
||||
:post-handlers '(:rem sp-ruby-post-handler))
|
||||
|
||||
;; Don't eagerly escape Swift style string interpolation
|
||||
(sp-local-pair 'swift-mode "\\(" ")" :when '(sp-in-string-p))
|
||||
|
||||
;; Don't do square-bracket space-expansion where it doesn't make sense to
|
||||
(sp-local-pair '(emacs-lisp-mode org-mode markdown-mode gfm-mode)
|
||||
"[" nil :post-handlers '(:rem ("| " "SPC")))
|
||||
@@ -114,9 +127,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))
|
||||
|
||||
@@ -176,7 +187,7 @@
|
||||
(sp-local-pair "(*" "*)" :actions nil)
|
||||
(sp-local-pair "(*" "*"
|
||||
:actions '(insert)
|
||||
:post-handlers '(("| " "SPC") ("|\n[i]*)[d-2]" "RET")))))
|
||||
:post-handlers '(("| " "SPC") ("|[i]*)[d-2]" "RET")))))
|
||||
|
||||
(after! smartparens-markdown
|
||||
(sp-with-modes '(markdown-mode gfm-mode)
|
||||
@@ -196,32 +207,52 @@
|
||||
|
||||
;; This keybind allows * to skip over **.
|
||||
(map! :map markdown-mode-map
|
||||
:ig "*" (λ! (if (looking-at-p "\\*\\* *$")
|
||||
(forward-char 2)
|
||||
(call-interactively 'self-insert-command)))))
|
||||
|
||||
;; Highjacks backspace to:
|
||||
;; a) balance spaces inside brackets/parentheses ( | ) -> (|)
|
||||
;; b) delete up to nearest column multiple of `tab-width' at a time
|
||||
;; c) close empty multiline brace blocks in one step:
|
||||
;; {
|
||||
;; |
|
||||
;; }
|
||||
;; becomes {|}
|
||||
;; d) refresh smartparens' :post-handlers, so SPC and RET expansions work
|
||||
;; even after a backspace.
|
||||
;; e) properly delete smartparen pairs when they are encountered, without
|
||||
;; the need for strict mode.
|
||||
;; f) do none of this when inside a string
|
||||
(advice-add #'delete-backward-char :override #'+default--delete-backward-char-a))
|
||||
|
||||
;; Makes `newline-and-indent' continue comments (and more reliably)
|
||||
(advice-add #'newline-and-indent :override #'+default--newline-indent-and-continue-comments-a))
|
||||
:ig "*" (general-predicate-dispatch nil
|
||||
(looking-at-p "\\*\\* *")
|
||||
(cmd! (forward-char 2)))))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Keybinding fixes
|
||||
|
||||
;; Highjacks backspace to delete up to nearest column multiple of `tab-width' at
|
||||
;; a time. If you have smartparens enabled, it will also:
|
||||
;; a) balance spaces inside brackets/parentheses ( | ) -> (|)
|
||||
;; b) close empty multiline brace blocks in one step:
|
||||
;; {
|
||||
;; |
|
||||
;; }
|
||||
;; becomes {|}
|
||||
;; c) refresh smartparens' :post-handlers, so SPC and RET expansions work even
|
||||
;; after a backspace.
|
||||
;; d) properly delete smartparen pairs when they are encountered, without the
|
||||
;; need for strict mode.
|
||||
;; e) do none of this when inside a string
|
||||
(advice-add #'delete-backward-char :override #'+default--delete-backward-char-a)
|
||||
|
||||
;; HACK Makes `newline-and-indent' continue comments (and more reliably).
|
||||
;; Consults `doom-point-in-comment-functions' to detect a commented region
|
||||
;; and uses that mode's `comment-line-break-function' to continue comments.
|
||||
;; If neither exists, it will fall back to the normal behavior of
|
||||
;; `newline-and-indent'.
|
||||
;;
|
||||
;; We use an advice here instead of a remapping because many modes define
|
||||
;; and remap to their own newline-and-indent commands, and tackling all
|
||||
;; those cases was judged to be more work than dealing with the edge cases
|
||||
;; on a case by case basis.
|
||||
(defadvice! +default--newline-indent-and-continue-comments-a (&rest _)
|
||||
"A replacement for `newline-and-indent'.
|
||||
|
||||
Continues comments if executed from a commented line. Consults
|
||||
`doom-point-in-comment-functions' to determine if in a comment."
|
||||
:before-until #'newline-and-indent
|
||||
(interactive "*")
|
||||
(when (and +default-want-RET-continue-comments
|
||||
(doom-point-in-comment-p)
|
||||
(fboundp comment-line-break-function))
|
||||
(funcall comment-line-break-function nil)
|
||||
t))
|
||||
|
||||
;; This section is dedicated to "fixing" certain keys so that they behave
|
||||
;; sensibly (and consistently with similar contexts).
|
||||
|
||||
@@ -252,6 +283,7 @@
|
||||
"s-c" (if (featurep 'evil) #'evil-yank #'copy-region-as-kill)
|
||||
"s-v" #'yank
|
||||
"s-s" #'save-buffer
|
||||
"s-x" #'execute-extended-command
|
||||
:v "s-x" #'kill-region
|
||||
;; Buffer-local font scaling
|
||||
"s-+" #'doom/reset-font-size
|
||||
@@ -259,7 +291,7 @@
|
||||
"s--" #'doom/decrease-font-size
|
||||
;; Conventional text-editing keys & motions
|
||||
"s-a" #'mark-whole-buffer
|
||||
"s-/" (λ! (save-excursion (comment-line 1)))
|
||||
"s-/" (cmd! (save-excursion (comment-line 1)))
|
||||
:n "s-/" #'evilnc-comment-or-uncomment-lines
|
||||
:v "s-/" #'evilnc-comment-operator
|
||||
:gi [s-backspace] #'doom/backward-kill-to-bol-and-indent
|
||||
@@ -278,6 +310,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
|
||||
@@ -313,25 +346,27 @@
|
||||
|
||||
;; replaces `apropos-documentation' b/c `apropos' covers this
|
||||
"d" nil
|
||||
"da" #'doom/help-autodefs
|
||||
"db" #'doom/report-bug
|
||||
"dd" #'doom/toggle-debug-mode
|
||||
"dc" #'doom/goto-private-config-file
|
||||
"dC" #'doom/goto-private-init-file
|
||||
"dd" #'doom-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/help-search
|
||||
"dx" #'doom/sandbox
|
||||
"dN" #'doom/help-search-news
|
||||
"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
|
||||
@@ -348,7 +383,7 @@
|
||||
"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
|
||||
@@ -372,10 +407,15 @@
|
||||
|
||||
;; A Doom convention where C-s on popups and interactive searches will invoke
|
||||
;; ivy/helm for their superior filtering.
|
||||
(define-key! :keymaps +default-minibuffer-maps
|
||||
"C-s" (if (featurep! :completion ivy)
|
||||
#'counsel-minibuffer-history
|
||||
#'helm-minibuffer-history))
|
||||
(when-let (command (cond ((featurep! :completion ivy)
|
||||
#'counsel-minibuffer-history)
|
||||
((featurep! :completion helm)
|
||||
#'helm-minibuffer-history)))
|
||||
(define-key!
|
||||
:keymaps (append +default-minibuffer-maps
|
||||
(when (featurep! :editor evil +everywhere)
|
||||
'(evil-ex-completion-map)))
|
||||
"C-s" command))
|
||||
|
||||
;; Smarter C-a/C-e for both Emacs and Evil. C-a will jump to indentation.
|
||||
;; Pressing it again will send you to the true bol. Same goes for C-e, except
|
||||
@@ -387,14 +427,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)))
|
||||
|
||||
|
||||
;;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; config/default/packages.el
|
||||
|
||||
(package! avy)
|
||||
(package! ace-link)
|
||||
(package! drag-stuff)
|
||||
(package! avy :pin "509471bad0e8094b8639729ec39ca141fae7d4bd")
|
||||
(package! drag-stuff :pin "6d06d846cd37c052d79acd0f372c13006aa7e7c8")
|
||||
(package! link-hint :pin "7440704cacb5c0fab35fff8ec59d30fbea17f44a")
|
||||
|
||||
(unless (featurep! :editor evil)
|
||||
(package! expand-region))
|
||||
(package! expand-region :pin "ea6b4cbb9985ddae532bd2faf9bb00570c9f2781"))
|
||||
|
||||
@@ -1,5 +1,42 @@
|
||||
;;; config/literate/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +literate-config-file
|
||||
(concat doom-private-dir "config.org")
|
||||
"The file path of your literate config file.")
|
||||
|
||||
(defvar +literate-config-cache-file
|
||||
(concat doom-cache-dir "literate-last-compile")
|
||||
"The file path that `+literate-config-file' will be tangled to, then
|
||||
byte-compiled from.")
|
||||
|
||||
;;;###autoload
|
||||
(defun +literate-tangle-h (&optional force-p)
|
||||
"Tangles `+literate-config-file' if it has changed."
|
||||
(let ((default-directory doom-private-dir))
|
||||
(when (or (file-newer-than-file-p +literate-config-file
|
||||
+literate-config-cache-file)
|
||||
force-p)
|
||||
(print! (start "Compiling your literate config..."))
|
||||
(print-group!
|
||||
(let* ((org (expand-file-name +literate-config-file))
|
||||
(dest (concat (file-name-sans-extension +literate-config-file) ".el"))
|
||||
(output (get-buffer-create "*org-tangle*")))
|
||||
(unwind-protect
|
||||
;; We tangle in a separate, blank process because loading it here
|
||||
;; would load all of :lang org (very expensive!).
|
||||
(and (require 'ob-tangle)
|
||||
(letf! (defun message (msg &rest args)
|
||||
(print! (info "%s") (apply #'format msg args)))
|
||||
(org-babel-tangle-file org dest))
|
||||
;; Write the cache file to serve as our mtime cache
|
||||
(with-temp-file +literate-config-cache-file))
|
||||
(kill-buffer output)))))))
|
||||
|
||||
;;;###autoload
|
||||
(after! org
|
||||
;; Recompile our literate config if we modify it
|
||||
(add-hook 'after-save-hook #'+literate-recompile-maybe-h))
|
||||
|
||||
;;;###autoload
|
||||
(defalias '+literate/reload #'doom/reload)
|
||||
|
||||
@@ -11,4 +48,4 @@ We assume any org file in `doom-private-dir' is connected to your literate
|
||||
config, and should trigger a recompile if changed."
|
||||
(when (and (eq major-mode 'org-mode)
|
||||
(file-in-directory-p buffer-file-name doom-private-dir))
|
||||
(+literate-tangle 'force)))
|
||||
(+literate-tangle-h 'force)))
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
;;; config/literate/init.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +literate-config-file
|
||||
(concat doom-private-dir "config.org")
|
||||
"The file path of your literate config file.")
|
||||
|
||||
(defvar +literate-config-cache-file
|
||||
(concat doom-cache-dir "literate-last-compile")
|
||||
"The file path that `+literate-config-file' will be tangled to, then
|
||||
byte-compiled from.")
|
||||
|
||||
|
||||
;;
|
||||
(defun +literate-tangle (&optional force-p)
|
||||
"Tangles `+literate-config-file' if it has changed."
|
||||
(let ((default-directory doom-private-dir))
|
||||
(when (or (file-newer-than-file-p +literate-config-file
|
||||
+literate-config-cache-file)
|
||||
force-p)
|
||||
(message "Compiling your literate config...")
|
||||
(let* ((org (expand-file-name +literate-config-file))
|
||||
(dest (concat (file-name-sans-extension +literate-config-file) ".el"))
|
||||
(output (get-buffer-create "*org-tangle*")))
|
||||
(unwind-protect
|
||||
;; We tangle in a separate, blank process because loading it here
|
||||
;; would load all of :lang org (very expensive!).
|
||||
(or (and (zerop (call-process
|
||||
"emacs" nil output nil
|
||||
"-q" "--batch"
|
||||
"-l" "ob-tangle"
|
||||
"--eval" (format "(org-babel-tangle-file %S %S)"
|
||||
org dest)))
|
||||
(with-current-buffer output
|
||||
(message "%s" (buffer-string))
|
||||
t)
|
||||
;; Write the cache file to serve as our mtime cache
|
||||
(with-temp-file +literate-config-cache-file
|
||||
(message "Done!")))
|
||||
(warn "There was a problem tangling your literate config!"))
|
||||
(kill-buffer output))))))
|
||||
|
||||
|
||||
;; Let 'er rip!
|
||||
(+literate-tangle (or doom-reloading-p noninteractive))
|
||||
;; No need to load the resulting file. Doom will do this for us after all
|
||||
;; modules have finished loading.
|
||||
|
||||
|
||||
;; Recompile our literate config if we modify it
|
||||
(after! org
|
||||
(add-hook 'after-save-hook #'+literate-recompile-maybe-h))
|
||||
@@ -28,14 +28,12 @@
|
||||
|
||||
;; TODO (evil-ex-define-cmd "rx" 'doom:regex) ; open re-builder
|
||||
(evil-ex-define-cmd "sh[ell]" #'+eshell:run)
|
||||
(evil-ex-define-cmd "t[mux]" #'+tmux:run) ; send to tmux
|
||||
(evil-ex-define-cmd "tcd" #'+tmux:cd-here) ; cd to default-directory in tmux
|
||||
(evil-ex-define-cmd "pad" #'+evil:open-scratch-buffer)
|
||||
|
||||
;;; 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)
|
||||
@@ -49,9 +47,9 @@
|
||||
(evil-ex-define-cmd "k[ill]m" #'+evil:kill-matching-buffers)
|
||||
(evil-ex-define-cmd "k[ill]o" #'doom/kill-other-buffers)
|
||||
(evil-ex-define-cmd "k[ill]b" #'doom/kill-buried-buffers)
|
||||
(evil-ex-define-cmd "l[ast]" #'doom/popup-restore)
|
||||
(evil-ex-define-cmd "l[ast]" #'+popup/restore)
|
||||
(evil-ex-define-cmd "messages" #'view-echo-area-messages)
|
||||
(evil-ex-define-cmd "pop[up]" #'doom/popup-this-buffer)
|
||||
(evil-ex-define-cmd "pop[up]" #'+popup/buffer)
|
||||
|
||||
;;; Project navigation
|
||||
(evil-ex-define-cmd "a" #'projectile-find-other-file)
|
||||
@@ -73,8 +71,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)
|
||||
|
||||
@@ -99,4 +98,8 @@
|
||||
(evil-ex-define-cmd "tabsave" #'+workspace:save)
|
||||
|
||||
;;; Org-mode
|
||||
(evil-ex-define-cmd "cap" #'org-capture)
|
||||
(evil-ex-define-cmd "cap[ture]" #'org-capture)
|
||||
|
||||
;;; ibuffer
|
||||
(when (featurep! :emacs ibuffer)
|
||||
(evil-ex-define-cmd "buffers" #'ibuffer))
|
||||
|
||||
@@ -1,238 +0,0 @@
|
||||
;;; editor/evil/+everywhere.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; We load evil-collection ourselves for these reasons:
|
||||
;;
|
||||
;; 1. To truly lazy load it. Some of its modules, like
|
||||
;; evil-collection-{elisp-mode,buff-menu} are loaded immediately, because
|
||||
;; Emacs loads their packages immediately, which pulls in all of
|
||||
;; evil-collection (and other packages with it, sometimes).
|
||||
;; 2. This ensures a predictable load order, versus lazy loading using :defer or
|
||||
;; :after-call. This means users can use (after! org ...) and be sure that
|
||||
;; 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.
|
||||
;; 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).
|
||||
|
||||
(defvar +evil-collection-disabled-list
|
||||
'(anaconda-mode
|
||||
buff-menu
|
||||
comint
|
||||
company
|
||||
custom
|
||||
eldoc
|
||||
elisp-mode
|
||||
ert
|
||||
free-keys
|
||||
help
|
||||
helm
|
||||
image
|
||||
kotlin-mode
|
||||
occur
|
||||
package-menu
|
||||
ruby-mode
|
||||
simple
|
||||
slime)
|
||||
"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.")
|
||||
|
||||
(defvar evil-collection-setup-minibuffer nil)
|
||||
|
||||
;; We do this ourselves, and better.
|
||||
(defvar evil-collection-want-unimpaired-p 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:
|
||||
;;
|
||||
;; (with-current-buffer
|
||||
;; (url-retrieve-synchronously "https://raw.githubusercontent.com/emacs-evil/evil-collection/master/evil-collection.el" t t)
|
||||
;; (goto-char (point-min))
|
||||
;; (when (re-search-forward "^(defvar evil-collection--supported-modes\n[^(]+")
|
||||
;; (let ((list (sexp-at-point)))
|
||||
;; ;; Fixes
|
||||
;; (when (assq 'pdf list)
|
||||
;; (setf (alist-get 'pdf list) '(pdf-tools)))
|
||||
;; (kill-new (prin1-to-string list)))))
|
||||
|
||||
(defvar evil-collection-mode-list
|
||||
`(2048-game
|
||||
ag
|
||||
alchemist
|
||||
anaconda-mode
|
||||
apropos
|
||||
arc-mode
|
||||
bookmark
|
||||
(buff-menu "buff-menu")
|
||||
calc
|
||||
calendar
|
||||
cider
|
||||
cmake-mode
|
||||
comint
|
||||
company
|
||||
compile
|
||||
(custom cus-edit)
|
||||
cus-theme
|
||||
daemons
|
||||
deadgrep
|
||||
debbugs
|
||||
debug
|
||||
diff-mode
|
||||
dired
|
||||
disk-usage
|
||||
doc-view
|
||||
docker
|
||||
ebib
|
||||
edbi
|
||||
edebug
|
||||
ediff
|
||||
eglot
|
||||
elfeed
|
||||
elisp-mode
|
||||
elisp-refs
|
||||
elisp-slime-nav
|
||||
emms
|
||||
epa
|
||||
ert
|
||||
eshell
|
||||
eval-sexp-fu
|
||||
evil-mc
|
||||
eww
|
||||
flycheck
|
||||
flymake
|
||||
free-keys
|
||||
geiser
|
||||
ggtags
|
||||
git-timemachine
|
||||
go-mode
|
||||
grep
|
||||
guix
|
||||
hackernews
|
||||
helm
|
||||
help
|
||||
helpful
|
||||
hg-histedit
|
||||
hungry-delete
|
||||
ibuffer
|
||||
image
|
||||
image-dired
|
||||
image+
|
||||
imenu-list
|
||||
indium
|
||||
info
|
||||
ivy
|
||||
js2-mode
|
||||
leetcode
|
||||
log-edit
|
||||
log-view
|
||||
lsp-ui-imenu
|
||||
lua-mode
|
||||
kotlin-mode
|
||||
macrostep
|
||||
man
|
||||
magit
|
||||
magit-todos
|
||||
,@(if evil-collection-setup-minibuffer '(minibuffer))
|
||||
monky
|
||||
mu4e
|
||||
mu4e-conversation
|
||||
neotree
|
||||
notmuch
|
||||
nov
|
||||
(occur replace)
|
||||
omnisharp
|
||||
outline
|
||||
p4
|
||||
(package-menu package)
|
||||
pass
|
||||
(pdf pdf-tools)
|
||||
popup
|
||||
proced
|
||||
process-menu
|
||||
prodigy
|
||||
profiler
|
||||
python
|
||||
quickrun
|
||||
racer
|
||||
realgud
|
||||
reftex
|
||||
restclient
|
||||
rjsx-mode
|
||||
robe
|
||||
rtags
|
||||
ruby-mode
|
||||
simple
|
||||
slime
|
||||
sly
|
||||
tablist
|
||||
(term term ansi-term multi-term)
|
||||
tetris
|
||||
tide
|
||||
transmission
|
||||
typescript-mode
|
||||
vc-annotate
|
||||
vc-dir
|
||||
vc-git
|
||||
vdiff
|
||||
view
|
||||
vlf
|
||||
vterm
|
||||
w3m
|
||||
wdired
|
||||
wgrep
|
||||
which-key
|
||||
woman
|
||||
xref
|
||||
youtube-dl
|
||||
(ztree ztree-diff)))
|
||||
|
||||
(defun +evil-collection-init (module &optional disabled-list)
|
||||
"Initialize evil-collection-MODULE.
|
||||
|
||||
Unlike `evil-collection-init', this respects `+evil-collection-disabled-list',
|
||||
and complains if a module is loaded too early (during startup)."
|
||||
(unless (memq (or (car-safe module) module) disabled-list)
|
||||
(doom-log "Initialized evil-collection-%s %s"
|
||||
(or (car-safe module) module)
|
||||
(if doom-init-time "" "(too early!)"))
|
||||
(with-demoted-errors "evil-collection error: %s"
|
||||
(evil-collection-init (list module)))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Bootstrap
|
||||
|
||||
;; These modes belong to packages that Emacs always loads at startup, causing
|
||||
;; evil-collection to load immediately. We avoid this by loading them after
|
||||
;; evil-collection has first loaded...
|
||||
(with-eval-after-load 'evil-collection
|
||||
(mapc #'+evil-collection-init '(comint custom help)))
|
||||
|
||||
;; ...or on first invokation of their associated major/minor modes.
|
||||
(add-transient-hook! 'Buffer-menu-mode
|
||||
(+evil-collection-init '(buff-menu "buff-menu")))
|
||||
(add-transient-hook! 'image-mode
|
||||
(+evil-collection-init 'image))
|
||||
(add-transient-hook! 'emacs-lisp-mode
|
||||
(+evil-collection-init 'elisp-mode))
|
||||
(add-transient-hook! 'occur-mode
|
||||
(+evil-collection-init 'replace))
|
||||
|
||||
(evil-define-key* 'normal process-menu-mode-map
|
||||
"q" #'kill-current-buffer
|
||||
"d" #'process-menu-delete-process)
|
||||
|
||||
;; Don't overwrite the leader keys
|
||||
(setq evil-collection-key-blacklist
|
||||
(list doom-leader-key doom-localleader-key
|
||||
doom-leader-alt-key doom-localleader-alt-key))
|
||||
|
||||
;; Load the rest
|
||||
(dolist (mode evil-collection-mode-list)
|
||||
(dolist (req (or (cdr-safe mode) (list mode)))
|
||||
(with-eval-after-load req
|
||||
(+evil-collection-init mode +evil-collection-disabled-list))))
|
||||
@@ -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,8 +34,8 @@ 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]]
|
||||
+ [[https://github.com/noctuid/evil-textobj-anyblock][evil-textobj-anyblock]]
|
||||
+ [[https://github.com/hlissner/evil-snipe][evil-snipe]]
|
||||
@@ -66,8 +68,10 @@ 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= |
|
||||
| vim-unimpaired | (provided by Doom) | [[https://github.com/hlissner/doom-emacs/blob/develop/modules/editor/evil/config.el#L413-L460][see the list]] |
|
||||
|
||||
This module has also ported vim-unimpaired keybinds to Emacs.
|
||||
|
||||
@@ -96,6 +100,10 @@ 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 sane definitions for
|
||||
~beginning-of-defun-function~ and ~end-of-defun-function~)
|
||||
+ =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 +112,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 +132,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 +140,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 +176,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
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
(call-interactively #'doom/escape)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil-resolve-vim-path-a (file-name)
|
||||
(defun +evil-replace-filename-modifiers-a (file-name)
|
||||
"Take a path and resolve any vim-like filename modifiers in it. This adds
|
||||
support for most vim file modifiers, as well as:
|
||||
|
||||
@@ -15,76 +15,65 @@ support for most vim file modifiers, as well as:
|
||||
|
||||
See http://vimdoc.sourceforge.net/htmldoc/cmdline.html#filename-modifiers for
|
||||
more information on modifiers."
|
||||
(let* (case-fold-search
|
||||
(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 ((origin-buffer (current-buffer))
|
||||
case-fold-search)
|
||||
(with-temp-buffer
|
||||
(let ((buffer-file-name (buffer-file-name origin-buffer)))
|
||||
(save-excursion (insert file-name))
|
||||
(while (re-search-forward "\\(^\\|[^\\\\]\\)\\(\\([%#]\\)\\(:\\([PphtreS~.]\\|g?s\\)\\)*\\)" nil t)
|
||||
(if (null buffer-file-name)
|
||||
(replace-match (match-string 1) t t nil 2)
|
||||
(let ((beg (match-beginning 2))
|
||||
(end (match-end 3))
|
||||
(path (pcase (match-string 3)
|
||||
("%" (file-relative-name buffer-file-name default-directory))
|
||||
("#" (and (other-buffer origin-buffer)
|
||||
(buffer-file-name (other-buffer origin-buffer)))))))
|
||||
(save-match-data
|
||||
(goto-char beg)
|
||||
(while (re-search-forward ":\\([PphtreS~.]\\|g?s\\)" (+ (point) 3) t)
|
||||
(let* ((modifier (match-string 1))
|
||||
(global (string-prefix-p "gs" modifier)))
|
||||
(when global
|
||||
(setq modifier (substring modifier 1)))
|
||||
(setq end (match-end 1)
|
||||
path
|
||||
(pcase (and path (substring modifier 0 1))
|
||||
(`nil "")
|
||||
("p" (expand-file-name path))
|
||||
("~" (concat "~/" (file-relative-name path "~")))
|
||||
("." (file-relative-name path))
|
||||
("t" (file-name-nondirectory (directory-file-name path)))
|
||||
("r" (file-name-sans-extension path))
|
||||
("e" (file-name-extension path))
|
||||
("S" (shell-quote-argument path))
|
||||
("h"
|
||||
(let ((parent (file-name-directory (expand-file-name path))))
|
||||
(unless (file-equal-p path parent)
|
||||
(if (file-name-absolute-p path)
|
||||
(directory-file-name parent)
|
||||
(file-relative-name parent)))))
|
||||
("s"
|
||||
(if (featurep 'evil)
|
||||
(when-let (args (evil-delimited-arguments (substring modifier 1) 2))
|
||||
(let ((pattern (evil-transform-vim-style-regexp (car args)))
|
||||
(replace (cadr args)))
|
||||
(replace-regexp-in-string
|
||||
(if global pattern (concat "\\(" pattern "\\).*\\'"))
|
||||
(evil-transform-vim-style-regexp replace) path t t
|
||||
(unless global 1))))
|
||||
path))
|
||||
("P"
|
||||
(let ((project-root (doom-project-root (file-name-directory (expand-file-name path)))))
|
||||
(unless project-root
|
||||
(user-error "Not in a project"))
|
||||
(abbreviate-file-name project-root)))))
|
||||
;; strip trailing slash, if applicable
|
||||
(or (string-empty-p path)
|
||||
(not (equal (substring path -1) "/"))
|
||||
(setq path (substring path 0 -1))))))
|
||||
(replace-match path t t nil 2))))
|
||||
(replace-regexp-in-string "\\\\\\([#%]\\)" "\\1" (buffer-string) t)))))
|
||||
|
||||
(defun +evil--insert-newline (&optional above _noextranewline)
|
||||
(let ((pos (save-excursion (beginning-of-line-text) (point)))
|
||||
@@ -134,8 +123,7 @@ more information on modifiers."
|
||||
(not (eq this-command 'evil-open-below))
|
||||
(evil-insert-state-p))
|
||||
(funcall orig-fn count)
|
||||
(cl-letf (((symbol-function 'evil-insert-newline-below)
|
||||
(lambda () (+evil--insert-newline))))
|
||||
(letf! (defun evil-insert-newline-below () (+evil--insert-newline))
|
||||
(let ((evil-auto-indent evil-auto-indent))
|
||||
(funcall orig-fn count)))))
|
||||
|
||||
@@ -145,8 +133,7 @@ more information on modifiers."
|
||||
(not (eq this-command 'evil-open-above))
|
||||
(evil-insert-state-p))
|
||||
(funcall orig-fn count)
|
||||
(cl-letf (((symbol-function 'evil-insert-newline-above)
|
||||
(lambda () (+evil--insert-newline 'above))))
|
||||
(letf! (defun evil-insert-newline-above () (+evil--insert-newline 'above))
|
||||
(let ((evil-auto-indent evil-auto-indent))
|
||||
(funcall orig-fn count)))))
|
||||
|
||||
|
||||
@@ -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,30 +76,21 @@ 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))
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil/easymotion ()
|
||||
"Invoke and lazy-load `evil-easymotion' without compromising which-key
|
||||
integration."
|
||||
(interactive)
|
||||
(let ((prefix (this-command-keys)))
|
||||
(evil-define-key* 'motion 'global prefix nil)
|
||||
(evilem-default-keybindings (key-description prefix))
|
||||
(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
|
||||
t))
|
||||
prefix)))))
|
||||
(defun +evil/window-move-down ()
|
||||
"Swap windows downward."
|
||||
(interactive) (+evil--window-swap 'down))
|
||||
|
||||
;;;###autoload (autoload '+evil:apply-macro "editor/evil/autoload/evil" nil t)
|
||||
(evil-define-operator +evil:apply-macro (beg end)
|
||||
|
||||
@@ -108,12 +108,13 @@ g Repeat alignment on all matches in each line"
|
||||
If BANG is non-nil, open compilation output in a comint buffer.
|
||||
|
||||
If BANG, then run ARGUMENTS as a full command. This command understands vim file
|
||||
modifiers (like %:p:h). See `+evil-resolve-vim-path-a' for details."
|
||||
modifiers (like %:p:h). See `+evil-replace-filename-modifiers-a' for details."
|
||||
(interactive "<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)
|
||||
@@ -121,7 +122,7 @@ modifiers (like %:p:h). See `+evil-resolve-vim-path-a' for details."
|
||||
If BANG is non-nil, open compilation output in a comint buffer.
|
||||
|
||||
This command understands vim file modifiers (like %:p:h). See
|
||||
`+evil-resolve-vim-path-a' for details."
|
||||
`+evil-replace-filename-modifiers-a' for details."
|
||||
(interactive "<sh><!>")
|
||||
(compile (evil-ex-replace-special-filenames
|
||||
(format "%s %s"
|
||||
@@ -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 (with `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
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
kills the buffer. If FORCE-P, force the deletion (don't ask for confirmation)."
|
||||
:repeat nil
|
||||
(interactive "<f><!>")
|
||||
(doom/delete-this-file (or filename (file-truename buffer-file-name))
|
||||
force-p))
|
||||
(doom/delete-this-file filename force-p))
|
||||
|
||||
;;;###autoload (autoload '+evil:move-this-file "editor/evil/autoload/files" nil t)
|
||||
(evil-define-command +evil:move-this-file (new-path &optional force-p)
|
||||
@@ -20,7 +19,7 @@ overwrite the destination file if it exists, without confirmation."
|
||||
(user-error "No new path was specified"))
|
||||
(doom/move-this-file new-path force-p))
|
||||
|
||||
;;;###autoload (autoload '+evil:copy-this-file "editor/evil/autoload/files" nil nil)
|
||||
;;;###autoload (autoload '+evil:copy-this-file "editor/evil/autoload/files" nil t)
|
||||
(evil-define-command +evil:copy-this-file (new-path &optional force-p)
|
||||
"Copy current buffer's file to NEW-PATH. Replaces %, # and other vim-esque
|
||||
filename modifiers (see `+evil*ex-replace-special-filenames'). If FORCE-P,
|
||||
@@ -30,4 +29,3 @@ overwrite the destination file if it exists, without confirmation."
|
||||
(when (or (not new-path) (string-empty-p new-path))
|
||||
(user-error "No new path was specified"))
|
||||
(doom/copy-this-file new-path force-p))
|
||||
|
||||
|
||||
@@ -7,7 +7,38 @@
|
||||
|
||||
;;;###autoload (autoload '+evil:defun-txtobj "editor/evil/autoload/textobjects" nil nil)
|
||||
(evil-define-text-object +evil:defun-txtobj (count &optional _beg _end type)
|
||||
"Text object to select the whole buffer."
|
||||
"Text object to select the top-level Lisp form or function definition at
|
||||
point."
|
||||
(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)))
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
;;; editor/evil/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; I'm a vimmer at heart. Its modal philosophy suits me better, and this module
|
||||
;; strives to make Emacs a much better vim than vim was.
|
||||
|
||||
(defvar +evil-repeat-keys (cons ";" ",")
|
||||
"The keys to use for universal repeating motions.
|
||||
|
||||
This is a cons cell whose CAR is the key for repeating a motion forward, and
|
||||
whose CDR is for repeating backward. They should both be kbd-able strings.")
|
||||
whose CDR is for repeating backward. They should both be `kbd'-able strings.")
|
||||
|
||||
(defvar +evil-want-o/O-to-continue-comments t
|
||||
"If non-nil, the o/O keys will continue comment lines if the point is on a
|
||||
@@ -20,9 +17,12 @@ 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-g-bindings t)
|
||||
(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 +31,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
|
||||
@@ -48,12 +43,15 @@ directives. By default, this only recognizes C directives.")
|
||||
evil-emacs-state-cursor '(box +evil-emacs-cursor-fn)
|
||||
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))
|
||||
;; 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)
|
||||
|
||||
@@ -124,24 +122,42 @@ 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 hlissner/doom-emacs#2493. Revert this if
|
||||
;; emacs-evil/evil#1268 is resolved upstream.
|
||||
(defadvice! +evil--fix-local-vars-a (&rest _)
|
||||
:before #'turn-on-evil-mode
|
||||
(when (eq major-mode 'fundamental-mode)
|
||||
(hack-local-variables)))
|
||||
|
||||
;; HACK Invoking helpful from evil-ex throws a "No recursive edit is in
|
||||
;; progress" error because, between evil-ex and helpful,
|
||||
;; `abort-recursive-edit' gets called one time too many.
|
||||
(defadvice! +evil--fix-helpful-key-in-evil-ex-a (key-sequence)
|
||||
:before #'helpful-key
|
||||
(when (evil-ex-p)
|
||||
(run-at-time 0.1 nil #'helpful-key key-sequence)
|
||||
(abort-recursive-edit)))
|
||||
|
||||
;; Make ESC (from normal mode) the universal escaper. See `doom-escape-hook'.
|
||||
(advice-add #'evil-force-normal-state :after #'+evil-escape-a)
|
||||
|
||||
;; monkey patch `evil-ex-replace-special-filenames' to improve support for
|
||||
;; file modifiers like %:p:h. This adds support for most of vim's modifiers,
|
||||
;; and one custom one: %:P (expand to the project root).
|
||||
(advice-add #'evil-ex-replace-special-filenames :override #'+evil-resolve-vim-path-a)
|
||||
(advice-add #'evil-ex-replace-special-filenames :override #'+evil-replace-filename-modifiers-a)
|
||||
|
||||
;; make `try-expand-dabbrev' (from `hippie-expand') work in minibuffer
|
||||
(add-hook 'minibuffer-inactive-mode-hook #'+evil--fix-dabbrev-in-minibuffer-h)
|
||||
@@ -150,19 +166,10 @@ directives. By default, this only recognizes C directives.")
|
||||
(advice-add #'evil-window-split :override #'+evil-window-split-a)
|
||||
(advice-add #'evil-window-vsplit :override #'+evil-window-vsplit-a)
|
||||
|
||||
;; Make o/O continue comments (see `+evil-want-o/O-to-continue-comments')
|
||||
;; Make o/O continue comments (see `+evil-want-o/O-to-continue-comments' to disable)
|
||||
(advice-add #'evil-open-above :around #'+evil--insert-newline-above-and-respect-comments-a)
|
||||
(advice-add #'evil-open-below :around #'+evil--insert-newline-below-and-respect-comments-a)
|
||||
|
||||
;; Recenter screen after most searches
|
||||
(dolist (fn '(evil-visualstar/begin-search-forward
|
||||
evil-visualstar/begin-search-backward
|
||||
evil-ex-search-word-backward
|
||||
evil-ex-search-word-backward
|
||||
evil-ex-search-forward
|
||||
evil-ex-search-backward))
|
||||
(advice-add fn :after #'doom-recenter-a))
|
||||
|
||||
;; --- custom interactive codes -----------
|
||||
;; These arg types will highlight matches in the current buffer
|
||||
(evil-ex-define-argument-type regexp-match
|
||||
@@ -201,6 +208,7 @@ directives. By default, this only recognizes C directives.")
|
||||
;;; Packages
|
||||
|
||||
(use-package! evil-easymotion
|
||||
:after-call pre-command-hook
|
||||
:commands evilem-create evilem-default-keybindings
|
||||
:config
|
||||
;; Use evil-search backend, instead of isearch
|
||||
@@ -208,7 +216,6 @@ directives. By default, this only recognizes C directives.")
|
||||
:bind ((evil-ex-search-highlight-all nil)))
|
||||
(evilem-make-motion evilem-motion-search-previous #'evil-ex-search-previous
|
||||
:bind ((evil-ex-search-highlight-all nil)))
|
||||
|
||||
(evilem-make-motion evilem-motion-search-word-forward #'evil-ex-search-word-forward
|
||||
:bind ((evil-ex-search-highlight-all nil)))
|
||||
(evilem-make-motion evilem-motion-search-word-backward #'evil-ex-search-word-backward
|
||||
@@ -218,24 +225,30 @@ directives. By default, this only recognizes C directives.")
|
||||
(use-package! evil-embrace
|
||||
:commands embrace-add-pair embrace-add-pair-regexp
|
||||
:hook (LaTeX-mode . embrace-LaTeX-mode-hook)
|
||||
:hook (LaTeX-mode . +evil-embrace-latex-mode-hook-h)
|
||||
:hook (org-mode . embrace-org-mode-hook)
|
||||
:hook ((ruby-mode enh-ruby-mode) . embrace-ruby-mode-hook)
|
||||
:hook (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)
|
||||
:hook (scala-mode . +evil-embrace-scala-mode-hook-h)
|
||||
:init
|
||||
(after! evil-surround
|
||||
(evil-embrace-enable-evil-surround-integration))
|
||||
:config
|
||||
(setq evil-embrace-show-help-p nil)
|
||||
|
||||
(defun +evil-embrace-scala-mode-hook-h ()
|
||||
(embrace-add-pair ?$ "${" "}"))
|
||||
|
||||
(defun +evil-embrace-latex-mode-hook-h ()
|
||||
(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
|
||||
@@ -244,14 +257,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))
|
||||
@@ -272,8 +282,13 @@ directives. By default, this only recognizes C directives.")
|
||||
evil-escape-delay 0.15)
|
||||
(evil-define-key* '(insert replace visual operator) 'global "\C-g" #'evil-escape)
|
||||
:config
|
||||
;; no `evil-escape' in minibuffer
|
||||
(add-hook 'evil-escape-inhibit-functions #'minibufferp)
|
||||
;; no `evil-escape' in minibuffer, unless `evil-collection-setup-minibuffer'
|
||||
;; is enabled, where we could be in insert mode in the minibuffer.
|
||||
(add-hook! 'evil-escape-inhibit-functions
|
||||
(defun +evil-inhibit-escape-in-minibuffer-fn ()
|
||||
(and (minibufferp)
|
||||
(or (not (bound-and-true-p evil-collection-setup-minibuffer))
|
||||
(evil-normal-state-p)))))
|
||||
;; so that evil-escape-mode-hook runs, and can be toggled by evil-mc
|
||||
(evil-escape-mode +1))
|
||||
|
||||
@@ -356,14 +371,12 @@ directives. By default, this only recognizes C directives.")
|
||||
(defmacro set-repeater! (command next-func prev-func)
|
||||
"Makes ; and , the universal repeat-keys in evil-mode.
|
||||
To change these keys see `+evil-repeat-keys'."
|
||||
(let ((fn-sym (intern (format "+evil/repeat-%s" (doom-unquote command)))))
|
||||
`(progn
|
||||
(defun ,fn-sym (&rest _)
|
||||
(when +evil-repeat-keys
|
||||
(evil-define-key* 'motion 'local
|
||||
(kbd (car +evil-repeat-keys)) #',next-func
|
||||
(kbd (cdr +evil-repeat-keys)) #',prev-func)))
|
||||
(advice-add #',command :after-while #',fn-sym))))
|
||||
`(defadvice! ,(intern (format "+evil--repeat-%s-a" (doom-unquote command))) (&rest _)
|
||||
:after-while #',command
|
||||
(when +evil-repeat-keys
|
||||
(evil-define-key* 'motion 'local
|
||||
(kbd (car +evil-repeat-keys)) #',next-func
|
||||
(kbd (cdr +evil-repeat-keys)) #',prev-func))))
|
||||
|
||||
;; n/N
|
||||
(set-repeater! evil-ex-search-next evil-ex-search-next evil-ex-search-previous)
|
||||
@@ -391,26 +404,6 @@ To change these keys see `+evil-repeat-keys'."
|
||||
evil-ex-search-previous evil-ex-search-next)
|
||||
|
||||
|
||||
;; `evil-collection'
|
||||
(when (featurep! +everywhere)
|
||||
(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)
|
||||
'("gd" "gf" "K"))
|
||||
(when (featurep! :tools eval)
|
||||
'("gr" "gR"))
|
||||
'("[" "]" "gz" "<escape>")))
|
||||
|
||||
(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))))
|
||||
|
||||
;; Keybinds that have no Emacs+evil analogues (i.e. don't exist):
|
||||
;; zq - mark word at point as good word
|
||||
;; zw - mark word at point as bad
|
||||
@@ -434,19 +427,22 @@ To change these keys see `+evil-repeat-keys'."
|
||||
:m "]y" #'+evil:c-string-encode
|
||||
:m "[y" #'+evil:c-string-decode
|
||||
(:when (featurep! :lang web)
|
||||
:m "]x" #'+web:encode-html-entities
|
||||
:m "[x" #'+web:decode-html-entities)
|
||||
:m "]x" #'+web:encode-html-entities
|
||||
:m "[x" #'+web:decode-html-entities)
|
||||
(:when (featurep! :ui vc-gutter)
|
||||
:m "]d" #'git-gutter:next-hunk
|
||||
:m "[d" #'git-gutter:previous-hunk)
|
||||
:m "]d" #'git-gutter:next-hunk
|
||||
:m "[d" #'git-gutter:previous-hunk)
|
||||
(:when (featurep! :ui hl-todo)
|
||||
:m "]t" #'hl-todo-next
|
||||
:m "[t" #'hl-todo-previous)
|
||||
:m "]t" #'hl-todo-next
|
||||
:m "[t" #'hl-todo-previous)
|
||||
(:when (featurep! :ui workspaces)
|
||||
:n "gt" #'+workspace:switch-next
|
||||
:n "gT" #'+workspace:switch-previous
|
||||
:n "]w" #'+workspace/switch-right
|
||||
:n "[w" #'+workspace/switch-left)
|
||||
:n "gt" #'+workspace:switch-next
|
||||
: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
|
||||
@@ -468,7 +464,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
|
||||
@@ -479,29 +475,28 @@ To change these keys see `+evil-repeat-keys'."
|
||||
:v "g-" #'evil-numbers/dec-at-pt-incremental
|
||||
:v "g+" #'evil-numbers/inc-at-pt
|
||||
(:when (featurep! :tools lookup)
|
||||
:nv "K" #'+lookup/documentation
|
||||
:nv "gd" #'+lookup/definition
|
||||
:nv "gD" #'+lookup/references
|
||||
:nv "gf" #'+lookup/file)
|
||||
:nv "K" #'+lookup/documentation
|
||||
:nv "gd" #'+lookup/definition
|
||||
:nv "gD" #'+lookup/references
|
||||
:nv "gf" #'+lookup/file)
|
||||
(:when (featurep! :tools eval)
|
||||
:nv "gr" #'+eval:region
|
||||
:n "gR" #'+eval/buffer
|
||||
:v "gR" #'+eval:replace-region
|
||||
;; Restore these keybinds, since the blacklisted/overwritten gr/gR will
|
||||
;; undo them:
|
||||
(:after dired
|
||||
:map dired-mode-map
|
||||
:n "gr" #'revert-buffer)
|
||||
(:after notmuch
|
||||
:map notmuch-common-keymap
|
||||
:n "gr" #'notmuch-refresh-this-buffer
|
||||
:n "gR" #'notmuch-poll-and-refresh-this-buffer)
|
||||
(:after elfeed
|
||||
:map elfeed-search-update--force
|
||||
:n "gr" #'elfeed-search-update--force
|
||||
:n "gR" #'elfeed-search-fetch))
|
||||
:nv "gr" #'+eval:region
|
||||
:n "gR" #'+eval/buffer
|
||||
:v "gR" #'+eval:replace-region
|
||||
;; Restore these keybinds, since the blacklisted/overwritten gr/gR will
|
||||
;; undo them:
|
||||
(:after dired
|
||||
:map dired-mode-map
|
||||
:n "gr" #'revert-buffer)
|
||||
(:after notmuch
|
||||
:map notmuch-common-keymap
|
||||
:n "gr" #'notmuch-refresh-this-buffer
|
||||
:n "gR" #'notmuch-poll-and-refresh-this-buffer)
|
||||
(:after elfeed
|
||||
:map elfeed-search-mode-map
|
||||
:n "gr" #'elfeed-search-update--force
|
||||
:n "gR" #'elfeed-search-fetch))
|
||||
|
||||
:nv "z=" #'flyspell-correct-word-generic
|
||||
;; custom evil keybinds
|
||||
:nv "zn" #'+evil:narrow-buffer
|
||||
:n "zN" #'doom/widen-indirectly-narrowed-buffer
|
||||
@@ -513,30 +508,30 @@ To change these keys see `+evil-repeat-keys'."
|
||||
|
||||
;; window management (prefix "C-w")
|
||||
(:map evil-window-map
|
||||
;; Navigation
|
||||
"C-h" #'evil-window-left
|
||||
"C-j" #'evil-window-down
|
||||
"C-k" #'evil-window-up
|
||||
"C-l" #'evil-window-right
|
||||
"C-w" #'other-window
|
||||
;; Swapping windows
|
||||
"H" #'+evil/window-move-left
|
||||
"J" #'+evil/window-move-down
|
||||
"K" #'+evil/window-move-up
|
||||
"L" #'+evil/window-move-right
|
||||
"C-S-w" #'ace-swap-window
|
||||
;; Window undo/redo
|
||||
(:prefix "m"
|
||||
"m" #'doom/window-maximize-buffer
|
||||
"v" #'doom/window-maximize-vertically
|
||||
"s" #'doom/window-maximize-horizontally)
|
||||
"u" #'winner-undo
|
||||
"C-u" #'winner-undo
|
||||
"C-r" #'winner-redo
|
||||
"o" #'doom/window-enlargen
|
||||
;; Delete window
|
||||
"d" #'evil-window-delete
|
||||
"C-C" #'ace-delete-window)
|
||||
;; Navigation
|
||||
"C-h" #'evil-window-left
|
||||
"C-j" #'evil-window-down
|
||||
"C-k" #'evil-window-up
|
||||
"C-l" #'evil-window-right
|
||||
"C-w" #'other-window
|
||||
;; Swapping windows
|
||||
"H" #'+evil/window-move-left
|
||||
"J" #'+evil/window-move-down
|
||||
"K" #'+evil/window-move-up
|
||||
"L" #'+evil/window-move-right
|
||||
"C-S-w" #'ace-swap-window
|
||||
;; Window undo/redo
|
||||
(:prefix "m"
|
||||
"m" #'doom/window-maximize-buffer
|
||||
"v" #'doom/window-maximize-vertically
|
||||
"s" #'doom/window-maximize-horizontally)
|
||||
"u" #'winner-undo
|
||||
"C-u" #'winner-undo
|
||||
"C-r" #'winner-redo
|
||||
"o" #'doom/window-enlargen
|
||||
;; Delete window
|
||||
"d" #'evil-window-delete
|
||||
"C-C" #'ace-delete-window)
|
||||
|
||||
;; text objects
|
||||
:textobj "a" #'evil-inner-arg #'evil-outer-arg
|
||||
@@ -547,41 +542,49 @@ 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
|
||||
:m "gs" evilem-map
|
||||
(: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)
|
||||
"SPC" (cmd!! #'evil-avy-goto-char-timer t)
|
||||
"/" #'evil-avy-goto-char-timer))
|
||||
|
||||
;; evil-snipe
|
||||
(:after evil-snipe
|
||||
:map evil-snipe-parent-transient-map
|
||||
"C-;" (λ! (require 'evil-easymotion)
|
||||
(call-interactively
|
||||
(evilem-create #'evil-snipe-repeat
|
||||
:bind ((evil-snipe-scope 'whole-buffer)
|
||||
(evil-snipe-enable-highlight)
|
||||
(evil-snipe-enable-incremental-highlight))))))
|
||||
:map evil-snipe-parent-transient-map
|
||||
"C-;" (cmd! (require 'evil-easymotion)
|
||||
(call-interactively
|
||||
(evilem-create #'evil-snipe-repeat
|
||||
:bind ((evil-snipe-scope 'whole-buffer)
|
||||
(evil-snipe-enable-highlight)
|
||||
(evil-snipe-enable-incremental-highlight))))))
|
||||
|
||||
;; evil-surround
|
||||
:v "S" #'evil-surround-region
|
||||
: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"
|
||||
:i "C-l" #'+company/whole-lines
|
||||
:i "C-k" #'+company/dict-or-keywords
|
||||
:i "C-f" #'company-files
|
||||
:i "C-]" #'company-etags
|
||||
:i "s" #'company-ispell
|
||||
:i "C-s" #'company-yasnippet
|
||||
:i "C-o" #'company-capf
|
||||
:i "C-n" #'+company/dabbrev
|
||||
:i "C-p" #'+company/dabbrev-code-previous)))
|
||||
(:prefix "C-x"
|
||||
:i "C-l" #'+company/whole-lines
|
||||
:i "C-k" #'+company/dict-or-keywords
|
||||
:i "C-f" #'company-files
|
||||
:i "C-]" #'company-etags
|
||||
:i "s" #'company-ispell
|
||||
:i "C-s" #'company-yasnippet
|
||||
:i "C-o" #'company-capf
|
||||
:i "C-n" #'+company/dabbrev
|
||||
:i "C-p" #'+company/dabbrev-code-previous)))
|
||||
|
||||
@@ -1,22 +1,29 @@
|
||||
;; -*- 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-quick-diff :recipe (:host github :repo "rgrinberg/evil-quick-diff"))
|
||||
(package! evil :pin "25fc5c6647979357cf3e39f0667a9b7ae5266af9")
|
||||
(package! evil-args :pin "758ad5ae54ad34202064fec192c88151c08cb387")
|
||||
(package! evil-easymotion :pin "f96c2ed38ddc07908db7c3c11bcd6285a3e8c2e9")
|
||||
(package! evil-embrace :pin "4379adea032b25e359d01a36301b4a5afdd0d1b7")
|
||||
(package! evil-escape
|
||||
:recipe (:host github :repo "hlissner/evil-escape")
|
||||
:pin "819f1ee1cf3f69a1ae920e6004f2c0baeebbe077")
|
||||
(package! evil-exchange :pin "3030e21ee16a42dfce7f7cf86147b778b3f5d8c1")
|
||||
(package! evil-indent-plus :pin "0c7501e6efed661242c3a20e0a6c79a6455c2c40")
|
||||
(package! evil-lion :pin "6b03593f5dd6e7c9ca02207f9a73615cf94c93ab")
|
||||
(package! evil-nerd-commenter :pin "1bd2de52011c39777a3e8779b14cee2790dc873b")
|
||||
(package! evil-numbers
|
||||
:recipe (:host github :repo "janpath/evil-numbers")
|
||||
:pin "c2cfdd1eb1f193bea28ee79b191b78309677058a")
|
||||
(package! evil-snipe :pin "6dcac7f2516c6137a2de532fc2c052f242559ee3")
|
||||
(package! evil-surround :pin "1c34944d8c98da4a2385d24ee89eef9cdf569a12")
|
||||
(package! evil-textobj-anyblock :pin "ff00980f0634f95bf2ad9956b615a155ea8743be")
|
||||
(package! evil-traces :pin "bc25cae9fa5ab0ba1507827f0944f52ce0ca7462")
|
||||
(package! evil-visualstar :pin "06c053d8f7381f91c53311b1234872ca96ced752")
|
||||
(package! exato :pin "aee7af7b7a0e7551478f453d1de7d5b9cb2e06c4")
|
||||
(package! evil-quick-diff
|
||||
:recipe (:host github :repo "rgrinberg/evil-quick-diff")
|
||||
:pin "69c883720b30a892c63bc89f49d4f0e8b8028908")
|
||||
|
||||
;;
|
||||
(when (featurep! +everywhere)
|
||||
@@ -26,4 +33,4 @@
|
||||
(package! neotree)
|
||||
(autoload 'neotree-make-executor "neotree" nil nil 'macro))
|
||||
|
||||
(package! evil-collection))
|
||||
(package! evil-collection :pin "e065da3732f015428bd0068481dadad9e0e6d09c"))
|
||||
|
||||
@@ -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)
|
||||
@@ -9,10 +9,10 @@
|
||||
(load! "../autoload/evil")
|
||||
|
||||
(before-each
|
||||
(fset 'resv #'+evil-resolve-vim-path-a)
|
||||
(fset 'resv #'+evil-replace-filename-modifiers-a)
|
||||
(spy-on 'doom-project-root :and-call-fake (lambda () project-root)))
|
||||
|
||||
;; `evil-ex-replace-special-filenames' / `+evil-resolve-vim-path-a'
|
||||
;; `evil-ex-replace-special-filenames' / `+evil-replace-filename-modifiers-a'
|
||||
(describe "file modifiers"
|
||||
(it "supports basic vim file modifiers"
|
||||
(let ((buffer-file-name "~/.emacs.d/test/modules/feature/test-evil.el")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
@@ -73,7 +73,8 @@ don't have a :trigger property in `+file-templates-alist'.")
|
||||
:when +file-templates-in-emacs-dirs-p
|
||||
:trigger "__doom-readme"
|
||||
:mode org-mode)
|
||||
("\\.org$" :trigger "__" :mode org-mode)
|
||||
(org-journal-mode :ignore t)
|
||||
(org-mode)
|
||||
;; PHP
|
||||
("\\.class\\.php$" :trigger "__.class.php" :mode php-mode)
|
||||
(php-mode)
|
||||
@@ -107,7 +108,7 @@ information.")
|
||||
|
||||
|
||||
;;
|
||||
;; Library
|
||||
;;; Library
|
||||
|
||||
(defun +file-templates-in-emacs-dirs-p (file)
|
||||
"Returns t if FILE is in Doom or your private directory."
|
||||
@@ -118,11 +119,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 +138,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 +157,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)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; editor/file-templates/packages.el
|
||||
|
||||
(package! yasnippet)
|
||||
|
||||
(package! yasnippet :pin "5b1217ab085fab4abeb1118dccb260691b446703")
|
||||
|
||||
@@ -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
|
||||
@@ -1,9 +0,0 @@
|
||||
(defun yas-java-project-package ()
|
||||
(or (and (eq major-mode 'java-mode)
|
||||
(+java-current-package))
|
||||
""))
|
||||
|
||||
(defun yas-java-class-name ()
|
||||
(or (and (eq major-mode 'java-mode)
|
||||
(+java-current-class))
|
||||
""))
|
||||
@@ -1,9 +1,9 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: Java file template
|
||||
# --
|
||||
package `(yas-java-project-package)`;
|
||||
package `(+java-current-package)`;
|
||||
|
||||
public class `(yas-java-class-name)` $1
|
||||
public class `(+java-current-class)` $1
|
||||
{
|
||||
$0
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: Java MAIN file template
|
||||
# --
|
||||
package `(yas-java-project-package)`;
|
||||
package `(+java-current-package)`;
|
||||
|
||||
public class `(yas-java-class-name)` $1
|
||||
public class `(+java-current-class)` $1
|
||||
{
|
||||
public static void main(String[] args) {
|
||||
$0
|
||||
|
||||
@@ -1,6 +1,20 @@
|
||||
# -*- mode: snippet -*-
|
||||
# name: Org template
|
||||
# --
|
||||
#+TITLE: ${1:`(file-name-base buffer-file-name)`}
|
||||
#+TITLE: ${1:`
|
||||
(string-join
|
||||
(mapcar #'capitalize
|
||||
;; Replace -,_... with space
|
||||
(split-string
|
||||
(let (case-fold-search)
|
||||
;; Seperating lower from upper: hello|World
|
||||
(replace-regexp-in-string
|
||||
"\\([[:lower:]]\\)\\([[:upper:]]\\)" "\\1 \\2"
|
||||
;; Separating upper from (upper and lower): HTTP|Server
|
||||
(replace-regexp-in-string "\\([[:upper:]]\\)\\([[:upper:]][0-9[:lower:]]\\)"
|
||||
"\\1 \\2" (file-name-base buffer-file-name))))
|
||||
"[^[:word:]0-9]+"
|
||||
)) " " )
|
||||
`}
|
||||
|
||||
$0
|
||||
@@ -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"
|
||||
@@ -7,36 +7,64 @@
|
||||
(match-string 2 buffer-file-name))
|
||||
"")`}
|
||||
#+DATE: `(format (format-time-string "%B %%s, %Y") (string-to-number (format-time-string "%d")))`
|
||||
#+SINCE: ${2:{replace with next tagged release version}}
|
||||
#+STARTUP: inlineimages
|
||||
#+SINCE: ${2:<replace with next tagged release version>}
|
||||
#+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.
|
||||
This module has no prerequisites.
|
||||
|
||||
* 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
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env `(if (equal (file-name-extension buffer-file-name) "zsh") "zsh" "bash")`
|
||||
set -euo pipefail
|
||||
|
||||
$0
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)))
|
||||
@@ -48,16 +48,24 @@
|
||||
"end\\|[]}]"
|
||||
"#\\|=begin"
|
||||
ruby-forward-sexp)
|
||||
(enh-ruby-mode "class\\|d\\(?:ef\\|o\\)\\|module\\|[[{]"
|
||||
"end\\|[]}]"
|
||||
"#\\|=begin"
|
||||
enh-ruby-forward-sexp nil)
|
||||
(matlab-mode "if\\|switch\\|case\\|otherwise\\|while\\|for\\|try\\|catch"
|
||||
"end"
|
||||
nil (lambda (_arg) (matlab-forward-sexp)))
|
||||
(nxml-mode "<!--\\|<[^/>]*[^/]>"
|
||||
"-->\\|</[^/>]*[^/]>"
|
||||
"<!--" sgml-skip-tag-forward nil))
|
||||
"<!--" sgml-skip-tag-forward nil)
|
||||
(latex-mode
|
||||
;; LaTeX-find-matching-end needs to be inside the env
|
||||
("\\\\begin{[a-zA-Z*]+}\\(\\)" 1)
|
||||
"\\\\end{[a-zA-Z*]+}"
|
||||
"%"
|
||||
(lambda (_arg)
|
||||
;; Don't fold whole document, that's useless
|
||||
(unless (save-excursion
|
||||
(search-backward "\\begin{document}"
|
||||
(line-beginning-position) t))
|
||||
(LaTeX-find-matching-end)))
|
||||
nil))
|
||||
hs-special-modes-alist
|
||||
'((t))))))
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; editor/fold/packages.el
|
||||
|
||||
(package! hideshow :built-in t)
|
||||
|
||||
(package! vimish-fold :pin "63685239655a151181b9152e45478dad587f86f2")
|
||||
(when (featurep! :editor evil)
|
||||
(package! evil-vimish-fold))
|
||||
(package! evil-vimish-fold :pin "b6e0e6b91b8cd047e80debef1a536d9d49eef31a"))
|
||||
|
||||
@@ -92,126 +92,142 @@ Stolen shamelessly from go-mode"
|
||||
;; Public library
|
||||
|
||||
(defun +format-completing-read ()
|
||||
"TODO"
|
||||
(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)
|
||||
"Use `+format-with' instead, if it is set."
|
||||
(if +format-with
|
||||
(list +format-with t)
|
||||
(funcall orig-fn)))
|
||||
"Use `+format-with' instead, if it is set.
|
||||
Prompts for a formatter if universal arg is set."
|
||||
(cond ((or (eq +format-with :none)
|
||||
(doom-temp-buffer-p (current-buffer))
|
||||
(doom-special-buffer-p (current-buffer)))
|
||||
(list nil nil))
|
||||
(current-prefix-arg
|
||||
(list (or (+format-completing-read)
|
||||
(user-error "Aborted"))
|
||||
t))
|
||||
(+format-with
|
||||
(list +format-with t))
|
||||
((funcall orig-fn))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +format-buffer (formatter mode-result &optional preserve-indent-p)
|
||||
"Format the source code in the current buffer.
|
||||
(defun +format-buffer-a (orig-fn formatter mode-result)
|
||||
"Advice that extends `format-all-buffer--with' to:
|
||||
|
||||
Returns any of the following values:
|
||||
|
||||
'unknown No formatter is defined for this major-mode
|
||||
'error Couldn't format buffer due to formatter errors
|
||||
'noop Buffer is already formatted
|
||||
|
||||
Otherwise, returns a list: (list OUTPUT ERRORS FIRST-DIFF), where OUTPUT is the
|
||||
formatted text, ERRORS are any errors in string format, and FIRST-DIFF is the
|
||||
position of the first change in the buffer.
|
||||
1. Enable partial/region reformatting, while preserving leading indentation,
|
||||
2. Applies changes via RCS patch, line by line, to protect buffer markers and
|
||||
reduce cursor movement or window scrolling.
|
||||
|
||||
See `+format/buffer' for the interactive version of this function, and
|
||||
`+format-buffer-h' to use as a `before-save-hook' hook."
|
||||
(if (not formatter)
|
||||
'no-formatter
|
||||
(let ((f-function (gethash formatter format-all--format-table))
|
||||
(executable (format-all--formatter-executable formatter))
|
||||
(indent 0))
|
||||
(pcase-let
|
||||
((`(,output ,errput ,first-diff)
|
||||
;; Since `format-all' functions (and various formatting functions,
|
||||
;; 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))
|
||||
(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)
|
||||
;; 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
|
||||
(setq indent (+format--current-indentation))
|
||||
(when (> indent 0)
|
||||
(indent-rigidly (point-min) (point-max) (- indent))))
|
||||
(funcall f-function executable mode-result))))))
|
||||
(unwind-protect
|
||||
(cond ((null output) 'error)
|
||||
((eq output t) 'noop)
|
||||
((let ((tmpfile (make-temp-file "doom-format"))
|
||||
(patchbuf (get-buffer-create " *doom format patch*"))
|
||||
(coding-system-for-read coding-system-for-read)
|
||||
(coding-system-for-write coding-system-for-write))
|
||||
(unless IS-WINDOWS
|
||||
(setq coding-system-for-read 'utf-8
|
||||
coding-system-for-write 'utf-8))
|
||||
(unwind-protect
|
||||
(progn
|
||||
(with-current-buffer patchbuf
|
||||
(erase-buffer))
|
||||
(with-temp-file tmpfile
|
||||
(erase-buffer)
|
||||
(insert output)
|
||||
(when (> indent 0)
|
||||
;; restore indentation without affecting new
|
||||
;; indentation
|
||||
(indent-rigidly (point-min) (point-max)
|
||||
(max 0 (- indent (+format--current-indentation))))))
|
||||
(if (zerop (call-process-region (point-min) (point-max) "diff" nil patchbuf nil "-n" "-" tmpfile))
|
||||
'noop
|
||||
(+format--apply-rcs-patch patchbuf)
|
||||
(list output errput first-diff)))
|
||||
(kill-buffer patchbuf)
|
||||
(delete-file tmpfile)))))
|
||||
(unless (= 0 (length errput))
|
||||
(message "Formatter error output:\n%s" errput)))))))
|
||||
(let ((f-function (gethash formatter format-all--format-table))
|
||||
(executable (format-all--formatter-executable formatter))
|
||||
(indent 0)
|
||||
(old-line-number (line-number-at-pos))
|
||||
(old-column (current-column)))
|
||||
(pcase-let*
|
||||
((`(,output ,errput)
|
||||
;; To reliably format regions, rather than the whole buffer, and
|
||||
;; `format-all' (and various formatting functions, like `gofmt') widen
|
||||
;; the buffer, we must copy the region first.
|
||||
(let ((output (buffer-substring-no-properties (point-min) (point-max)))
|
||||
(origin-buffer (or (buffer-base-buffer) (current-buffer))))
|
||||
(with-temp-buffer
|
||||
(with-silent-modifications
|
||||
(insert output)
|
||||
;; Ensure this temp buffer seems as much like the origin
|
||||
;; buffer as possible, in case the formatter is an elisp
|
||||
;; function, like `gofmt'.
|
||||
(cl-loop for (var . val)
|
||||
in (cl-remove-if-not #'listp (buffer-local-variables origin-buffer))
|
||||
;; Making enable-multibyte-characters buffer-local
|
||||
;; causes an error.
|
||||
unless (eq var 'enable-multibyte-characters)
|
||||
;; Using setq-local would quote var.
|
||||
do (set (make-local-variable var) val))
|
||||
;; Since we're piping a region of text to the formatter, remove
|
||||
;; any leading indentation to make it look like a file.
|
||||
(setq indent (+format--current-indentation))
|
||||
(when (> indent 0)
|
||||
(indent-rigidly (point-min) (point-max) (- indent)))
|
||||
(funcall f-function executable mode-result)))))
|
||||
(`,status
|
||||
(cond ((null output) :error)
|
||||
((eq output t) :already-formatted)
|
||||
(t :reformatted))))
|
||||
(unwind-protect
|
||||
(when (eq status :reformatted)
|
||||
(let ((tmpfile (make-temp-file "doom-format"))
|
||||
(patchbuf (get-buffer-create " *doom format patch*"))
|
||||
(coding-system-for-read coding-system-for-read)
|
||||
(coding-system-for-write coding-system-for-write))
|
||||
(unless IS-WINDOWS
|
||||
(setq coding-system-for-read 'utf-8
|
||||
coding-system-for-write 'utf-8))
|
||||
(unwind-protect
|
||||
(progn
|
||||
(with-current-buffer patchbuf
|
||||
(erase-buffer))
|
||||
(with-temp-file tmpfile
|
||||
(erase-buffer)
|
||||
(insert output)
|
||||
(when (> indent 0)
|
||||
;; restore indentation without affecting new
|
||||
;; indentation
|
||||
(indent-rigidly (point-min) (point-max)
|
||||
(max 0 (- indent (+format--current-indentation))))))
|
||||
(if (zerop (call-process-region (point-min) (point-max) "diff" nil patchbuf nil "-n" "-" tmpfile))
|
||||
(setq status :already-formatted)
|
||||
(+format--apply-rcs-patch patchbuf)
|
||||
(list output errput)))
|
||||
(kill-buffer patchbuf)
|
||||
(delete-file tmpfile))))
|
||||
(format-all--show-or-hide-errors errput)
|
||||
(goto-char (point-min))
|
||||
(forward-line (1- old-line-number))
|
||||
(let ((line-length (- (point-at-eol) (point-at-bol))))
|
||||
(goto-char (+ (point) (min old-column line-length))))
|
||||
(run-hook-with-args 'format-all-after-format-functions formatter status)
|
||||
(message (pcase status
|
||||
(:error "Formatting error")
|
||||
(:already-formatted "Already formatted")
|
||||
(:reformatted (format "Reformatted with %s" formatter))))))))
|
||||
|
||||
|
||||
;;
|
||||
;; Commands
|
||||
;;; Commands
|
||||
|
||||
;;;###autoload
|
||||
(defun +format/buffer (&optional arg)
|
||||
"Format the source code in the current buffer."
|
||||
(interactive "P")
|
||||
(let ((+format-with (or (if arg (+format-completing-read)) +format-with)))
|
||||
(pcase-let ((`(,formatter ,mode-result) (format-all--probe)))
|
||||
(pcase
|
||||
(+format-buffer
|
||||
formatter mode-result
|
||||
(or +format-preserve-indentation +format-region-p))
|
||||
(`no-formatter
|
||||
(when (called-interactively-p 'any)
|
||||
(message "No formatter specified for %s" major-mode))
|
||||
nil)
|
||||
(`error (message "Failed to format buffer due to errors") nil)
|
||||
(`noop (message "Buffer was already formatted") nil)
|
||||
(_ (message "Formatted (%s)" formatter) t)))))
|
||||
(defun +format/buffer ()
|
||||
"Reformat the current buffer using LSP or `format-all-buffer'."
|
||||
(interactive)
|
||||
(call-interactively
|
||||
(if (and +format-with-lsp
|
||||
(bound-and-true-p lsp-mode)
|
||||
(lsp-feature? "textDocument/formatting"))
|
||||
#'lsp-format-buffer
|
||||
#'format-all-buffer)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +format/region (beg end &optional arg)
|
||||
(defun +format/region (beg end)
|
||||
"Runs the active formatter on the lines within BEG and END.
|
||||
|
||||
WARNING: this may not work everywhere. It will throw errors if the region
|
||||
contains a syntax error in isolation. It is mostly useful for formatting
|
||||
snippets or single lines."
|
||||
(interactive "rP")
|
||||
(save-restriction
|
||||
(narrow-to-region beg end)
|
||||
(let ((+format-region-p t))
|
||||
(+format/buffer arg))))
|
||||
(if (and +format-with-lsp
|
||||
(bound-and-true-p lsp-mode)
|
||||
(lsp-feature? "textDocument/rangeFormatting"))
|
||||
(call-interactively #'lsp-format-region)
|
||||
(save-restriction
|
||||
(narrow-to-region beg end)
|
||||
(let ((+format-region-p t))
|
||||
(+format/buffer)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +format/region-or-buffer ()
|
||||
@@ -219,7 +235,7 @@ snippets or single lines."
|
||||
is selected)."
|
||||
(interactive)
|
||||
(call-interactively
|
||||
(if (use-region-p)
|
||||
(if (doom-region-active-p)
|
||||
#'+format/region
|
||||
#'+format/buffer)))
|
||||
|
||||
|
||||
@@ -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)))))
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
(name formatter &key modes filter ok-statuses error-regexp)
|
||||
"Define (or modify) a formatter named NAME.
|
||||
|
||||
Supported keywords: :modes :install :filter :ok-statuses :error-regexp
|
||||
Supported keywords: :modes :filter :ok-statuses :error-regexp
|
||||
|
||||
NAME is a symbol that identifies this formatter.
|
||||
|
||||
|
||||
@@ -23,6 +23,12 @@ Indentation is always preserved when formatting regions.")
|
||||
(defvar-local +format-with nil
|
||||
"Set this to explicitly use a certain formatter for the current buffer.")
|
||||
|
||||
(defvar +format-with-lsp t
|
||||
"If non-nil, format with LSP formatter if it's available.
|
||||
|
||||
This can be set buffer-locally with `setq-hook!' to disable LSP formatting in
|
||||
select buffers.")
|
||||
|
||||
|
||||
;;
|
||||
;;; Bootstrap
|
||||
@@ -55,4 +61,4 @@ This is controlled by `+format-on-save-enabled-modes'."
|
||||
;; 1. Enables partial reformatting (while preserving leading indentation),
|
||||
;; 2. Applies changes via RCS patch, line by line, to protect buffer markers
|
||||
;; and avoid any jarring cursor+window scrolling.
|
||||
(advice-add #'format-all-buffer :override #'+format/buffer)
|
||||
(advice-add #'format-all-buffer--with :around #'+format-buffer-a)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; editor/format/packages.el
|
||||
|
||||
(package! format-all)
|
||||
(package! format-all :pin "47d862d40a")
|
||||
|
||||
@@ -3,26 +3,5 @@
|
||||
(use-package! god-mode
|
||||
:hook (doom-after-init-modules . god-mode-all)
|
||||
:config
|
||||
(pushnew! god-exempt-major-modes
|
||||
'Custom-mode
|
||||
'Info-mode
|
||||
'ag-mode
|
||||
'calculator-mode
|
||||
'calendar-mode
|
||||
'cider-test-report-mode
|
||||
'compilation-mode
|
||||
'debugger-mode
|
||||
'edebug-mode
|
||||
'ediff-mode
|
||||
'eww-mode
|
||||
'geben-breakpoint-list-mode
|
||||
'ibuffer-mode
|
||||
'org-agenda-mode
|
||||
'pdf-outline-buffer-mode
|
||||
'recentf-dialog-mode
|
||||
'sldb-mode
|
||||
'sly-db-mode
|
||||
'wdired-mode)
|
||||
|
||||
(add-hook 'post-command-hook #'+god--configure-cursor-and-modeline-h)
|
||||
(add-hook 'overwrite-mode-hook #'+god--toggle-on-overwrite-h))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; editor/god/packages.el
|
||||
|
||||
(package! god-mode)
|
||||
(package! god-mode :pin "1eb6ef3a4f67a805c5d6deb1e3895b6c853707d7")
|
||||
|
||||
@@ -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:
|
||||
@@ -18,19 +28,25 @@ lispy is active
|
||||
The default key themes that are set are as follows:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(lispyville-set-key-theme
|
||||
'((operators normal)
|
||||
c-w
|
||||
(prettify insert)
|
||||
(atom-movement normal visual)
|
||||
slurp/barf-lispy
|
||||
(wrap normal insert)
|
||||
additional
|
||||
additional-insert
|
||||
(additional-wrap normal insert)
|
||||
(escape insert)))
|
||||
'((operators normal)
|
||||
c-w
|
||||
(prettify insert)
|
||||
(atom-movement normal visual)
|
||||
slurp/barf-lispy
|
||||
additional
|
||||
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))~.
|
||||
To change the key themes set ~lispyville-key-theme~. Think of
|
||||
~lispyville-key-theme~ as the equivalent of ~parinfer-extensions~. See
|
||||
lispyville's [[https://github.com/noctuid/lispyville/blob/master/README.org][README]] for more info on the specific keybindings of each key theme
|
||||
(starting [[https://github.com/noctuid/lispyville#operators-key-theme][here]]).
|
||||
|
||||
* 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.
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
;;; editor/lispy/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package! lispy
|
||||
:hook ((common-lisp-mode . lispy-mode)
|
||||
:hook ((lisp-mode . lispy-mode)
|
||||
(emacs-lisp-mode . lispy-mode)
|
||||
(scheme-mode . lispy-mode)
|
||||
(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)
|
||||
:init
|
||||
(setq lispyville-key-theme
|
||||
'((operators normal)
|
||||
c-w
|
||||
(prettify insert)
|
||||
(atom-movement normal visual)
|
||||
slurp/barf-lispy
|
||||
additional
|
||||
additional-insert))
|
||||
:config
|
||||
(lispyville-set-key-theme
|
||||
'((operators normal)
|
||||
c-w
|
||||
(prettify insert)
|
||||
(atom-movement normal visual)
|
||||
slurp/barf-lispy
|
||||
(wrap normal insert)
|
||||
additional
|
||||
additional-insert
|
||||
(additional-wrap normal insert)
|
||||
(escape insert))))
|
||||
(lispyville-set-key-theme))
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; editor/lispyville/packages.el
|
||||
|
||||
(package! lispy)
|
||||
|
||||
(package! lispy :pin "cdaa9c70ca39a880163cbbce924bb46cc56b9fa4")
|
||||
(when (featurep! :editor evil)
|
||||
(package! lispyville))
|
||||
(package! lispyville :pin "25a70126ea807653e0a8c512d4128c90ed673d7a"))
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
(message "evil-mc paused")
|
||||
(message "evil-mc resumed")))
|
||||
|
||||
;;;###autoload (autoload '+multiple-cursors/evil-mc-make-cursor-here "editor/multiple-cursors/autoload/evil-mc" nil t)
|
||||
(evil-define-command +multiple-cursors/evil-mc-make-cursor-here ()
|
||||
;;;###autoload (autoload '+multiple-cursors/evil-mc-toggle-cursor-here "editor/multiple-cursors/autoload/evil-mc" nil t)
|
||||
(evil-define-command +multiple-cursors/evil-mc-toggle-cursor-here ()
|
||||
"Create a cursor at point. If in visual block or line mode, then create
|
||||
cursors on each line of the selection, on the column of the cursor. Otherwise
|
||||
pauses cursors."
|
||||
@@ -22,7 +22,18 @@ pauses cursors."
|
||||
:keep-visual nil
|
||||
:evil-mc t
|
||||
(interactive)
|
||||
(cond ((memq evil-this-type '(block line))
|
||||
(cond ((and (evil-mc-has-cursors-p)
|
||||
(evil-normal-state-p)
|
||||
(let* ((pos (point))
|
||||
(cursor (cl-find-if (lambda (cursor)
|
||||
(eq pos (evil-mc-get-cursor-start cursor)))
|
||||
evil-mc-cursor-list)))
|
||||
(when cursor
|
||||
(evil-mc-delete-cursor cursor)
|
||||
(setq evil-mc-cursor-list (delq cursor evil-mc-cursor-list))
|
||||
t))))
|
||||
|
||||
((memq evil-this-type '(block line))
|
||||
(let ((col (evil-column))
|
||||
(line-at-pt (line-number-at-pos)))
|
||||
;; Fix off-by-one error
|
||||
@@ -51,39 +62,61 @@ 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
|
||||
:keep-visual 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"))))
|
||||
|
||||
;;;###autoload (autoload '+multiple-cursors/evil-mc-undo-cursor "editor/multiple-cursors/autoload/evil-mc" nil t)
|
||||
(evil-define-command +multiple-cursors/evil-mc-undo-cursor ()
|
||||
"Undos last cursor, or all cursors in visual region."
|
||||
:repeat nil
|
||||
:evil-mc t
|
||||
(interactive)
|
||||
(if (evil-visual-state-p)
|
||||
(or (mapc (lambda (c)
|
||||
(evil-mc-delete-cursor c)
|
||||
(setq evil-mc-cursor-list (delq c evil-mc-cursor-list)))
|
||||
(cl-remove-if-not
|
||||
(lambda (pos)
|
||||
(and (>= pos evil-visual-beginning)
|
||||
(< pos evil-visual-end)))
|
||||
evil-mc-cursor-list
|
||||
:key #'evil-mc-get-cursor-start))
|
||||
(message "No cursors to undo in region"))
|
||||
(evil-mc-undo-last-added-cursor)))
|
||||
|
||||
@@ -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,7 +67,7 @@
|
||||
(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
|
||||
@@ -72,12 +82,32 @@
|
||||
:test #'eq
|
||||
:key #'car))
|
||||
|
||||
;; HACK Allow these commands to be repeated by prefixing them with a numerical
|
||||
;; argument. See gabesoft/evil-mc#110
|
||||
(defadvice! +multiple-cursors--make-repeatable-a (orig-fn)
|
||||
:around '(evil-mc-make-and-goto-first-cursor
|
||||
evil-mc-make-and-goto-last-cursor
|
||||
evil-mc-make-and-goto-prev-cursor
|
||||
evil-mc-make-and-goto-next-cursor
|
||||
evil-mc-skip-and-goto-prev-cursor
|
||||
evil-mc-skip-and-goto-next-cursor
|
||||
evil-mc-make-and-goto-prev-match
|
||||
evil-mc-make-and-goto-next-match
|
||||
evil-mc-skip-and-goto-prev-match
|
||||
evil-mc-skip-and-goto-next-match)
|
||||
(dotimes (i (if (integerp current-prefix-arg) current-prefix-arg 1))
|
||||
(funcall orig-fn)))
|
||||
|
||||
;; If we're entering insert mode, it's a good bet that we want to start using
|
||||
;; our multiple cursors
|
||||
(add-hook 'evil-insert-state-entry-hook #'evil-mc-resume-cursors)
|
||||
|
||||
;; evil-escape's escape key sequence leaves behind extraneous characters
|
||||
(cl-pushnew 'evil-escape-mode evil-mc-incompatible-minor-modes)
|
||||
;; Lispy commands don't register on more than 1 cursor. Lispyville is fine
|
||||
;; though.
|
||||
(when (featurep! :editor lispy)
|
||||
(cl-pushnew 'lispy-mode evil-mc-incompatible-minor-modes))
|
||||
|
||||
(add-hook! 'doom-escape-hook
|
||||
(defun +multiple-cursors-escape-multiple-cursors-h ()
|
||||
|
||||
@@ -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 "9f271e0e6048297692f80ed6c5ae8994ac523abc")
|
||||
(package! evil-mc :pin "4d4c0172e4c7f80acc1d0e73d5fb3e536929b262"))
|
||||
|
||||
((package! multiple-cursors :pin "b880554d04b8f61165afba7d4de19ac9e39bb7ab")))
|
||||
|
||||
@@ -4,9 +4,7 @@
|
||||
:after-call pre-command-hook
|
||||
:config
|
||||
;; Prevent undo actions from exiting edit state
|
||||
(add-to-list 'objed-keeper-commands 'undo-tree-undo)
|
||||
(add-to-list 'objed-keeper-commands 'undo-tree-redo)
|
||||
(add-to-list 'objed-keeper-commands 'undo-tree-visualize)
|
||||
(pushnew! objed-keeper-commands 'undo-fu-only-undo 'undo-fu-only-redo)
|
||||
|
||||
(defvar +objed--extra-face-remaps nil)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; editor/objed/packages.el
|
||||
|
||||
(package! objed)
|
||||
(package! objed :pin "e89d8dae3b2d4331a4455d2a7b203500537d184d")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -11,4 +11,4 @@
|
||||
;; separate session:
|
||||
(autoload 'evil-define-key "evil-core" nil nil 'macro))
|
||||
|
||||
(package! parinfer)
|
||||
(package! parinfer :pin "eaad857ae4351f72a561ee3dec8943713510003f")
|
||||
|
||||
@@ -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 "48f193697db996855aee1ad2bc99b38c6646fe76")
|
||||
|
||||
@@ -288,16 +288,27 @@ shadow the default snippet)."
|
||||
|
||||
;;;###autoload
|
||||
(defun +snippets-expand-on-region-a (orig-fn &optional no-condition)
|
||||
"Fix off-by-one issue with expanding snippets on an evil visual region, and
|
||||
switches to insert mode.
|
||||
"Fix off-by-one when expanding snippets on an evil visual region.
|
||||
|
||||
If evil-local-mode isn't enabled, run ORIG-FN as is."
|
||||
Also strips whitespace out of selection. Also switches to insert mode. If
|
||||
`evil-local-mode' isn't enabled, or we're not in visual mode, run ORIG-FN as
|
||||
is."
|
||||
(if (not (and (bound-and-true-p evil-local-mode)
|
||||
(evil-visual-state-p)))
|
||||
(funcall orig-fn no-condition)
|
||||
(evil-visual-select evil-visual-beginning evil-visual-end 'inclusive)
|
||||
(cl-letf (((symbol-function 'region-beginning) (lambda () evil-visual-beginning))
|
||||
((symbol-function 'region-end) (lambda () evil-visual-end)))
|
||||
;; Trim whitespace in selected region, so as not to introduce extra
|
||||
;; whitespace into `yas-selected-text'.
|
||||
(evil-visual-select (save-excursion
|
||||
(goto-char evil-visual-beginning)
|
||||
(skip-chars-forward " \t")
|
||||
(point))
|
||||
(save-excursion
|
||||
(goto-char evil-visual-end)
|
||||
(skip-chars-backward " \t")
|
||||
(point))
|
||||
'inclusive)
|
||||
(letf! ((defun region-beginning () evil-visual-beginning)
|
||||
(defun region-end () evil-visual-end))
|
||||
(funcall orig-fn no-condition)))
|
||||
(when (and (bound-and-true-p evil-local-mode)
|
||||
(yas-active-snippets))
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
|
||||
|
||||
;;
|
||||
;; Packages
|
||||
;;; Packages
|
||||
|
||||
(use-package! yasnippet
|
||||
:defer-incrementally eldoc easymenu help-mode
|
||||
:commands (yas-minor-mode-on
|
||||
yas-expand
|
||||
yas-expand-snippet
|
||||
@@ -19,9 +20,11 @@
|
||||
;; Remove default ~/.emacs.d/snippets
|
||||
(defvar yas-snippet-dirs nil)
|
||||
|
||||
;; Ensure `yas-reload-all' is called as late as possible. Other modules could
|
||||
;; have additional configuration for yasnippet. For example, file-templates.
|
||||
(add-transient-hook! 'yas-minor-mode-hook (yas-reload-all))
|
||||
(unless (daemonp)
|
||||
;; Ensure `yas-reload-all' is called as late as possible. Other modules
|
||||
;; could have additional configuration for yasnippet. For example,
|
||||
;; file-templates.
|
||||
(add-transient-hook! 'yas-minor-mode-hook (yas-reload-all)))
|
||||
|
||||
(add-hook! '(text-mode-hook
|
||||
prog-mode-hook
|
||||
@@ -30,24 +33,26 @@
|
||||
#'yas-minor-mode-on)
|
||||
|
||||
:config
|
||||
(setq yas-verbosity (if doom-debug-mode 3 0)
|
||||
yas-also-auto-indent-first-line t)
|
||||
|
||||
(add-to-list 'load-path +snippets-dir)
|
||||
;; default snippets library, if available
|
||||
(require 'doom-snippets nil t)
|
||||
|
||||
;; Allow private snippets in DOOMDIR/snippets
|
||||
(add-to-list 'yas-snippet-dirs '+snippets-dir)
|
||||
|
||||
;; In case `+snippets-dir' and `doom-snippets-dir' are the same
|
||||
;; Reduce verbosity. 3 is too chatty about initializing yasnippet. 2 is just
|
||||
;; right (only shows errors).
|
||||
(setq yas-verbosity (if doom-debug-p 3 0))
|
||||
|
||||
;; default snippets library, if available
|
||||
(add-to-list 'load-path +snippets-dir)
|
||||
(require 'doom-snippets nil t)
|
||||
|
||||
;; HACK In case `+snippets-dir' and `doom-snippets-dir' are the same, or
|
||||
;; duplicates exist in `yas-snippet-dirs'.
|
||||
(advice-add #'yas-snippet-dirs :filter-return #'delete-dups)
|
||||
|
||||
;; Remove GUI dropdown prompt (prefer ivy/helm)
|
||||
(delq! 'yas-dropdown-prompt yas-prompt-functions)
|
||||
;; Prioritize private snippets in `+snippets-dir' over built-in ones if there
|
||||
;; are multiple choices.
|
||||
(add-to-list 'yas-prompt-functions #'+snippets-prompt-private nil #'eq)
|
||||
(add-to-list 'yas-prompt-functions #'+snippets-prompt-private)
|
||||
|
||||
;; Register `def-project-mode!' modes with yasnippet. This enables project
|
||||
;; specific snippet libraries (e.g. for Laravel, React or Jekyll projects).
|
||||
@@ -60,22 +65,14 @@
|
||||
;; tell smartparens overlays not to interfere with yasnippet keybinds
|
||||
(advice-add #'yas-expand :before #'sp-remove-active-pair-overlay))
|
||||
|
||||
;; Enable `read-only-mode' for built-in snippets (in `doom-local-dir')
|
||||
(add-hook 'snippet-mode-hook #'+snippets-read-only-maybe-h)
|
||||
|
||||
;; (Evil only) fix off-by-one issue with line-wise visual selections in
|
||||
;; `yas-insert-snippet', and switches to insert mode afterwards.
|
||||
(advice-add #'yas-insert-snippet :around #'+snippets-expand-on-region-a)
|
||||
|
||||
(define-key! snippet-mode-map
|
||||
"C-c C-k" #'+snippet--abort
|
||||
"C-c C-e" #'+snippet--edit)
|
||||
;; Show keybind hints in snippet header-line
|
||||
(add-hook 'snippet-mode-hook #'+snippets-show-hints-in-header-line-h)
|
||||
|
||||
;; Replace commands with superior alternatives
|
||||
(define-key! yas-minor-mode-map
|
||||
[remap yas-new-snippet] #'+snippets/new
|
||||
[remap yas-visit-snippet-file] #'+snippets/edit)
|
||||
;; Enable `read-only-mode' for built-in snippets (in `doom-local-dir')
|
||||
(add-hook 'snippet-mode-hook #'+snippets-read-only-maybe-h)
|
||||
|
||||
(map! :map yas-keymap
|
||||
"C-e" #'+snippets/goto-end-of-field
|
||||
@@ -84,7 +81,20 @@
|
||||
[M-left] #'+snippets/goto-start-of-field
|
||||
[M-backspace] #'+snippets/delete-to-start-of-field
|
||||
[backspace] #'+snippets/delete-backward-char
|
||||
[delete] #'+snippets/delete-forward-char-or-field))
|
||||
[delete] #'+snippets/delete-forward-char-or-field
|
||||
;; Replace commands with superior alternatives
|
||||
:map yas-minor-mode-map
|
||||
[remap yas-new-snippet] #'+snippets/new
|
||||
[remap yas-visit-snippet-file] #'+snippets/edit)
|
||||
|
||||
;; REVIEW Fix #2639: For some reason `yas--all-templates' returns duplicates
|
||||
;; of some templates. Until I figure out the real cause this fixes it.
|
||||
(defadvice! +snippets--remove-duplicates-a (templates)
|
||||
:filter-return #'yas--all-templates
|
||||
(cl-delete-duplicates templates :test #'equal))
|
||||
|
||||
;; If in a daemon session, front-load this expensive work:
|
||||
(if (daemonp) (yas-reload-all)))
|
||||
|
||||
|
||||
(use-package! auto-yasnippet
|
||||
@@ -96,6 +106,6 @@
|
||||
us who use yas-minor-mode and enable yasnippet more selectively. This advice
|
||||
swaps `yas-global-mode' with `yas-minor-mode'."
|
||||
:around '(aya-expand aya-open-line)
|
||||
(cl-letf (((symbol-function #'yas-global-mode) #'yas-minor-mode)
|
||||
(yas-global-mode yas-minor-mode))
|
||||
(letf! ((#'yas-global-mode #'yas-minor-mode)
|
||||
(yas-global-mode yas-minor-mode))
|
||||
(apply orig-fn args))))
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; editor/snippets/packages.el
|
||||
|
||||
(package! yasnippet)
|
||||
(package! auto-yasnippet)
|
||||
|
||||
(package! yasnippet :pin "5b1217ab085fab4abeb1118dccb260691b446703")
|
||||
(package! auto-yasnippet :pin "db9e0dd4335b2202cd5dac95bbbc87a1032d9bbe")
|
||||
(package! doom-snippets
|
||||
:recipe (:host github
|
||||
:repo "hlissner/doom-snippets"
|
||||
:files ("*.el" "*")))
|
||||
:files ("*.el" "*"))
|
||||
:pin "422f683adfbec1b01fe00524690b64dc9e702ae0")
|
||||
|
||||
@@ -24,3 +24,7 @@ Otherwise no extra indentation will be used.")
|
||||
'(text-mode markdown-mode markdown-view-mode gfm-mode gfm-view-mode rst-mode
|
||||
latex-mode LaTeX-mode)
|
||||
"Major-modes where `+word-wrap-mode' should not provide extra indentation.")
|
||||
|
||||
(when (memq 'visual-line-mode text-mode-hook)
|
||||
(remove-hook 'text-mode-hook #'visual-line-mode)
|
||||
(add-hook 'text-mode-hook #'+word-wrap-mode))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; editor/word-wrap/packages.el
|
||||
|
||||
(package! adaptive-wrap)
|
||||
(package! adaptive-wrap :pin "1810c0ee8d827dd502ddeaae5bd759d4811fcbce")
|
||||
|
||||
56
.emacs.d/modules/emacs/dired/config.el
Executable file → Normal file
56
.emacs.d/modules/emacs/dired/config.el
Executable file → Normal file
@@ -3,47 +3,44 @@
|
||||
(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
|
||||
(let ((args (list "-aBhl" "--group-directories-first")))
|
||||
(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 "-ahl" "-v" "--group-directories-first")))
|
||||
(when IS-BSD
|
||||
;; Use GNU ls as `gls' from `coreutils' if available. Add `(setq
|
||||
;; dired-use-ls-dired nil)' to your config to suppress the Dired warning
|
||||
;; when not using GNU ls.
|
||||
(if-let (gls (executable-find "gls"))
|
||||
(setq insert-directory-program gls)
|
||||
;; BSD ls doesn't support --group-directories-first
|
||||
(setq args (delete "--group-directories-first" args))))
|
||||
(setq dired-listing-switches (string-join args " ")))
|
||||
;; BSD ls doesn't support -v or --group-directories-first
|
||||
(setq args (list (car args)))))
|
||||
(setq dired-listing-switches (string-join args " "))
|
||||
|
||||
(add-hook! 'dired-mode-hook
|
||||
(defun +dired-disable-gnu-ls-flags-in-tramp-buffers-h ()
|
||||
"Fix #1703: dired over TRAMP displays a blank screen.
|
||||
(add-hook! 'dired-mode-hook
|
||||
(defun +dired-disable-gnu-ls-flags-in-tramp-buffers-h ()
|
||||
"Fix #1703: dired over TRAMP displays a blank screen.
|
||||
|
||||
This is because there's no guarantee the remote system has GNU ls, which is the
|
||||
only variant that supports --group-directories-first."
|
||||
(when (file-remote-p default-directory)
|
||||
(setq-local dired-listing-switches
|
||||
(string-join
|
||||
(split-string dired-listing-switches
|
||||
"--group-directories-first")
|
||||
" ")))))
|
||||
(when (file-remote-p default-directory)
|
||||
(setq-local dired-actual-switches (car args))))))
|
||||
|
||||
;; Don't complain about this command being disabled when we use it
|
||||
(put 'dired-find-alternate-file 'disabled nil)
|
||||
@@ -64,7 +61,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 +71,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))
|
||||
@@ -122,13 +116,13 @@ we have to clean it up ourselves."
|
||||
(defvar +wdired-icons-enabled -1)
|
||||
|
||||
(defadvice! +dired-disable-icons-in-wdired-mode-a (&rest _)
|
||||
:before #'+wdired-before-start-advice
|
||||
:before #'wdired-change-to-wdired-mode
|
||||
(setq-local +wdired-icons-enabled (if all-the-icons-dired-mode 1 -1))
|
||||
(when all-the-icons-dired-mode
|
||||
(all-the-icons-dired-mode -1)))
|
||||
|
||||
(defadvice! +dired-restore-icons-after-wdired-mode-a (&rest _)
|
||||
:after #'+wdired-after-finish-advice
|
||||
:after #'wdired-change-to-dired-mode
|
||||
(all-the-icons-dired-mode +wdired-icons-enabled))))
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; emacs/dired/packages.el
|
||||
|
||||
(package! diredfl)
|
||||
(package! dired-git-info)
|
||||
(package! diff-hl)
|
||||
(package! dired-rsync)
|
||||
(package! diredfl :pin "83567d00affce66a4e501563eddd0bd436ac48d0")
|
||||
(package! dired-git-info :pin "b47f2b0c3a6cb9b7a62a4ee2605a492e512d40a9")
|
||||
(package! diff-hl :pin "a625033fb1dde83f6e4c2fc21f632b22ec34b609")
|
||||
(package! dired-rsync :pin "bfd5c155be1cb6b71c83e5f41116c81b6532b6d5")
|
||||
(when (featurep! +ranger)
|
||||
(package! ranger))
|
||||
(package! ranger :pin "ae9b3816a6da927cca5beb62c45400103797a2da"))
|
||||
(when (featurep! +icons)
|
||||
(package! all-the-icons-dired))
|
||||
(package! fd-dired)
|
||||
(package! all-the-icons-dired :pin "fc2dfa1e9eb8bf1c402a675e7089638d702a27a5"))
|
||||
(package! fd-dired :pin "001cc95effdd5c4d9974b3f2c40b2ddf1f0e3de2")
|
||||
|
||||
@@ -39,6 +39,23 @@
|
||||
: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/open-for-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)
|
||||
"Use `counsel-find-file' instead of `find-file'."
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; emacs/ibuffer/packages.el
|
||||
|
||||
(package! ibuffer-projectile)
|
||||
(package! ibuffer-vc)
|
||||
(package! ibuffer-projectile :pin "504b0edaa0d937ce60ccc8fdf09f2dae0a90fbaf")
|
||||
(package! ibuffer-vc :pin "1249c1e30cf11badfe032ac3b1058f24ba510ace")
|
||||
|
||||
@@ -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))
|
||||
@@ -1,30 +1,5 @@
|
||||
;;; emacs/vc/autoload/vc.el -*- lexical-binding: t; -*-
|
||||
|
||||
(autoload 'browse-at-remote--file-url "browse-at-remote")
|
||||
|
||||
;;;###autoload
|
||||
(defun +vc/browse-at-remote-file-or-region ()
|
||||
"Open the current file at remote in your browser.
|
||||
If a selection is active, highlight them. Otherwise omits the #L<N> suffix in
|
||||
the URL."
|
||||
(interactive)
|
||||
(if (or (use-region-p)
|
||||
(ignore-errors (evil-visual-state-p)))
|
||||
(browse-at-remote)
|
||||
(browse-url (browse-at-remote--file-url (buffer-file-name)))))
|
||||
|
||||
;;;###autoload
|
||||
(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)
|
||||
(if (or (use-region-p)
|
||||
(ignore-errors (evil-visual-state-p)))
|
||||
(browse-at-remote-kill)
|
||||
(kill-new (browse-at-remote--file-url (buffer-file-name)))))
|
||||
|
||||
|
||||
(defun +vc--remote-homepage ()
|
||||
(or (let ((url (browse-at-remote--remote-ref)))
|
||||
(cdr (browse-at-remote--get-url-from-remote (car url))))
|
||||
@@ -40,4 +15,6 @@ the URL."
|
||||
(defun +vc/browse-at-remote-kill-homepage ()
|
||||
"Copy homepage URL of current project to clipboard."
|
||||
(interactive)
|
||||
(kill-new (+vc--remote-homepage)))
|
||||
(let ((url (+vc--remote-homepage)))
|
||||
(kill-new url)
|
||||
(message "Copied to clipboard: %S" url)))
|
||||
|
||||
@@ -4,18 +4,33 @@
|
||||
(setenv "GIT_ASKPASS" "git-gui--askpass"))
|
||||
|
||||
|
||||
(after! log-view
|
||||
(set-evil-initial-state!
|
||||
'(log-view-mode
|
||||
vc-git-log-view-mode
|
||||
vc-hg-log-view-mode
|
||||
vc-bzr-log-view-mode
|
||||
vc-svn-log-view-mode)
|
||||
'emacs)
|
||||
(map! :map log-view-mode-map
|
||||
"j" #'log-view-msg-next
|
||||
"k" #'log-view-msg-prev))
|
||||
|
||||
|
||||
(after! vc-annotate
|
||||
(set-popup-rules!
|
||||
'(("^\\vc-d" :select nil) ; *vc-diff*
|
||||
("^\\vc-c" :select t))) ; *vc-change-log*
|
||||
(set-evil-initial-state!
|
||||
'(vc-annotate-mode vc-git-log-view-mode)
|
||||
'normal)
|
||||
'(("^\\*vc-diff" :select nil) ; *vc-diff*
|
||||
("^\\*vc-change" :select t))) ; *vc-change-log*
|
||||
(set-evil-initial-state! 'vc-annotate-mode 'normal)
|
||||
|
||||
;; Clean up after itself
|
||||
(define-key vc-annotate-mode-map [remap quit-window] #'kill-current-buffer))
|
||||
|
||||
|
||||
(after! vc-dir
|
||||
(set-evil-initial-state! 'vc-dir-mode 'emacs))
|
||||
|
||||
|
||||
(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
|
||||
@@ -53,9 +68,8 @@ info in the `header-line-format' is a good indication."
|
||||
|
||||
|
||||
(use-package! git-commit
|
||||
:after-call after-find-file
|
||||
:hook (doom-first-file . global-git-commit-mode)
|
||||
:config
|
||||
(global-git-commit-mode +1)
|
||||
(set-yas-minor-mode! 'git-commit-mode)
|
||||
|
||||
;; Enforce git commit conventions.
|
||||
@@ -71,3 +85,15 @@ otherwise in default state."
|
||||
(when (and (bound-and-true-p evil-mode)
|
||||
(bobp) (eolp))
|
||||
(evil-insert-state)))))
|
||||
|
||||
|
||||
(after! browse-at-remote
|
||||
(setq browse-at-remote-add-line-number-if-no-region-selected nil)
|
||||
|
||||
;; HACK `browse-at-remote' produces urls with `nil' in them, when the repo is
|
||||
;; detached. This creates broken links. I think it is more sensible to
|
||||
;; fall back to master in those cases.
|
||||
(defadvice! +vc--fallback-to-master-branch-a ()
|
||||
"Return 'master' in detached state."
|
||||
:after-until #'browse-at-remote--get-local-branch
|
||||
"master"))
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
(package! vc-annotate :built-in t)
|
||||
(package! smerge-mode :built-in t)
|
||||
|
||||
(package! browse-at-remote)
|
||||
(package! git-timemachine)
|
||||
(package! gitconfig-mode)
|
||||
(package! gitignore-mode)
|
||||
(package! browse-at-remote :pin "6aecae4b5d202e582425fc8aa2c9c2b6a4779f25")
|
||||
(package! git-commit :pin "d459e528f46423f1976e5fa415e64f8f7162b473")
|
||||
(package! git-timemachine :pin "391eb61050de321101e631fcf373fc70ec6e7700")
|
||||
(package! gitconfig-mode :pin "55468314a5f6b77d2c96be62c7005ac94545e217")
|
||||
(package! gitignore-mode :pin "55468314a5f6b77d2c96be62c7005ac94545e217")
|
||||
|
||||
@@ -12,10 +12,15 @@
|
||||
- [[#arch-linux][Arch Linux]]
|
||||
- [[#nixos][NixOS]]
|
||||
- [[#opensuse][openSUSE]]
|
||||
- [[#debianubuntu][Debian/Ubuntu]]
|
||||
- [[#features][Features]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#offlineimap][offlineimap]]
|
||||
- [[#mbsync][mbsync]]
|
||||
- [[#mu-and-mu4e][mu and mu4e]]
|
||||
- [[#troubleshooting][Troubleshooting]]
|
||||
- [[#no-such-file-or-directory-mu4e][=No such file or directory, mu4e=]]
|
||||
- [[#void-function-org-time-add-error-on-gentoo][~(void-function org-time-add)~ error on Gentoo]]
|
||||
|
||||
* Description
|
||||
This module makes Emacs an email client, using ~mu4e~.
|
||||
@@ -33,17 +38,17 @@ via IMAP) and ~mu~ (to index my mail into a format ~mu4e~ can understand).
|
||||
+ ~+gmail~ Enables gmail-specific configuration.
|
||||
|
||||
** Plugins
|
||||
+ [[https://github.com/agpchil/mu4e-maildirs-extension][mu4e-maildirs-extension]]
|
||||
This module install no plugins.
|
||||
|
||||
* Prerequisites
|
||||
This module requires:
|
||||
|
||||
+ Either ~mbsync~ (default) or ~offlineimap~ (to sync mail with)
|
||||
+ ~mu~ (to index your downloaded messages)
|
||||
+ ~mu~, to index your downloaded messages and to provide the ~mu4e~ package.
|
||||
|
||||
** MacOS
|
||||
#+BEGIN_SRC sh
|
||||
brew install mu --with-emacs
|
||||
brew install mu
|
||||
# And one of the following
|
||||
brew install isync # mbsync
|
||||
brew install offlineimap
|
||||
@@ -54,6 +59,7 @@ Run one of the following commands.
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
sudo pacman -S isync # mbsync
|
||||
# OR
|
||||
sudo pacman -S offlineimap
|
||||
#+END_SRC
|
||||
|
||||
@@ -74,7 +80,7 @@ environment.systemPackages = with pkgs; [
|
||||
];
|
||||
#+END_SRC
|
||||
|
||||
[[https://github.com/Emiller88/dotfiles/blob/master/modules/shell/mail.nix][An example of setting up mbsync with home-manager]]
|
||||
[[https://github.com/Emiller88/dotfiles/blob/5eaabedf1b141c80a8d32e1b496055231476f65e/modules/shell/mail.nix][An example of setting up mbsync and mu with home-manager]]
|
||||
|
||||
** openSUSE
|
||||
Remove ~#~ in ~#sync_program=offlineimap~ to choose ~offlineimap~ instead of
|
||||
@@ -84,26 +90,69 @@ Remove ~#~ in ~#sync_program=offlineimap~ to choose ~offlineimap~ instead of
|
||||
sync_program=isync # mbsync
|
||||
#sync_program=offlineimap
|
||||
|
||||
sudo zypper install maildir-utils $sync_programm
|
||||
sudo zypper install maildir-utils $sync_program
|
||||
#+END_SRC
|
||||
|
||||
** Debian/Ubuntu
|
||||
Run the command corresponding to the desired backend and the last one.
|
||||
#+BEGIN_SRC sh
|
||||
sudo apt-get install isync # mbsync
|
||||
# or
|
||||
sudo apt-get install offlineimap
|
||||
# then
|
||||
sudo apt-get install maildir-utils # mu
|
||||
#+END_SRC
|
||||
* TODO Features
|
||||
|
||||
* Configuration
|
||||
** offlineimap
|
||||
This module uses =mbsync= by default. To change this, change ~+mu4e-backend~:
|
||||
This module uses =mbsync= by default. To use =offlineimap=, change ~+mu4e-backend~:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq +mu4e-backend 'offlineimap)
|
||||
#+END_SRC
|
||||
|
||||
Then you must set up offlineimap and index your mail:
|
||||
Next, you need to write a configuration file for =offlineimap=. Mine can be found
|
||||
[[https://github.com/hlissner/dotfiles/blob/be0dce5dae8f3cbafaac0cc44269d84b4a742c46/shell/mu/][in my dotfiles repository]]. It is configured to download mail to ~\~/.mail~. I
|
||||
use [[https://www.passwordstore.org/][unix pass]] to securely store my login credentials. You can find a *very*
|
||||
detailed configuration [[https://github.com/OfflineIMAP/offlineimap/blob/master/offlineimap.conf][here]].
|
||||
|
||||
1. Write a ~\~/.offlineimaprc~. Mine can be found [[https://github.com/hlissner/dotfiles/tree/master/shell/mu][in my dotfiles repository]]. It
|
||||
is configured to download mail to ~\~/.mail~. I use [[https://www.passwordstore.org/][unix pass]] to securely
|
||||
store my login credentials.
|
||||
2. Download your email: ~offlineimap -o~ (may take a while)
|
||||
3. Index it with mu: ~mu index --maildir ~/.mail~
|
||||
Next you can download your email with ~offlineimap -o~. This may take a while,
|
||||
especially if you have thousands of mails.
|
||||
|
||||
You can now proceed with the [[#mu-and-mu4e][mu and mu4e]] section.
|
||||
|
||||
** mbsync
|
||||
The steps needed to set up =mu4e= with =mbsync= are very similar to the ones for
|
||||
[[#offlineimap][offlineimap]].
|
||||
|
||||
Start with writing a ~\~/.mbsyncrc~. An example for GMAIL can be found on
|
||||
[[http://pragmaticemacs.com/emacs/migrating-from-offlineimap-to-mbsync-for-mu4e/][pragmaticemacs.com]]. A non-GMAIL example is available as a gist [[https://gist.github.com/agraul/60977cc497c3aec44e10591f94f49ef0][here]]. The [[http://isync.sourceforge.net/mbsync.html][manual
|
||||
page]] contains all needed information to set up your own.
|
||||
|
||||
Next you can download your email with ~mbsync --all~. This may take a while, but
|
||||
should be quicker than =offlineimap= ;).
|
||||
|
||||
You can now proceed with the [[#mu-and-mu4e][mu and mu4e]] section.
|
||||
|
||||
** mu and mu4e
|
||||
You should have your email downloaded already. If you have not, you need to set
|
||||
=offlineimap= or =mbsync= up before you proceed.
|
||||
|
||||
Before you can use =mu4e= or the cli program =mu=, you need to index your email
|
||||
initially. How to do that differs a little depending on the version of =mu= you
|
||||
use. You can check your version with ~mu --version~.
|
||||
|
||||
For =mu= *>=1.4* you need to run two commands:
|
||||
#+BEGIN_SRC sh
|
||||
mu init --maildir ~/.mail --my-address email@example.com
|
||||
mu index
|
||||
#+END_SRC
|
||||
|
||||
=mu= *<1.4* only requires one command:
|
||||
#+BEGIN_SRC sh
|
||||
mu index --maildir ~/.mail
|
||||
#+END_SRC
|
||||
|
||||
Then configure Emacs to use your email address:
|
||||
|
||||
@@ -115,9 +164,20 @@ Then configure Emacs to use your email address:
|
||||
(mu4e-trash-folder . "/Lissner.net/Trash")
|
||||
(mu4e-refile-folder . "/Lissner.net/All Mail")
|
||||
(smtpmail-smtp-user . "henrik@lissner.net")
|
||||
(user-mail-address . "henrik@lissner.net")
|
||||
(user-mail-address . "henrik@lissner.net") ;; only needed for mu < 1.4
|
||||
(mu4e-compose-signature . "---\nHenrik Lissner"))
|
||||
t)
|
||||
#+END_SRC
|
||||
|
||||
** TODO mbsync
|
||||
* Troubleshooting
|
||||
** =No such file or directory, mu4e=
|
||||
You will get =No such file or directory, mu4e= errors if you don't run ~doom
|
||||
sync~ after installing =mu= through your package manager.
|
||||
** ~(void-function org-time-add)~ error on Gentoo
|
||||
Gentoo users will see this error because [[https://gitweb.gentoo.org/repo/gentoo.git/tree/net-mail/mu/files/70mu-gentoo.el#n2][the =net-mail/mu= package eagerly loads
|
||||
=mu4e= (which pulls in =org=) much too early]]; before Emacs reads =~/.emacs.d=.
|
||||
So early, that it loads the built-in version of org-mode, rather than the newer
|
||||
version that Doom installs.
|
||||
|
||||
Later versions of the =net-mail/mu= package have [[https://gitweb.gentoo.org/repo/gentoo.git/commit/net-mail/mu?id=770e1fccb119fbce8ba6d16021a3598123f212ff][fixed this issue]], but you may
|
||||
need to switch to the unstable build of =net-mail/mu= to see it.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
list of cons cells (VARIABLE . VALUE) -- you may want to modify:
|
||||
|
||||
+ `user-full-name' (this or the global `user-full-name' is required)
|
||||
+ `user-mail-address' (required)
|
||||
+ `user-mail-address' (required in mu4e < 1.4)
|
||||
+ `smtpmail-smtp-user' (required for sending mail from Emacs)
|
||||
|
||||
OPTIONAL:
|
||||
@@ -19,8 +19,9 @@ OPTIONAL:
|
||||
DEFAULT-P is a boolean. If non-nil, it marks that email account as the
|
||||
default/fallback account."
|
||||
(after! mu4e
|
||||
(when-let (address (cdr (assq 'user-mail-address letvars)))
|
||||
(add-to-list 'mu4e-user-mail-address-list address))
|
||||
(when (version< mu4e-mu-version "1.4")
|
||||
(when-let (address (cdr (assq 'user-mail-address letvars)))
|
||||
(add-to-list 'mu4e-user-mail-address-list address)))
|
||||
(setq mu4e-contexts
|
||||
(cl-loop for context in mu4e-contexts
|
||||
unless (string= (mu4e-context-name context) label)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user