about summary refs log blame commit diff stats
path: root/.emacs.d/lisp/init-paredit.el
blob: 73c8267fa86a690e50c4b79d8a5d9c3858f98af4 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

















                                                                                                    







                                                                           



                                          
 
       




































































                                                                               
                                                              


























                                                   
                           






                                                                    




                                             
;;; init-paredit.el --- Paredit Configuration File -*- lexical-binding: t -*-
;;; Commentary:
;; add-hooks/add-lisp-hook based on https://github.com/bodil/emacs.d/blob/master/bodil/bodil-lisp.el
;;; Code:

(defun add-hooks (modes func)
 (dolist (mode modes)
  (add-hook (intern (concat (symbol-name mode) "-hook")) func)))

(setq lisp-modes
 '(scheme-mode emacs-lisp-mode lisp-mode clojure-mode cider-repl-mode
   eval-expression-minibuffer-setup ielm-mode lisp-interaction-mode))

(defun add-lisp-hook (func)
  (add-hooks lisp-modes func))

(use-package paredit
  :diminish
  :bind
  (:map paredit-mode-map
        ([remap mark-sexp] . sp-mark-sexp)
        ("M-[" . sp-wrap-square)
        ("C-c M-{" . sp-wrap-curly)
        ([remap paredit-wrap-round] . sp-wrap-round)
        ([remap paredit-meta-doublequote] . sp-wrap-double-quotation-marks)
        ("M-W" . paredit-copy-as-kill))
  :config
  (defun sp-wrap-double-quotation-marks ()
    (interactive)
    (sp-wrap-with-pair "\""))

  :init
  ;; From emacswiki - extreme barfage & slurpage
  (defun paredit-barf-all-the-way-backward ()
    (interactive)
    (paredit-split-sexp)
    (paredit-backward-down)
    (paredit-splice-sexp))
  (defun paredit-barf-all-the-way-forward ()
    (interactive)
    (paredit-split-sexp)
    (paredit-forward-down)
    (paredit-splice-sexp)
    (if (eolp) (delete-horizontal-space)))
  (defun paredit-slurp-all-the-way-backward ()
    (interactive)
    (catch 'done
      (while (not (bobp))
        (save-excursion
          (paredit-backward-up)
          (if (eq (char-before) ?\()
              (throw 'done t)))
        (paredit-backward-slurp-sexp))))
  (defun paredit-slurp-all-the-way-forward ()
    (interactive)
    (catch 'done
      (while (not (eobp))
        (save-excursion
          (paredit-forward-up)
          (if (eq (char-after) ?\))
              (throw 'done t)))
        (paredit-forward-slurp-sexp))))

  ;; From https://github.com/bodil/emacs.d/blob/master/bodil/bodil-paredit.el
  ;; Inverse M-(
  (defun paredit-wrap-round-from-behind ()
    (interactive)
    (forward-sexp -1)
    (paredit-wrap-round)
    (insert " ")
    (forward-char -1))
  ;; From https://github.com/bodil/emacs.d/blob/master/bodil/bodil-paredit.el
  ;; Duplicate sexp
  (defun paredit-duplicate-after-point ()
    "Duplicates the content of the line that is after the point."
    (interactive)
    ;; skips to the next sexp
    (while (looking-at " ")
      (forward-char))
    (set-mark-command nil)
    ;; while we find sexps we move forward on the line
    (while (and (<= (point) (car (bounds-of-thing-at-point 'sexp)))
                (not (= (point) (line-end-position))))
      (forward-sexp)
      (while (looking-at " ")
        (forward-char)))
    (kill-ring-save (mark) (point))
    ;; go to the next line and copy the sexprs we encountered
    (paredit-newline)
    (set-mark-command nil)
    (yank)
    (exchange-point-and-mark))

  (defun replace-paredit-binding (commands original-keys new-keys)
    (when commands
      (if (and (consp (car commands))
               (equal (caar commands) original-keys))
          (setcar (car commands) new-keys)
        (replace-paredit-binding (cdr commands) original-keys new-keys))))
  (defun paredit-commands-advice ()
    ;; Default paredit-convolute-sexp binding clashes with xref-find-references
    (replace-paredit-binding paredit-commands "M-?" "C-c M-?")

    (nconc paredit-commands
           '("Extreme Barfage & Slurpage"
             (("C-M-)")
              paredit-slurp-all-the-way-forward
              ("(foo (bar |baz) quux zot)"
               "(foo (bar |baz quux zot))")
              ("(a b ((c| d)) e f)"
               "(a b ((c| d)) e f)"))
             (("C-M-}" "M-F")
              paredit-barf-all-the-way-forward
              ("(foo (bar |baz quux) zot)"
               "(foo (bar|) baz quux zot)"))
             (("C-M-(")
              paredit-slurp-all-the-way-backward
              ("(foo bar (baz| quux) zot)"
               "((foo bar baz| quux) zot)")
              ("(a b ((c| d)) e f)"
               "(a b ((c| d)) e f)"))
             (("C-M-{" "M-B")
              paredit-barf-all-the-way-backward
              ("(foo (bar baz |quux) zot)"
               "(foo bar baz (|quux) zot)")))
           '("Extra"
             (("C-c M-)")
              paredit-wrap-round-from-behind
              ("(foo| bar baz" "((| foo) bar baz"))
             (("C-c C-S-d")
              paredit-duplicate-after-point
              ("|(foo)" "(foo)\n|(foo)"))))

    ;; Only need to do this once
    (advice-remove 'paredit-define-keys 'paredit-commands-advice))

  (advice-add 'paredit-define-keys :before 'paredit-commands-advice)
  (add-lisp-hook #'turn-off-smartparens-mode)
  (add-lisp-hook #'enable-paredit-mode))

(provide 'init-paredit)
;;; init-paredit.el ends here