Last active
March 24, 2021 09:08
-
-
Save camsaul/047f72f518218ed23acf0f2b7f4003f9 to your computer and use it in GitHub Desktop.
Emacs Lisp convert Clojure expectations form to clojure.test deftest form
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defun cam/-next-sexp-on-current-line-p () | |
"Whether the next sexp after point is one the current line." | |
(let ((next-sexp (save-excursion | |
(paredit-forward) | |
(current-line)))) | |
(= next-sexp (current-line)))) | |
(defun cam/-clojure-in-expect-form-p () | |
"Whether we are currently in a expect form." | |
(save-excursion | |
(beginning-of-defun) | |
(paredit-forward-down) | |
(eq (sexp-at-point) 'expect))) | |
(defun cam/-clojure-convert-expect-to-deftest () | |
"Convert the current expect form to a deftest form." | |
(interactive) | |
(unless (cam/-clojure-in-expect-form-p) | |
(error "Not in an expect form")) | |
;; comments below denote cursor position with _ | |
;; _(expect x y) | |
(beginning-of-defun) | |
;; (_expect x y) | |
(paredit-forward-down) | |
;; (_ x y) | |
(kill-sexp) | |
(case (paredit-count-sexps-forward) | |
(1 | |
;; (is_ assertion) | |
(insert "is") | |
;; make sure assertion is on the same line as is | |
(unless (cam/-next-sexp-on-current-line-p) | |
(join-line -1))) | |
(2 | |
;; (=_ expected actual) | |
(insert "=") | |
;; make sure expected is on the same line as = | |
(unless (cam/-next-sexp-on-current-line-p) | |
(join-line -1)) | |
;; (= expected_ actual) | |
(paredit-forward) | |
;; put actual on its own line if its not already | |
(when (cam/-next-sexp-on-current-line-p) | |
(paredit-newline)) | |
;; _(= expected actual) | |
(paredit-backward-up) | |
;; (_(= expected actual) | |
(paredit-wrap-sexp) | |
;; (is _(= expected actual) | |
(insert "is "))) | |
;; _(is ...) | |
(paredit-backward-up) | |
;; (_(is ...)) | |
(paredit-wrap-sexp) | |
;; (deftest a-test _(is ...)) | |
(insert "deftest a-test ") | |
(paredit-newline) | |
;; _(deftest ...) | |
(beginning-of-defun)) | |
(defun cam/-clojure-delete-comment-line () | |
"Delete a full-line comment line, and return the deleted text, excluding initial semicolons and whitespace." | |
(beginning-of-line) | |
(search-forward " ") | |
(prog1 (buffer-substring-no-properties (point) (point-at-eol)) | |
(delete-region (point-at-bol) (point-at-bol 2)))) | |
(defun cam/-clojure-in-long-string-p () | |
"Whether we are currently inside of a long string that goes past `fill-column'." | |
(and (paredit-in-string-p) | |
(save-excursion | |
;; "..."_ | |
(paredit-forward-up) | |
(> (current-column) fill-column)))) | |
(defun cam/clojure-split-long-string () | |
"Split a long string into multiple lines with a str form." | |
(interactive) | |
(when (cam/-clojure-in-long-string-p) | |
;; _"..." | |
(paredit-backward-up) | |
;; (_"...") | |
(paredit-wrap-sexp) | |
;; (str _"...") | |
(insert "str ") | |
;; "_..." | |
(paredit-forward-down) | |
(while (cam/-clojure-in-long-string-p) | |
;; move forward to the first word after the fill column | |
(let ((original-line (current-line))) | |
(while (and (= (current-line) original-line) | |
(< (current-column) fill-column)) | |
(paredit-forward))) | |
;; now back one word, where we'll split it. | |
(paredit-backward) | |
;; kill rest of line | |
(paredit-kill) | |
;; "..."_ | |
(paredit-forward-up) | |
;; insert new line then new string with what we just killed. | |
(paredit-newline) | |
(paredit-doublequote) | |
(yank) | |
;; _"..." | |
(paredit-backward-up) | |
;; "_word ..." | |
(paredit-forward-down)) | |
;; _"..." | |
(paredit-backward-up))) | |
(defun cam/clojure-convert-comment-to-testing () | |
"Convert the comment line into a testing form in the deftest form that follows it." | |
(interactive) | |
(when-let ((comment-string (cam/-clojure-delete-comment-line))) | |
;; _(deftest ...) | |
(paredit-forward-down) | |
(paredit-forward-down) | |
(paredit-backward-up) | |
(paredit-wrap-sexp) | |
(insert "testing ") | |
;; (testing "_" ...) | |
(paredit-doublequote) | |
(insert comment-string) | |
(cam/clojure-split-long-string) | |
(paredit-forward-up) | |
(paredit-newline))) | |
(defun cam/-lisp-line-is-comment-p () | |
"Whether the current line is a full-line comment." | |
(string-match-p | |
(rx line-start (one-or-more ";")) | |
(buffer-substring-no-properties (point-at-bol) (min (+ (point-at-bol) 4) | |
(point-at-eol))))) | |
(defun cam/-lisp-previous-line-is-comment-p () | |
"Whether the previous line is a full-line comment." | |
(save-excursion | |
(forward-line -1) | |
(beginning-of-line) | |
(cam/-lisp-line-is-comment-p))) | |
(defun cam/clojure-collapse-comments () | |
"Collapse the current comment line and all ones directly above it into a single line." | |
(interactive) | |
(beginning-of-line) | |
(when (cam/-lisp-previous-line-is-comment-p) | |
(let ((comment-string (cam/-clojure-delete-comment-line))) | |
;; move to end of previous line, insert space, and the text of the comment line we just deleted | |
(end-of-line 0) | |
(insert " ") | |
(insert comment-string)) | |
(cam/clojure-collapse-comments))) | |
(defun cam/-reindent-clojure-defun () | |
"Reinident the current form." | |
(let ((end (save-excursion | |
(end-of-defun) | |
(point)))) | |
(clojure-align (point) end))) | |
(defun cam/clojure-expect-to-deftest () | |
"Convert the expect form under `point' to a deftest form." | |
(interactive) | |
(cam/-clojure-convert-expect-to-deftest) | |
(when (cam/-lisp-previous-line-is-comment-p) | |
(forward-line -1) | |
(cam/clojure-collapse-comments) | |
(cam/clojure-convert-comment-to-testing)) | |
(cam/-reindent-clojure-defun)) | |
(defun cam/clojure-next-expect-to-deftest () | |
"Convert the next expect form to a deftest form. Throws error if no more deftest forms exist." | |
(interactive) | |
(search-forward "(expect") | |
(cam/clojure-expect-to-deftest)) | |
(defun cam/clojure-all-expect-forms-to-deftest () | |
"Convert all the expect forms in the current buffer after `point' to deftest forms." | |
(interactive) | |
(ignore-errors | |
(while (ignore-errors | |
(cam/clojure-next-expect-to-deftest) | |
t)))) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defun cam/clojure-move-is-down-one-level () | |
(interactive) | |
(beginning-of-defun) | |
(search-forward "(is") | |
(paredit-forward-down) | |
(paredit-forward) | |
(paredit-forward) | |
(paredit-backward) | |
(paredit-kill) | |
(paredit-raise-sexp) | |
(paredit-raise-sexp) | |
(paredit-forward-down) | |
(paredit-backward-up) | |
(paredit-forward) | |
(paredit-backward-down) | |
(paredit-backward) | |
(paredit-wrap-sexp) | |
(insert "= ") | |
(yank) | |
(paredit-newline) | |
(paredit-backward-up) | |
(paredit-wrap-sexp) | |
(insert "is " ) | |
(cam/-reindent-clojure-defun)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Requires
paredit
andclojure-mode