2019-04-21 19:59:44 -04:00
|
|
|
;;; editor/snippets/config.el -*- lexical-binding: t; -*-
|
2017-02-11 06:59:49 -05:00
|
|
|
|
2018-05-25 00:46:11 +02:00
|
|
|
(defvar +snippets-dir (expand-file-name "snippets/" doom-private-dir)
|
|
|
|
"Directory where `yasnippet' will search for your private snippets.")
|
|
|
|
|
|
|
|
|
|
|
|
;;
|
2020-04-17 21:58:55 -04:00
|
|
|
;;; Packages
|
2018-05-25 00:46:11 +02:00
|
|
|
|
2019-07-23 12:44:03 +02:00
|
|
|
(use-package! yasnippet
|
2020-03-31 02:24:14 -04:00
|
|
|
:defer-incrementally eldoc easymenu help-mode
|
2019-07-22 19:11:12 +02:00
|
|
|
:commands (yas-minor-mode-on
|
|
|
|
yas-expand
|
|
|
|
yas-expand-snippet
|
|
|
|
yas-lookup-snippet
|
|
|
|
yas-insert-snippet
|
|
|
|
yas-new-snippet
|
|
|
|
yas-visit-snippet-file)
|
2017-02-11 06:59:49 -05:00
|
|
|
:init
|
2019-11-22 16:30:45 -05:00
|
|
|
;; Remove default ~/.emacs.d/snippets
|
|
|
|
(defvar yas-snippet-dirs nil)
|
|
|
|
|
2020-04-24 04:07:57 -04:00
|
|
|
(unless (daemonp)
|
2020-04-17 21:58:55 -04:00
|
|
|
;; 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)))
|
2017-02-28 17:58:52 -05:00
|
|
|
|
2019-07-26 19:57:13 +02:00
|
|
|
(add-hook! '(text-mode-hook
|
|
|
|
prog-mode-hook
|
|
|
|
conf-mode-hook
|
|
|
|
snippet-mode-hook)
|
|
|
|
#'yas-minor-mode-on)
|
2017-02-19 18:32:09 -05:00
|
|
|
|
|
|
|
:config
|
2020-08-21 00:09:59 -04:00
|
|
|
(add-to-list 'doom-debug-variables '(yas-verbosity . 3))
|
|
|
|
|
2020-04-17 21:58:55 -04:00
|
|
|
;; Allow private snippets in DOOMDIR/snippets
|
|
|
|
(add-to-list 'yas-snippet-dirs '+snippets-dir)
|
|
|
|
|
|
|
|
;; Reduce verbosity. 3 is too chatty about initializing yasnippet. 2 is just
|
|
|
|
;; right (only shows errors).
|
2020-05-25 02:58:07 -04:00
|
|
|
(setq yas-verbosity (if doom-debug-p 3 0))
|
2018-07-09 15:33:31 +02:00
|
|
|
|
2019-07-14 22:46:16 +02:00
|
|
|
;; default snippets library, if available
|
2020-04-17 21:58:55 -04:00
|
|
|
(add-to-list 'load-path +snippets-dir)
|
2019-07-14 22:46:16 +02:00
|
|
|
(require 'doom-snippets nil t)
|
|
|
|
|
2020-04-17 21:58:55 -04:00
|
|
|
;; HACK In case `+snippets-dir' and `doom-snippets-dir' are the same, or
|
|
|
|
;; duplicates exist in `yas-snippet-dirs'.
|
2019-11-22 16:30:45 -05:00
|
|
|
(advice-add #'yas-snippet-dirs :filter-return #'delete-dups)
|
2018-07-09 15:33:31 +02:00
|
|
|
|
2018-08-11 16:48:31 +02:00
|
|
|
;; Remove GUI dropdown prompt (prefer ivy/helm)
|
2019-07-22 19:11:12 +02:00
|
|
|
(delq! 'yas-dropdown-prompt yas-prompt-functions)
|
2018-08-11 16:48:31 +02:00
|
|
|
;; Prioritize private snippets in `+snippets-dir' over built-in ones if there
|
|
|
|
;; are multiple choices.
|
2020-04-17 21:58:55 -04:00
|
|
|
(add-to-list 'yas-prompt-functions #'+snippets-prompt-private)
|
2018-08-11 16:48:31 +02:00
|
|
|
|
2018-06-19 13:00:05 +02:00
|
|
|
;; Register `def-project-mode!' modes with yasnippet. This enables project
|
|
|
|
;; specific snippet libraries (e.g. for Laravel, React or Jekyll projects).
|
2019-07-26 19:57:13 +02:00
|
|
|
(add-hook 'doom-project-hook #'+snippets-enable-project-modes-h)
|
2018-07-09 15:33:31 +02:00
|
|
|
|
2017-12-27 18:20:14 -05:00
|
|
|
;; Exit snippets on ESC from normal mode
|
2018-05-25 00:46:11 +02:00
|
|
|
(add-hook 'doom-escape-hook #'yas-abort-snippet)
|
2018-07-09 15:33:31 +02:00
|
|
|
|
2018-05-25 00:46:11 +02:00
|
|
|
(after! smartparens
|
2018-07-09 15:33:31 +02:00
|
|
|
;; tell smartparens overlays not to interfere with yasnippet keybinds
|
2018-06-19 13:00:05 +02:00
|
|
|
(advice-add #'yas-expand :before #'sp-remove-active-pair-overlay))
|
2018-07-09 15:33:31 +02:00
|
|
|
|
editor/snippets: expand on snippet commands & keybinds
- Introduces the +snippets/new (SPC s n) command for creating a new
private snippet
- Introduces the +snippets/new-lias (SPC s N) command for creating a new
private snippet alias, which will invoke another snippet (you will be
prompted to select one). This will only work with the emacs-snippets
library bundled with Doom Emacs, however, as it depends on its API.
- Introduces +snippets/edit (SPC s c) for modifying existing snippets.
How this differs from yas-visit-snippet-file is it will copy the
contents of built-in snippets into a buffer primed for your private
snippets (in DOOMDIR/snippets), while yas-visit-snippet-file will
simply open the originating snippet.
- Introduces the +snippets/find (SPC s ?),
+snippets/find-for-current-mode (SPC s /) and
+snippets/find-private (SPC s f) commands for, respectively, finding a
snippet file among *all* directories in yas-snippet-dirs, finding a
snippet for the current major mode (plus parents), and finding a
snippet from among your private library. This opens built-in snippets
in read-only mode, but you can press C-c C-e to open it in
+snippets/edit.
2019-07-12 20:41:50 +02:00
|
|
|
;; (Evil only) fix off-by-one issue with line-wise visual selections in
|
2019-05-31 20:11:06 -04:00
|
|
|
;; `yas-insert-snippet', and switches to insert mode afterwards.
|
2019-07-26 19:57:13 +02:00
|
|
|
(advice-add #'yas-insert-snippet :around #'+snippets-expand-on-region-a)
|
editor/snippets: expand on snippet commands & keybinds
- Introduces the +snippets/new (SPC s n) command for creating a new
private snippet
- Introduces the +snippets/new-lias (SPC s N) command for creating a new
private snippet alias, which will invoke another snippet (you will be
prompted to select one). This will only work with the emacs-snippets
library bundled with Doom Emacs, however, as it depends on its API.
- Introduces +snippets/edit (SPC s c) for modifying existing snippets.
How this differs from yas-visit-snippet-file is it will copy the
contents of built-in snippets into a buffer primed for your private
snippets (in DOOMDIR/snippets), while yas-visit-snippet-file will
simply open the originating snippet.
- Introduces the +snippets/find (SPC s ?),
+snippets/find-for-current-mode (SPC s /) and
+snippets/find-private (SPC s f) commands for, respectively, finding a
snippet file among *all* directories in yas-snippet-dirs, finding a
snippet for the current major mode (plus parents), and finding a
snippet from among your private library. This opens built-in snippets
in read-only mode, but you can press C-c C-e to open it in
+snippets/edit.
2019-07-12 20:41:50 +02:00
|
|
|
|
2020-04-17 21:58:55 -04:00
|
|
|
;; Show keybind hints in snippet header-line
|
2019-07-26 19:57:13 +02:00
|
|
|
(add-hook 'snippet-mode-hook #'+snippets-show-hints-in-header-line-h)
|
2020-04-17 21:58:55 -04:00
|
|
|
;; Enable `read-only-mode' for built-in snippets (in `doom-local-dir')
|
|
|
|
(add-hook 'snippet-mode-hook #'+snippets-read-only-maybe-h)
|
2019-10-26 21:34:44 -04:00
|
|
|
|
|
|
|
(map! :map yas-keymap
|
|
|
|
"C-e" #'+snippets/goto-end-of-field
|
|
|
|
"C-a" #'+snippets/goto-start-of-field
|
|
|
|
[M-right] #'+snippets/goto-end-of-field
|
|
|
|
[M-left] #'+snippets/goto-start-of-field
|
|
|
|
[M-backspace] #'+snippets/delete-to-start-of-field
|
|
|
|
[backspace] #'+snippets/delete-backward-char
|
2020-04-17 21:58:55 -04:00
|
|
|
[delete] #'+snippets/delete-forward-char-or-field
|
|
|
|
;; Replace commands with superior alternatives
|
|
|
|
:map yas-minor-mode-map
|
|
|
|
[remap yas-new-snippet] #'+snippets/new
|
2020-04-24 04:07:57 -04:00
|
|
|
[remap yas-visit-snippet-file] #'+snippets/edit)
|
|
|
|
|
2020-06-05 02:52:18 -04:00
|
|
|
;; 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))
|
|
|
|
|
2020-07-23 00:55:51 -04:00
|
|
|
;; HACK Smartparens will interfere with snippets expanded by `hippie-expand`,
|
|
|
|
;; so temporarily disable smartparens during snippet expansion.
|
|
|
|
(after! hippie-exp
|
|
|
|
(defvar +snippets--smartparens-enabled-p t)
|
|
|
|
(defvar +snippets--expanding-p nil)
|
|
|
|
|
|
|
|
;; Is called for all snippet expansions,
|
|
|
|
(add-hook! 'yas-before-expand-snippet-hook
|
|
|
|
(defun +snippets--disable-smartparens-before-expand-h ()
|
|
|
|
;; Remember the initial smartparens state only once, when expanding a
|
|
|
|
;; top-level snippet.
|
|
|
|
(unless +snippets--expanding-p
|
|
|
|
(setq +snippets--expanding-p t
|
|
|
|
+snippets--smartparens-enabled-p smartparens-mode))
|
|
|
|
(when smartparens-mode
|
|
|
|
(smartparens-mode -1))))
|
|
|
|
|
|
|
|
;; Is called only for the top level snippet, but not for the nested ones.
|
|
|
|
;; Hence `+snippets--expanding-p'.
|
|
|
|
(add-hook! 'yas-after-exit-snippet-hook
|
|
|
|
(defun +snippets--restore-smartparens-after-expand-h ()
|
|
|
|
(setq +snippets--expanding-p nil)
|
|
|
|
(when +snippets--smartparens-enabled-p
|
|
|
|
(smartparens-mode 1)))))
|
|
|
|
|
2020-04-24 04:07:57 -04:00
|
|
|
;; If in a daemon session, front-load this expensive work:
|
|
|
|
(if (daemonp) (yas-reload-all)))
|
2017-02-11 06:59:49 -05:00
|
|
|
|
|
|
|
|
2019-07-23 12:44:03 +02:00
|
|
|
(use-package! auto-yasnippet
|
2019-07-22 00:35:24 +02:00
|
|
|
:defer t
|
|
|
|
:config
|
2020-07-25 22:05:40 -04:00
|
|
|
(setq aya-persist-snippets-dir +snippets-dir)
|
2019-07-26 19:57:13 +02:00
|
|
|
(defadvice! +snippets--inhibit-yas-global-mode-a (orig-fn &rest args)
|
2019-07-22 00:35:24 +02:00
|
|
|
"auto-yasnippet enables `yas-global-mode'. This is obnoxious for folks like
|
|
|
|
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)
|
2020-04-29 21:08:17 -04:00
|
|
|
(letf! ((#'yas-global-mode #'yas-minor-mode)
|
|
|
|
(yas-global-mode yas-minor-mode))
|
2019-07-22 00:35:24 +02:00
|
|
|
(apply orig-fn args))))
|