From 3d27c3f68ecfd7141e87ff7fc67dc19aa4f87656 Mon Sep 17 00:00:00 2001 From: yuhan0 Date: Sat, 13 Jul 2019 17:04:08 +0800 Subject: [PATCH 1/4] Refactor clojure-unwind to take prefix arguments. Numeric prefix arg unwinds N levels, and universal arg unwinds all. clojure-unwind-all command is left as an alias for calling clojure-unwind with universal argument. --- clojure-mode.el | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/clojure-mode.el b/clojure-mode.el index ca54be2f..31205ccc 100644 --- a/clojure-mode.el +++ b/clojure-mode.el @@ -2196,10 +2196,12 @@ before fixing whitespace." (delete-trailing-whitespace (car sexp) (cdr sexp))))) ;;;###autoload -(defun clojure-unwind () - "Unwind thread at point or above point by one level. -Return nil if there are no more levels to unwind." - (interactive) +(defun clojure-unwind (&optional n) + "Unwind thread at point or above point by N levels. +With universal argument \\[universal-argument], fully unwind thread." + (interactive "P") + (setq n (cond ((equal n '(4)) 999) + (n) (1))) (save-excursion (let ((limit (save-excursion (beginning-of-defun) @@ -2208,23 +2210,24 @@ Return nil if there are no more levels to unwind." (when (looking-at "(") (forward-char 1) (forward-sexp 1))) - (search-backward-regexp "([^-]*->" limit) - (if (clojure--nothing-more-to-unwind) - (progn (clojure--pop-out-of-threading) - (clojure--fix-sexp-whitespace) - nil) - (down-list) - (prog1 (cond - ((looking-at "[^-]*->\\_>") (clojure--unwind-first)) - ((looking-at "[^-]*->>\\_>") (clojure--unwind-last))) - (clojure--fix-sexp-whitespace 'move-out)) - t)))) + (while (> n 0) + (search-backward-regexp "([^-]*->" limit) + (if (clojure--nothing-more-to-unwind) + (progn (clojure--pop-out-of-threading) + (clojure--fix-sexp-whitespace) + (setq n 0)) ;; break out of loop + (down-list) + (cond + ((looking-at "[^-]*->\\_>") (clojure--unwind-first)) + ((looking-at "[^-]*->>\\_>") (clojure--unwind-last))) + (clojure--fix-sexp-whitespace 'move-out) + (setq n (1- n))))))) ;;;###autoload (defun clojure-unwind-all () "Fully unwind thread at point or above point." (interactive) - (while (clojure-unwind))) + (clojure-unwind '(4))) (defun clojure--remove-superfluous-parens () "Remove extra parens from a form." From f2cda8c69434bd6b9e954272e79d481325b0f68a Mon Sep 17 00:00:00 2001 From: yuhan0 Date: Fri, 12 Jul 2019 13:19:42 +0800 Subject: [PATCH 2/4] Add default keybindings for rename-ns-alias and add-arity refactorings Removed keybinding for clojure-unwind-all (use C-u universal arg with clojure-unwind instead) --- clojure-mode.el | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/clojure-mode.el b/clojure-mode.el index 31205ccc..334f50c5 100644 --- a/clojure-mode.el +++ b/clojure-mode.el @@ -217,8 +217,6 @@ Out-of-the box `clojure-mode' understands lein, boot, gradle, (define-key map (kbd "f") #'clojure-thread-first-all) (define-key map (kbd "C-l") #'clojure-thread-last-all) (define-key map (kbd "l") #'clojure-thread-last-all) - (define-key map (kbd "C-a") #'clojure-unwind-all) - (define-key map (kbd "a") #'clojure-unwind-all) (define-key map (kbd "C-p") #'clojure-cycle-privacy) (define-key map (kbd "p") #'clojure-cycle-privacy) (define-key map (kbd "C-(") #'clojure-convert-collection-to-list) @@ -241,10 +239,13 @@ Out-of-the box `clojure-mode' understands lein, boot, gradle, (define-key map (kbd "n h") #'clojure-insert-ns-form-at-point) (define-key map (kbd "n u") #'clojure-update-ns) (define-key map (kbd "n s") #'clojure-sort-ns) + (define-key map (kbd "n r") #'clojure-rename-ns-alias) (define-key map (kbd "s i") #'clojure-introduce-let) (define-key map (kbd "s m") #'clojure-move-to-let) (define-key map (kbd "s f") #'clojure-let-forward-slurp-sexp) (define-key map (kbd "s b") #'clojure-let-backward-slurp-sexp) + (define-key map (kbd "C-a") #'clojure-add-arity) + (define-key map (kbd "a") #'clojure-add-arity) map) "Keymap for Clojure refactoring commands.") (fset 'clojure-refactor-map clojure-refactor-map) @@ -263,11 +264,13 @@ Out-of-the box `clojure-mode' understands lein, boot, gradle, ["Cycle if, if-not" clojure-cycle-if] ["Cycle when, when-not" clojure-cycle-when] ["Cycle not" clojure-cycle-not] + ["Add function arity" clojure-add-arity] ("ns forms" ["Insert ns form at the top" clojure-insert-ns-form] ["Insert ns form here" clojure-insert-ns-form-at-point] ["Update ns form" clojure-update-ns] - ["Sort ns form" clojure-sort-ns]) + ["Sort ns form" clojure-sort-ns] + ["Rename ns alias" clojure-rename-ns-alias]) ("Convert collection" ["Convert to list" clojure-convert-collection-to-list] ["Convert to quoted list" clojure-convert-collection-to-quoted-list] From 645ab5f25f81c613bc84198ed89d43ce424859bf Mon Sep 17 00:00:00 2001 From: yuhan0 Date: Fri, 12 Jul 2019 13:58:45 +0800 Subject: [PATCH 3/4] Tweak docstrings and indentation --- clojure-mode.el | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/clojure-mode.el b/clojure-mode.el index 334f50c5..17036fb6 100644 --- a/clojure-mode.el +++ b/clojure-mode.el @@ -2682,7 +2682,7 @@ lists up." ;;;###autoload (defun clojure-let-backward-slurp-sexp (&optional n) "Slurp the s-expression before the let form into the let form. -With a numberic prefix argument slurp the previous N s-expression +With a numeric prefix argument slurp the previous N s-expressions into the let form." (interactive "p") (let ((n (or n 1))) @@ -2702,7 +2702,8 @@ into the let form." ;;;###autoload (defun clojure-let-forward-slurp-sexp (&optional n) "Slurp the next s-expression after the let form into the let form. -With a numeric prefix argument slurp the next N s-expressions into the let form." +With a numeric prefix argument slurp the next N s-expressions +into the let form." (interactive "p") (unless n (setq n 1)) (dotimes (_ n) @@ -2731,8 +2732,8 @@ With a numeric prefix argument the let is introduced N lists up." (let ((rgx (concat ":as +" current-alias)) (bound (save-excursion (forward-list 1) (point)))) (if (save-excursion (search-forward-regexp rgx bound t)) - (let ((new-alias (read-from-minibuffer "New alias: "))) - (clojure--rename-ns-alias-internal current-alias new-alias)) + (let ((new-alias (read-from-minibuffer "New alias: "))) + (clojure--rename-ns-alias-internal current-alias new-alias)) (message "Cannot find namespace alias: '%s'" current-alias)))))) ;;;###autoload @@ -2755,7 +2756,7 @@ With a numeric prefix argument the let is introduced N lists up." ((looking-back "\\[" 1) ;; single-arity defn (let* ((bol (save-excursion (beginning-of-line) (point))) (same-line (save-excursion (re-search-backward "defn" bol t))) - (new-arity-text (concat (when same-line "\n") "([])\n["))) + (new-arity-text (concat (when same-line "\n") "([])\n["))) (re-search-backward " +\\[") (replace-match new-arity-text) (save-excursion From f0252da40226793f00d7bcd53ec4e057a80cab45 Mon Sep 17 00:00:00 2001 From: yuhan0 Date: Tue, 16 Jul 2019 10:07:18 +0800 Subject: [PATCH 4/4] Update changelog and tests for clojure-unwind changes --- CHANGELOG.md | 5 +++-- test/clojure-mode-refactor-threading-test.el | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fdff004..bc1e35eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,8 @@ ### New features * [#496](https://github.com/clojure-emacs/clojure-mode/issues/496): Highlight `[[wikilinks]]` in comments. -* [#366](https://github.com/clojure-emacs/clj-refactor.el/issues/366): Add support for renaming ns aliases (`clojure-rename-ns-alias`). -* [#410](https://github.com/clojure-emacs/clojure-mode/issues/410): Add support for adding an arity to a function (`clojure-add-arity`). +* [#366](https://github.com/clojure-emacs/clj-refactor.el/issues/366): Add support for renaming ns aliases (`clojure-rename-ns-alias`, default binding `C-c C-r n r`). +* [#410](https://github.com/clojure-emacs/clojure-mode/issues/410): Add support for adding an arity to a function (`clojure-add-arity`, default binding `C-c C-r a`), . ### Bugs fixed @@ -21,6 +21,7 @@ ### Changes * [#524](https://github.com/clojure-emacs/clojure-mode/issues/524): Add proper indentation rule for `delay` (same as for `future`). +* [#538](https://github.com/clojure-emacs/clojure-mode/pull/538): Refactor `clojure-unwind` to take numeric prefix argument for unwinding N steps, and universal argument for unwinding completely. The dedicated `C-c C-r a` binding for `clojure-unwind-all`is now removed and replaced with the universal arg convention `C-u C-c C-r u`. ## 5.10.0 (2019-01-05) diff --git a/test/clojure-mode-refactor-threading-test.el b/test/clojure-mode-refactor-threading-test.el index be86eb16..b78fecb3 100644 --- a/test/clojure-mode-refactor-threading-test.el +++ b/test/clojure-mode-refactor-threading-test.el @@ -227,6 +227,26 @@ (clojure-unwind) (clojure-unwind)) + (when-refactoring-it "should unwind N steps with numeric prefix arg" + "(->> [1 2 3 4 5] + (filter even?) + (map square) + sum)" + + "(->> (sum (map square (filter even? [1 2 3 4 5]))))" + + (clojure-unwind 3)) + + (when-refactoring-it "should unwind completely with universal prefix arg" + "(->> [1 2 3 4 5] + (filter even?) + (map square) + sum)" + + "(sum (map square (filter even? [1 2 3 4 5])))" + + (clojure-unwind '(4))) + (when-refactoring-it "should unwind with function name" "(->> [1 2 3 4 5] sum