This repository has been archived on 2024-10-22. You can view files and clone it, but cannot push or open issues or pull requests.
spacemacs/layers/+lang/clojure/packages.el
John Practicalli Stevenson f2c075b673 [clojure] key binding for cider eval list around point
New command added to CIDER in version 0.26 to evaluate the list around the
current point, different to evaluate sexp around point which also evaluates
symbols.

https://github.com/clojure-emacs/cider/pull/2881
2020-10-01 12:29:35 +02:00

585 lines
24 KiB
EmacsLisp

;;; packages.el --- Clojure Layer packages File for Spacemacs
;;
;; Copyright (c) 2012-2020 Sylvain Benner & Contributors
;;
;; Author: Sylvain Benner <sylvain.benner@gmail.com>
;; URL: https://github.com/syl20bnr/spacemacs
;;
;; This file is not part of GNU Emacs.
;;
;;; License: GPLv3
(setq clojure-packages
'(
cider
cider-eval-sexp-fu
(clj-refactor :toggle clojure-enable-clj-refactor)
(helm-cider :toggle (configuration-layer/layer-used-p 'helm))
clojure-mode
(clojure-snippets :toggle (configuration-layer/layer-used-p 'auto-completion))
company
eldoc
evil-cleverparens
flycheck
(flycheck-clojure :toggle (memq 'squiggly (if (listp clojure-enable-linters)
clojure-enable-linters
(list clojure-enable-linters))))
(flycheck-clj-kondo :toggle (memq 'clj-kondo (if (listp clojure-enable-linters)
clojure-enable-linters
(list clojure-enable-linters))))
(flycheck-joker :toggle (memq 'joker (if (listp clojure-enable-linters)
clojure-enable-linters
(list clojure-enable-linters))))
ggtags
counsel-gtags
helm-gtags
org
parinfer
popwin
(sayid :toggle clojure-enable-sayid)
smartparens
subword))
(defun clojure/init-cider ()
(use-package cider
:defer t
:init
(progn
(spacemacs/register-repl 'cider 'cider-jack-in "cider")
(setq cider-stacktrace-default-filters '(tooling dup)
cider-repl-pop-to-buffer-on-connect nil
cider-prompt-save-file-on-load nil
cider-repl-use-clojure-font-lock t
cider-repl-history-file (concat spacemacs-cache-directory "cider-repl-history"))
(add-hook 'clojure-mode-hook 'cider-mode)
(dolist (x '(spacemacs-jump-handlers-clojure-mode
spacemacs-jump-handlers-clojurec-mode
spacemacs-jump-handlers-clojurescript-mode
spacemacs-jump-handlers-clojurex-mode
spacemacs-jump-handlers-cider-repl-mode))
(add-to-list x '(spacemacs/clj-find-var :async t)))
;; TODO: having this work for cider-macroexpansion-mode would be nice,
;; but the problem is that it uses clojure-mode as its major-mode
(let ((cider--key-binding-prefixes
'(("m=" . "format")
("m=e" . "edn")
("md" . "debug")
("me" . "evaluation")
("mep" . "pretty print")
("mg" . "goto")
("mh" . "documentation")
("mm" . "manage repls")
("mml" . "link session")
("mmS" . "sibling sessions")
("mmq" . "quit/restart")
("mp" . "profile")
("ms" . "send to repl")
("msc" . "connect external repl")
("msj" . "jack-in")
("msq" . "quit/restart repl")
("mt" . "test")
("mT" . "toggle"))))
(spacemacs|forall-clojure-modes m
(mapc (lambda (x) (spacemacs/declare-prefix-for-mode
m (car x) (cdr x)))
cider--key-binding-prefixes)
(spacemacs/set-leader-keys-for-major-mode m
;; shortcuts
"'" 'sesman-start
;; help / documentation
"ha" 'cider-apropos
"hc" 'cider-cheatsheet
"hd" 'cider-clojuredocs
"hh" 'cider-doc
"hj" 'cider-javadoc
"hn" 'cider-browse-ns
"hN" 'cider-browse-ns-all
"hs" 'cider-browse-spec
"hS" 'cider-browse-spec-all
;; evaluate in source code buffer
"e;" 'cider-eval-defun-to-comment
"e$" 'spacemacs/cider-eval-sexp-end-of-line
"e(" 'cider-eval-list-at-point
"eb" 'cider-eval-buffer
"ee" 'cider-eval-last-sexp
"ef" 'cider-eval-defun-at-point
"ei" 'cider-interrupt
"el" 'spacemacs/cider-eval-sexp-end-of-line
"em" 'cider-macroexpand-1
"eM" 'cider-macroexpand-all
"en" 'cider-ns-refresh
"eN" 'cider-ns-reload ;; SPC u for cider-ns-reload-all
"ep;" 'cider-pprint-eval-defun-to-comment
"ep:" 'cider-pprint-eval-last-sexp-to-comment
"epf" 'cider-pprint-eval-defun-at-point
"epe" 'cider-pprint-eval-last-sexp
"er" 'cider-eval-region
"eu" 'cider-undef
"ev" 'cider-eval-sexp-at-point
"eV" 'cider-eval-sexp-up-to-point
"ew" 'cider-eval-last-sexp-and-replace
;; format code style
"==" 'cider-format-buffer
"=eb" 'cider-format-edn-buffer
"=ee" 'cider-format-edn-last-sexp
"=er" 'cider-format-edn-region
"=f" 'cider-format-defun
"=r" 'cider-format-region
;; goto
"gb" 'cider-pop-back
"gc" 'cider-classpath
"gg" 'spacemacs/clj-find-var
"ge" 'cider-jump-to-compilation-error
"gn" 'cider-find-ns
"gr" 'cider-find-resource
"gs" 'cider-browse-spec
"gS" 'cider-browse-spec-all
;; manage cider connections / sesman
"mb" 'sesman-browser
"mi" 'sesman-info
"mg" 'sesman-goto
"mlb" 'sesman-link-with-buffer
"mld" 'sesman-link-with-directory
"mlu" 'sesman-unlink
"mqq" 'sesman-quit
"mqr" 'sesman-restart
"mlp" 'sesman-link-with-project
"mSj" 'cider-connect-sibling-clj
"mSs" 'cider-connect-sibling-cljs
"ms" 'sesman-start
;; send code - spacemacs convention
"sa" (if (eq m 'cider-repl-mode)
'cider-switch-to-last-clojure-buffer
'cider-switch-to-repl-buffer)
"sb" 'cider-load-buffer
"sB" 'spacemacs/cider-send-buffer-in-repl-and-focus
"scj" 'cider-connect-clj
"scm" 'cider-connect-clj&cljs
"scs" 'cider-connect-cljs
"se" 'spacemacs/cider-send-last-sexp-to-repl
"sE" 'spacemacs/cider-send-last-sexp-to-repl-focus
"sf" 'spacemacs/cider-send-function-to-repl
"sF" 'spacemacs/cider-send-function-to-repl-focus
"si" 'sesman-start
"sjj" 'cider-jack-in-clj
"sjm" 'cider-jack-in-clj&cljs
"sjs" 'cider-jack-in-cljs
"sl" 'spacemacs/cider-find-and-clear-repl-buffer
"sL" 'cider-find-and-clear-repl-output
"sn" 'spacemacs/cider-send-ns-form-to-repl
"sN" 'spacemacs/cider-send-ns-form-to-repl-focus
"so" 'cider-repl-switch-to-other
"sqq" 'cider-quit
"sqr" 'cider-restart
"sqn" 'cider-ns-reload
"sqN" 'cider-ns-reload-all
"sr" 'spacemacs/cider-send-region-to-repl
"sR" 'spacemacs/cider-send-region-to-repl-focus
"su" 'cider-repl-require-repl-utils
;; toggle options
"Te" 'cider-enlighten-mode
"Tf" 'spacemacs/cider-toggle-repl-font-locking
"Tp" 'spacemacs/cider-toggle-repl-pretty-printing
"Tt" 'cider-auto-test-mode
;; cider-tests
"ta" 'spacemacs/cider-test-run-all-tests
"tb" 'cider-test-show-report
"tl" 'spacemacs/cider-test-run-loaded-tests
"tn" 'spacemacs/cider-test-run-ns-tests
"tp" 'spacemacs/cider-test-run-project-tests
"tr" 'spacemacs/cider-test-rerun-failed-tests
"tt" 'spacemacs/cider-test-run-focused-test
;; cider-debug
"db" 'cider-debug-defun-at-point
"de" 'spacemacs/cider-display-error-buffer
"dv" 'cider-inspect
;; profile
"p+" 'cider-profile-samples
"pc" 'cider-profile-clear
"pn" 'cider-profile-ns-toggle
"ps" 'cider-profile-var-summary
"pS" 'cider-profile-summary
"pt" 'cider-profile-toggle
"pv" 'cider-profile-var-profiled-p)))
;; cider-repl-mode only
(spacemacs/set-leader-keys-for-major-mode 'cider-repl-mode
"," 'cider-repl-handle-shortcut)
(spacemacs/set-leader-keys-for-major-mode 'cider-clojure-interaction-mode
"epl" 'cider-eval-print-last-sexp))
:config
(progn
;; add support for golden-ratio
(with-eval-after-load 'golden-ratio
(add-to-list 'golden-ratio-extra-commands 'cider-popup-buffer-quit-function))
;; add support for evil
(evil-set-initial-state 'cider-stacktrace-mode 'motion)
(evil-set-initial-state 'cider-popup-buffer-mode 'motion)
(add-hook 'cider--debug-mode-hook 'spacemacs/cider-debug-setup)
(evilified-state-evilify cider-stacktrace-mode cider-stacktrace-mode-map
(kbd "C-j") 'cider-stacktrace-next-cause
(kbd "C-k") 'cider-stacktrace-previous-cause
(kbd "TAB") 'cider-stacktrace-cycle-current-cause
(kbd "0") 'cider-stacktrace-cycle-all-causes
(kbd "1") 'cider-stacktrace-cycle-cause-1
(kbd "2") 'cider-stacktrace-cycle-cause-2
(kbd "3") 'cider-stacktrace-cycle-cause-3
(kbd "4") 'cider-stacktrace-cycle-cause-4
(kbd "5") 'cider-stacktrace-cycle-cause-5
(kbd "a") 'cider-stacktrace-toggle-all
(kbd "c") 'cider-stacktrace-toggle-clj
(kbd "d") 'cider-stacktrace-toggle-duplicates
(kbd "J") 'cider-stacktrace-toggle-java
(kbd "r") 'cider-stacktrace-toggle-repl
(kbd "T") 'cider-stacktrace-toggle-tooling)
;; open cider-doc directly and close it with q
(setq cider-prompt-for-symbol nil)
(evilified-state-evilify cider-docview-mode cider-docview-mode-map
(kbd "q") 'cider-popup-buffer-quit)
(evilified-state-evilify cider-inspector-mode cider-inspector-mode-map
(kbd "L") 'cider-inspector-pop
(kbd "n") 'cider-inspector-next-page
(kbd "N") 'cider-inspector-prev-page
(kbd "p") 'cider-inspector-prev-page
(kbd "r") 'cider-inspector-refresh)
(evilified-state-evilify cider-test-report-mode cider-test-report-mode-map
(kbd "C-j") 'cider-test-next-result
(kbd "C-k") 'cider-test-previous-result
(kbd "RET") 'cider-test-jump
(kbd "d") 'cider-test-ediff
(kbd "e") 'cider-test-stacktrace
(kbd "q") 'cider-popup-buffer-quit
(kbd "r") 'cider-test-rerun-tests
(kbd "t") 'cider-test-run-test
(kbd "T") 'cider-test-run-ns-tests)
(evil-define-key 'normal cider-repl-mode-map
(kbd "C-j") 'cider-repl-next-input
(kbd "C-k") 'cider-repl-previous-input
(kbd "RET") 'cider-repl-return)
(if (package-installed-p 'company)
(evil-define-key 'insert cider-repl-mode-map
(kbd "C-j") 'spacemacs//clj-repl-wrap-c-j
(kbd "C-k") 'spacemacs//clj-repl-wrap-c-k)
(evil-define-key 'insert cider-repl-mode-map
(kbd "C-j") 'cider-repl-next-input
(kbd "C-k") 'cider-repl-previous-input))
(evil-define-key 'insert cider-repl-mode-map
(kbd "<C-return>") 'cider-repl-newline-and-indent)
(when clojure-enable-fancify-symbols
(clojure/fancify-symbols 'cider-repl-mode)
(clojure/fancify-symbols 'cider-clojure-interaction-mode)))
(defadvice cider-find-var (before add-evil-jump activate)
(evil-set-jump))))
(defun clojure/init-cider-eval-sexp-fu ()
(with-eval-after-load 'eval-sexp-fu
(require 'cider-eval-sexp-fu)))
(defun clojure/init-clj-refactor ()
(use-package clj-refactor
:defer t
:init
(add-hook 'clojure-mode-hook 'clj-refactor-mode)
:config
(progn
(cljr-add-keybindings-with-prefix "C-c C-f")
;; Usually we do not set keybindings in :config, however this must be done
;; here because it reads the variable `cljr--all-helpers'. Since
;; `clj-refactor-mode' is added to the hook, this should trigger when a
;; clojure buffer is opened anyway, so there's no "keybinding delay".
(spacemacs|forall-clojure-modes m
(dolist (r cljr--all-helpers)
(let* ((binding (car r))
(func (cadr r)))
(when (not (string-prefix-p "hydra" (symbol-name func)))
(spacemacs/set-leader-keys-for-major-mode m
(concat "r" binding) func))))))))
(defun clojure/init-helm-cider ()
(use-package helm-cider
:defer t
:init
(progn
(add-hook 'clojure-mode-hook 'helm-cider-mode)
(setq sayid--key-binding-prefixes
'(("mhc" . "helm-cider-cheatsheet")))
(spacemacs|forall-clojure-modes m
(mapc (lambda (x) (spacemacs/declare-prefix-for-mode
m (car x) (cdr x)))
sayid--key-binding-prefixes)
(spacemacs/set-leader-keys-for-major-mode m
"hc" 'helm-cider-cheatsheet)))))
(defun clojure/init-clojure-mode ()
(use-package clojure-mode
:defer t
:init
(progn
(add-to-list 'auto-mode-alist '("\\.boot\\'" . clojure-mode))
;; This regexp matches shebang expressions like `#!/usr/bin/env boot'
(add-to-list 'magic-mode-alist '("#!.*boot\\s-*$" . clojure-mode))
;; Define all the prefixes here, although most of them apply only to bindings in clj-refactor
(let ((clj-refactor--key-binding-prefixes
'(("mr" . "refactor")
("mra" . "add")
("mrc" . "cycle/clean/convert")
("mrd" . "destructure")
("mre" . "extract/expand")
("mrf" . "find/function")
("mrh" . "hotload")
("mri" . "introduce/inline")
("mrm" . "move")
("mrp" . "project/promote")
("mrr" . "remove/rename/replace")
("mrs" . "show/sort/stop")
("mrt" . "thread")
("mru" . "unwind/update"))))
(spacemacs|forall-clojure-modes m
(mapc (lambda (x) (spacemacs/declare-prefix-for-mode
m (car x) (cdr x)))
clj-refactor--key-binding-prefixes)
(spacemacs/set-leader-keys-for-major-mode m
"=l" 'clojure-align
"ran" 'clojure-insert-ns-form
"raN" 'clojure-insert-ns-form-at-point
"rci" 'clojure-cycle-if
"rcp" 'clojure-cycle-privacy
"rc#" 'clojure-convert-collection-to-set
"rc'" 'clojure-convert-collection-to-quoted-list
"rc(" 'clojure-convert-collection-to-list
"rc[" 'clojure-convert-collection-to-vector
"rc{" 'clojure-convert-collection-to-map
"rc:" 'clojure-toggle-keyword-string
"rsn" 'clojure-sort-ns
"rtf" 'clojure-thread-first-all
"rth" 'clojure-thread
"rtl" 'clojure-thread-last-all
"rua" 'clojure-unwind-all
"ruw" 'clojure-unwind)
(unless clojure-enable-clj-refactor
(spacemacs/set-leader-keys-for-major-mode m
"r?" 'spacemacs/clj-describe-missing-refactorings)))))
:config
(when clojure-enable-fancify-symbols
(spacemacs|forall-clojure-modes m
(clojure/fancify-symbols m)))))
(defun clojure/post-init-eldoc ()
(add-hook 'cider-mode-hook 'eldoc-mode)
(add-hook 'cider-repl-mode-hook 'eldoc-mode)
(add-hook 'cider-clojure-interaction-mode-hook 'eldoc-mode))
(defun clojure/pre-init-evil-cleverparens ()
(spacemacs|use-package-add-hook evil-cleverparens
:pre-init
(spacemacs|forall-clojure-modes m
(add-to-list 'evil-lisp-safe-structural-editing-modes m))))
(defun clojure/pre-init-popwin ()
(spacemacs|use-package-add-hook popwin
:post-config
(push '("*cider-error*" :dedicated t :position bottom :stick t :noselect nil :height 0.4)
popwin:special-display-config)
(push '("*cider-doc*" :dedicated t :position bottom :stick t :noselect nil :height 0.4)
popwin:special-display-config)))
(defun clojure/post-init-smartparens ()
(add-hook 'cider-repl-mode-hook
(if dotspacemacs-smartparens-strict-mode
#'smartparens-strict-mode
#'smartparens-mode))
(with-eval-after-load 'smartparens
(sp-local-pair 'clojure-mode "`" nil :actions nil)))
(defun clojure/post-init-subword ()
(add-hook 'cider-mode-hook 'subword-mode))
(defun clojure/post-init-company ()
(spacemacs|add-company-backends
:backends company-capf
:modes
cider-mode
cider-repl-mode))
(defun clojure/post-init-ggtags ()
(add-hook 'clojure-mode-local-vars-hook #'spacemacs/ggtags-mode-enable))
(defun clojure/post-init-counsel-gtags ()
(spacemacs/counsel-gtags-define-keys-for-mode 'clojure-mode))
(defun clojure/post-init-helm-gtags ()
(spacemacs/helm-gtags-define-keys-for-mode 'clojure-mode))
(defun clojure/init-clojure-snippets ()
(use-package clojure-snippets
:defer t))
(defun clojure/pre-init-org ()
(spacemacs|use-package-add-hook org
:post-config (add-to-list 'org-babel-load-languages '(clojure . t))
(setq org-babel-clojure-backend 'cider)))
(defun clojure/init-sayid ()
(use-package sayid
:defer t
:init
(progn
(setq sayid--key-binding-prefixes
'(("mdt" . "trace")))
(spacemacs|forall-clojure-modes m
(mapc (lambda (x) (spacemacs/declare-prefix-for-mode m
(car x) (cdr x)))
sayid--key-binding-prefixes)
(spacemacs/set-leader-keys-for-major-mode m
;;These keybindings mostly preserved from the default sayid bindings
"d!" 'sayid-load-enable-clear
"dE" 'sayid-eval-last-sexp ;in default sayid bindings this is lowercase e, but that was already used in clojure mode
"dc" 'sayid-clear-log
"df" 'sayid-query-form-at-point
"dh" 'sayid-show-help
"ds" 'sayid-show-traced
"dS" 'sayid-show-traced-ns
"dtb" 'sayid-trace-ns-in-file
"dtd" 'sayid-trace-fn-disable
"dtD" 'sayid-trace-disable-all
"dte" 'sayid-trace-fn-enable
"dtE" 'sayid-trace-enable-all
"dtK" 'sayid-kill-all-traces
"dtn" 'sayid-inner-trace-fn
"dto" 'sayid-outer-trace-fn
"dtp" 'sayid-trace-ns-by-pattern
"dtr" 'sayid-remove-trace-fn
"dty" 'sayid-trace-all-ns-in-dir
"dV" 'sayid-set-view
"dw" 'sayid-get-workspace
"dx" 'sayid-reset-workspace))
(evilified-state-evilify sayid-mode sayid-mode-map
(kbd "H") 'sayid-buf-show-help
(kbd "n") 'sayid-buffer-nav-to-next
(kbd "N") 'sayid-buffer-nav-to-prev
(kbd "C-s v") 'sayid-toggle-view
(kbd "C-s V") 'sayid-set-view
(kbd "L") 'sayid-buf-back
(kbd "e") 'sayid-gen-instance-expr) ;Originally this was bound to 'g', but I feel this is still mnemonic and doesn't overlap with evil
(evilified-state-evilify sayid-pprint-mode sayid-pprint-mode-map
(kbd "h") 'sayid-pprint-buf-show-help
(kbd "n") 'sayid-pprint-buf-next
(kbd "N") 'sayid-pprint-buf-prev
(kbd "l") 'sayid-pprint-buf-exit)
(evilified-state-evilify sayid-traced-mode sayid-traced-mode-map
(kbd "l") 'sayid-show-traced
(kbd "h") 'sayid-traced-buf-show-help))
:config
(progn
;; If sayid-version is null the .elc file
;; is corrupted. Then force a reinstall and
;; reload the feature.
(when (null sayid-version)
(package-reinstall 'sayid)
(unload-feature 'sayid)
(require 'sayid)
(setq cider-jack-in-lein-plugins (delete `("com.billpiel/sayid" nil) cider-jack-in-lein-plugins))))))
(defun clojure/post-init-parinfer ()
(add-hook 'clojure-mode-hook 'parinfer-mode))
(defun clojure/post-init-flycheck ()
;; When user has chosen to use multiple linters.
(when (> (safe-length clojure-enable-linters) 1)
;; If adding a linter, you must add to checkers-per-mode for each mode
;; it can support the mapping from the linter name in clojure-enable-linters
;; to the flycheck checker to use to add to flycheck.
(let* ((checkers-per-mode '((clj . ((clj-kondo . clj-kondo-clj)
(joker . clojure-joker)
(squiggly . clojure-cider-eastwood)))
(cljc . ((clj-kondo . clj-kondo-cljc)
(joker . clojure-joker)))
(cljs . ((clj-kondo . clj-kondo-cljs)
(joker . clojurescript-joker)))
(edn . ((clj-kondo . clj-kondo-edn)
(joker . edn-joker))))))
;; For each checker mode
(dolist (mode-checkers checkers-per-mode)
;; We find the first checker in order from the user configured linters which
;; the mode supports and make it the primary-linter. All other linters after that
;; the mode support is made a next-linter. Finally, we extract the checkers of the
;; primary linter and the next linters.
(let* ((checkers (cdr mode-checkers))
(primary-linter (seq-find (lambda (l)
(assq l checkers))
clojure-enable-linters))
(primary-checker (cdr (assq primary-linter checkers)))
(next-linters (seq-filter (lambda (l)
(and (not (eq l primary-linter))
(assq l checkers)))
clojure-enable-linters))
(next-checkers (mapcar (lambda (l)
(cdr (assq l checkers)))
next-linters)))
;; Move primary checker to the front of flycheck lists of checkers so that
;; it is used as the primary checker, because flycheck picks the first one
;; it finds.
(delq primary-checker flycheck-checkers)
(push primary-checker flycheck-checkers)
;; For every checker, set their next checkers, starting with the primary
;; checker which has all others has a next-checker, and then the next
;; one has all the ones after it, and so on, until the last one which
;; has no next-checker to be added. This is because flycheck next-checkers
;; must be nested if we want more than two to run. It will pick the first
;; available next-checker from next-checkers and run that after. If we want
;; a checker after that one, it must also have next-checkers configured.
(let ((checkers-to-add next-checkers))
(dolist (checker (cons primary-checker next-checkers))
(dolist (next-checker checkers-to-add)
(flycheck-add-next-checker checker next-checker t))
(setq checkers-to-add (cdr checkers-to-add))))))))
(spacemacs|forall-clojure-modes m
(spacemacs/enable-flycheck m)))
(defun clojure/init-flycheck-clojure ()
(use-package flycheck-clojure
:if (configuration-layer/package-usedp 'flycheck)
:config (progn
(flycheck-clojure-setup)
(with-eval-after-load 'cider
(flycheck-clojure-inject-jack-in-dependencies)))))
(defun clojure/init-flycheck-clj-kondo ()
(use-package flycheck-clj-kondo
:if (configuration-layer/package-usedp 'flycheck)))
(defun clojure/init-flycheck-joker ()
(use-package flycheck-joker
:if (configuration-layer/package-usedp 'flycheck)))