diff --git a/modules/config/default/+evil.el b/modules/config/default/+evil.el index 5d624abed..e1c7eddb6 100644 --- a/modules/config/default/+evil.el +++ b/modules/config/default/+evil.el @@ -6,94 +6,6 @@ (add-hook 'evil-insert-state-exit-hook #'+default|disable-delete-selection-mode) -;; -;;; Smartparens config - -(when (featurep! +smartparens) - ;; You can disable :unless predicates with (sp-pair "'" nil :unless nil) - ;; And disable :post-handlers with (sp-pair "{" nil :post-handlers nil) - ;; or specific :post-handlers with: - ;; (sp-pair "{" nil :post-handlers '(:rem ("| " "SPC"))) - (after! smartparens - ;; Autopair quotes more conservatively; if I'm next to a word/before another - ;; quote, I likely don't want to open a new pair. - (let ((unless-list '(sp-point-before-word-p - sp-point-after-word-p - sp-point-before-same-p))) - (sp-pair "'" nil :unless unless-list) - (sp-pair "\"" nil :unless unless-list)) - - ;; Expand {|} => { | } - ;; Expand {|} => { - ;; | - ;; } - (dolist (brace '("(" "{" "[")) - (sp-pair brace nil - :post-handlers '(("||\n[i]" "RET") ("| " "SPC")) - ;; I likely don't want a new pair if adjacent to a word or opening brace - :unless '(sp-point-before-word-p sp-point-before-same-p))) - - ;; Major-mode specific fixes - (sp-local-pair '(ruby-mode enh-ruby-mode) "{" "}" - :pre-handlers '(:rem sp-ruby-pre-handler) - :post-handlers '(:rem sp-ruby-post-handler)) - - ;; 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"))) - - ;; Reasonable default pairs for HTML-style comments - (sp-local-pair (append sp--html-modes '(markdown-mode gfm-mode)) - "" - :unless '(sp-point-before-word-p sp-point-before-same-p) - :actions '(insert) :post-handlers '(("| " "SPC"))) - - ;; 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) - (dolist (key '("#" "{" "}" "/" "*" ";" "," ":" "(" ")" "\177")) - (define-key c-mode-base-map key nil))) - - ;; Expand C-style doc comment blocks. Must be done manually because some of - ;; these languages use specialized (and deferred) parsers, whose state we - ;; can't access while smartparens is doing its thing. - (defun +default-expand-doc-comment-block (&rest _ignored) - (let ((indent (current-indentation))) - (newline-and-indent) - (save-excursion - (newline) - (insert (make-string indent 32) " */") - (delete-char 2)))) - (sp-local-pair - '(js2-mode typescript-mode rjsx-mode rust-mode c-mode c++-mode objc-mode - csharp-mode java-mode php-mode css-mode scss-mode less-css-mode - stylus-mode) - "/*" "*/" - :actions '(insert) - :post-handlers '(("| " "SPC") ("|\n*/[i][d-2]" "RET") (+default-expand-doc-comment-block "*"))) - - ;; Highjacks backspace to: - ;; a) balance spaces inside brackets/parentheses ( | ) -> (|) - ;; b) delete space-indented `tab-width' steps 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) - - ;; Makes `newline-and-indent' continue comments (and more reliably) - (advice-add #'newline-and-indent :around #'+default*newline-indent-and-continue-comments))) - - ;; ;;; Keybindings diff --git a/modules/config/default/config.el b/modules/config/default/config.el index c8c341e03..88b984898 100644 --- a/modules/config/default/config.el +++ b/modules/config/default/config.el @@ -27,6 +27,94 @@ epa-pinentry-mode 'loopback)) +;; +;;; Smartparens config + +(when (featurep! +smartparens) + ;; You can disable :unless predicates with (sp-pair "'" nil :unless nil) + ;; And disable :post-handlers with (sp-pair "{" nil :post-handlers nil) + ;; or specific :post-handlers with: + ;; (sp-pair "{" nil :post-handlers '(:rem ("| " "SPC"))) + (after! smartparens + ;; Autopair quotes more conservatively; if I'm next to a word/before another + ;; quote, I likely don't want to open a new pair. + (let ((unless-list '(sp-point-before-word-p + sp-point-after-word-p + sp-point-before-same-p))) + (sp-pair "'" nil :unless unless-list) + (sp-pair "\"" nil :unless unless-list)) + + ;; Expand {|} => { | } + ;; Expand {|} => { + ;; | + ;; } + (dolist (brace '("(" "{" "[")) + (sp-pair brace nil + :post-handlers '(("||\n[i]" "RET") ("| " "SPC")) + ;; I likely don't want a new pair if adjacent to a word or opening brace + :unless '(sp-point-before-word-p sp-point-before-same-p))) + + ;; Major-mode specific fixes + (sp-local-pair '(ruby-mode enh-ruby-mode) "{" "}" + :pre-handlers '(:rem sp-ruby-pre-handler) + :post-handlers '(:rem sp-ruby-post-handler)) + + ;; 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"))) + + ;; Reasonable default pairs for HTML-style comments + (sp-local-pair (append sp--html-modes '(markdown-mode gfm-mode)) + "" + :unless '(sp-point-before-word-p sp-point-before-same-p) + :actions '(insert) :post-handlers '(("| " "SPC"))) + + ;; 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) + (dolist (key '("#" "{" "}" "/" "*" ";" "," ":" "(" ")" "\177")) + (define-key c-mode-base-map key nil))) + + ;; Expand C-style doc comment blocks. Must be done manually because some of + ;; these languages use specialized (and deferred) parsers, whose state we + ;; can't access while smartparens is doing its thing. + (defun +default-expand-doc-comment-block (&rest _ignored) + (let ((indent (current-indentation))) + (newline-and-indent) + (save-excursion + (newline) + (insert (make-string indent 32) " */") + (delete-char 2)))) + (sp-local-pair + '(js2-mode typescript-mode rjsx-mode rust-mode c-mode c++-mode objc-mode + csharp-mode java-mode php-mode css-mode scss-mode less-css-mode + stylus-mode) + "/*" "*/" + :actions '(insert) + :post-handlers '(("| " "SPC") ("|\n*/[i][d-2]" "RET") (+default-expand-doc-comment-block "*"))) + + ;; Highjacks backspace to: + ;; a) balance spaces inside brackets/parentheses ( | ) -> (|) + ;; b) delete space-indented `tab-width' steps 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) + + ;; Makes `newline-and-indent' continue comments (and more reliably) + (advice-add #'newline-and-indent :around #'+default*newline-indent-and-continue-comments))) + + ;; ;;; Keybinding fixes