Skip to content

Instantly share code, notes, and snippets.

@jasonjckn
Last active April 13, 2020 19:09
Show Gist options
  • Save jasonjckn/efe33cd7dc244991db27aca2a7dc9125 to your computer and use it in GitHub Desktop.
Save jasonjckn/efe33cd7dc244991db27aca2a7dc9125 to your computer and use it in GitHub Desktop.
evil-eval-motion.el
;;; ~/.doom.d/+evil-enhancements.el -*- lexical-binding: t; -*-
(defun outer-sexp-at-region (beg end &optional skip-comment?)
(pcase-let ((`(,beg1 ,end1)
(save-excursion
(save-match-data
(goto-char beg)
(sp-forward-whitespace)
(when skip-comment?
(if (string= "#" (char-to-string (char-after (point))))
(sp-forward-sexp)))
(sp-forward-sexp)
(let ((end (point)))
(sp-backward-sexp)
(list (point) end)))))
(`(,beg2 ,end2)
(save-excursion
(save-match-data
(goto-char (- end 1))
(beginning-of-line)
(sp-forward-whitespace)
(when skip-comment?
(if (string= "#" (char-to-string (char-after (point))))
(sp-forward-sexp)))
(sp-forward-sexp)
(let ((end (point)))
(sp-backward-sexp)
(list (point) end))))))
(list (min beg1 beg2) (max end1 end2))))
(defun eros-eval-region (start end)
(eros--eval-overlay
(let ((output-buffer (generate-new-buffer "*temp*")))
(eval-region start end output-buffer)
(let ((res (with-current-buffer output-buffer (buffer-string))))
(kill-buffer output-buffer)
(string-trim res)))
end))
(defcustom evil-extra-operator-eval-region-modes-alist
'((lisp-mode slime-eval-region)
(emacs-lisp-mode eros-eval-region)
(scheme-mode geiser-eval-region)
(clojure-mode cider-eval-region)
(ruby-mode ruby-send-region)
(enh-ruby-mode ruby-send-region)
(python-mode python-shell-send-region)
(julia-mode julia-shell-run-region))
""
:type '(alist :key-type symbol)
:group 'evil-extra-operator)
(defcustom evil-extra-operator-eval-buffer-modes-alist
'((clojure-mode cider-load-buffer))
""
:type '(alist :key-type symbol)
:group 'evil-extra-operator)
(defface eval-motion-overlay-face10
'((((class color) (background light))
:background "#b3d9ff" :box (:line-width -1 :color "grey90"))
(((class color) (background dark))
:background "grey10" :box (:line-width -1 :color "black")))
"")
(defface eval-motion-overlay-face17
'((((class color) (background light))
:background "#9ebcbb") ;;#d9b3ff
(((class color) (background dark))
:background "grey10" :box (:line-width -1 :color "black")))
"")
(defun create-eval-motion-overlay (beg end &optional face)
(let ((overlay (make-overlay beg end)))
(overlay-put overlay 'font-lock-face (or face 'eval-motion-overlay-face10))
(overlay-put overlay 'modification-hooks (list (lambda (o &rest _args) (delete-overlay o))))
(run-at-time "1 sec" nil #'delete-overlay overlay)))
(evil-define-operator evil-eval-motion (beg end type register yank-handler)
"Evil operator for evaluating code."
:move-point nil
(interactive "<R><x><y>")
(cond
;; load whole file buffer
((and (not register) (= beg 1))
(pcase-let* ((`(,_ ,ele-buffer) (assoc major-mode evil-extra-operator-eval-buffer-modes-alist))
(`(,_ ,ele-region) (assoc major-mode evil-extra-operator-eval-region-modes-alist)))
(cond (ele-buffer
(funcall ele-buffer)
(create-eval-motion-overlay (point-min) (point-max)))
(ele-region
(funcall ele-region (point-min) (point-max))
(create-eval-motion-overlay (point-min) (point-max))))))
;; load region
((not register)
(pcase-let* ((`(,beg ,end) (outer-sexp-at-region beg end t))
(`(,_ ,ele) (assoc major-mode evil-extra-operator-eval-region-modes-alist)))
(funcall ele beg end)
(create-eval-motion-overlay beg end)))))
(defun evil-eval-buffer ()
(interactive)
(evil-eval-motion 1 (point-max)))
(defun evil-a-paren2 (count beg end type)
(cond
((member major-mode '(clojurescript-mode
clojure-mode
cider-mode
cider-repl-mode))
(pcase-let* ((`(,beg ,end) (outer-sexp-at-region (point) (+ 1 (point)) t)))
(list beg end type)))
(t
(evil-a-paren count beg end type))))
(evil-define-operator evil-cp-delete-a-paren (beg end type register yank-handler)
:move-point nil
(interactive "<x><y>")
(pcase-let ((`(,beg ,end ,type) (evil-a-paren2 1 beg end type)))
(evil-delete beg end type)))
(evil-define-operator evil-cp-change-a-paren (beg end type register yank-handler)
:move-point nil
(interactive "<x><y>")
(pcase-let ((`(,beg ,end ,type) (evil-a-paren2 1 beg end type)))
(evil-change beg end type)))
(evil-define-operator evil-cp-yank-a-paren (beg end type register yank-handler)
:move-point nil
(interactive "<x><y>")
(pcase-let ((`(,beg ,end ,type) (evil-a-paren2 1 beg end type)))
(evil-yank beg end type)))
(evil-define-operator evil-cp-eval-a-paren (beg end type register yank-handler)
:move-point nil
(interactive "<x><y>")
(pcase-let ((`(,beg ,end ,type) (evil-a-paren2 1 beg end type))
(`(,mode ,ele) (assoc major-mode evil-extra-operator-eval-region-modes-alist)))
(funcall ele beg end)))
(general-define-key :keymaps 'motion
"r" #'evil-cp-a-defun
;;"4" #'evil-end-of-line
)
(general-define-key :keymaps 'motion :prefix "g"
"o" 'evil-ace-jump-line-mode
"k" 'evil-window-top
"j" 'evil-window-bottom
"m" 'evil-window-middle
")" 'evil-a-symbol) ;; evil-a-paren
;;(general-define-key :keymaps 'normal :prefix "g"
;; "p" 'spacemacs/paste-transient-state/body)
(evil-define-key 'insert evil-cleverparens-mode-map
(kbd "E") #'evil-eval-buffer
(kbd "s-E") #'evil-eval-buffer)
(evil-define-key 'normal evil-cleverparens-mode-map
(kbd "E") #'evil-eval-buffer
(kbd "s-E") #'evil-eval-buffer
(kbd "s-D") #'evil-cp-delete-a-paren
(kbd "s-C") #'evil-cp-change-a-paren
(kbd "s-Y") #'evil-cp-yank-a-paren
(kbd "e") #'evil-eval-motion)
(evil-define-key 'visual evil-cleverparens-mode-map
(kbd "e") #'evil-eval-motion)
(add-hook 'smartparens-mode-hook
(lambda ()
(evil-cleverparens-mode +1)
(define-key sp-keymap (kbd "C-<right>") 'sp-forward-slurp-sexp)
(define-key sp-keymap (kbd "C-<left>") 'sp-forward-barf-sexp)
(define-key sp-keymap (kbd "C-M-<left>") 'sp-backward-slurp-sexp)
(define-key sp-keymap (kbd "C-M-<right>") 'sp-backward-barf-sexp)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment