From 309e6eb4bba7d768ee293b54006c1ac4fbe08c6c Mon Sep 17 00:00:00 2001 From: MadAnd Date: Sun, 7 Aug 2016 20:35:59 +0300 Subject: [PATCH] Fix smartparens after nested snippet expansions Current implementation, #1644, doesn't handle the nested snippet expansion properly, so you end up with smarparens disabled. Very annoying. I improved the implementation to remember the current state of smartaperns before a top-level snippet expansion and preserve on any nested snippet expansions. Also, some housekeeping of the related code: * Move hook handlers to the `funcs.el`. * Add comments about yasnippet hooks subtleties relevant to the issue. Fixes #1512 --- layers/+completion/auto-completion/funcs.el | 36 +++++++++++++++++++ .../+completion/auto-completion/packages.el | 13 ++----- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/layers/+completion/auto-completion/funcs.el b/layers/+completion/auto-completion/funcs.el index 13ffdf175..426b8aeab 100644 --- a/layers/+completion/auto-completion/funcs.el +++ b/layers/+completion/auto-completion/funcs.el @@ -220,3 +220,39 @@ (interactive) (call-interactively 'aya-expand) (unless holy-mode (evil-insert-state))) + + +;; Yasnippet and Smartparens + +;; If enabled, smartparens will mess snippets expanded by `hippie-expand`. +;; We want to temporarily disable Smartparens during the snippet expansion and +;; switch it back to the initial state when done. +;; +;; However, there is an asymmetry in Yasnippet's hooks: +;; * `yas-before-expand-snippet-hook' is called for all snippet expansions, +;; including the nested ones. +;; * `yas-after-exit-snippet-hook' is called only for the top level snippet, +;; but NOT for the nested ones. +;; +;; That's why we introduce `spacemacs--yasnippet-expanding' below. + +(defvar spacemacs--smartparens-enabled-initially t + "Stored whether smartparens is originally enabled or not.") +(defvar spacemacs--yasnippet-expanding nil + "Whether the snippet expansion is in progress.") + +(defun spacemacs//smartparens-disable-before-expand-snippet () + "Handler for `yas-before-expand-snippet-hook'. +Disable smartparens and remember its initial state." + ;; Remember the initial smartparens state only once, when expanding a top-level snippet. + (unless spacemacs--yasnippet-expanding + (setq spacemacs--yasnippet-expanding t + spacemacs--smartparens-enabled-initially smartparens-mode)) + (smartparens-mode -1)) + +(defun spacemacs//smartparens-restore-after-exit-snippet () + "Handler for `yas-after-exit-snippet-hook'. + Restore the initial state of smartparens." + (setq spacemacs--yasnippet-expanding nil) + (when spacemacs--smartparens-enabled-initially + (smartparens-mode 1))) diff --git a/layers/+completion/auto-completion/packages.el b/layers/+completion/auto-completion/packages.el index d0edef7c4..22ef79a49 100644 --- a/layers/+completion/auto-completion/packages.el +++ b/layers/+completion/auto-completion/packages.el @@ -246,16 +246,7 @@ (defun auto-completion/post-init-smartparens () (with-eval-after-load 'smartparens - ;; We need to know whether the smartparens was enabled, see - ;; `yas-before-expand-snippet-hook' below. - (defvar smartparens-enabled-initially t - "Stored whether smartparens is originally enabled or not.") (add-hook 'yas-before-expand-snippet-hook - (lambda () - ;; If enabled, smartparens will mess snippets expanded by `hippie-expand` - (setq smartparens-enabled-initially smartparens-mode) - (smartparens-mode -1))) + #'spacemacs//smartparens-disable-before-expand-snippet) (add-hook 'yas-after-exit-snippet-hook - (lambda () - (when smartparens-enabled-initially - (smartparens-mode 1)))))) + #'spacemacs//smartparens-restore-after-exit-snippet)))