diff --git a/CHANGELOG.md b/CHANGELOG.md index bee4707b..e6870174 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### 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. ### Bugs fixed diff --git a/clojure-mode.el b/clojure-mode.el index 19bcc95b..db0420a8 100644 --- a/clojure-mode.el +++ b/clojure-mode.el @@ -2659,6 +2659,23 @@ lists up." (insert sexp) (clojure--replace-sexps-with-bindings-and-indent))) +(defun clojure--rename-ns-alias-internal (current-alias new-alias) + "Rename a namespace alias CURRENT-ALIAS to NEW-ALIAS." + (clojure--find-ns-in-direction 'backward) + (let ((rgx (concat ":as +" current-alias)) + (bound (save-excursion (forward-list 1) (point)))) + (when (save-excursion (search-forward-regexp rgx bound t)) + (save-excursion + (while (re-search-forward rgx bound t) + (replace-match (concat ":as " new-alias)))) + (save-excursion + (while (re-search-forward (concat current-alias "/") nil t) + (replace-match (concat new-alias "/")))) + (save-excursion + (while (re-search-forward (concat "#::" current-alias "{") nil t) + (replace-match (concat "#::" new-alias "{")))) + (message "Successfully renamed alias '%s' to '%s'" current-alias new-alias)))) + ;;;###autoload (defun clojure-let-backward-slurp-sexp (&optional n) "Slurp the s-expression before the let form into the let form. @@ -2701,6 +2718,20 @@ With a numeric prefix argument the let is introduced N lists up." (interactive) (clojure--move-to-let-internal (read-from-minibuffer "Name of bound symbol: "))) +;;;###autoload +(defun clojure-rename-ns-alias () + "Rename a namespace alias." + (interactive) + (let ((current-alias (read-from-minibuffer "Current alias: "))) + (save-excursion + (clojure--find-ns-in-direction 'backward) + (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)) + (message "Cannot find namespace alias: '%s'" current-alias)))))) + ;;; ClojureScript (defconst clojurescript-font-lock-keywords diff --git a/test/clojure-mode-refactor-rename-ns-alias-test.el b/test/clojure-mode-refactor-rename-ns-alias-test.el new file mode 100644 index 00000000..8e7f8d82 --- /dev/null +++ b/test/clojure-mode-refactor-rename-ns-alias-test.el @@ -0,0 +1,55 @@ +;;; clojure-mode-refactor-rename-ns-alias-test.el --- Clojure Mode: refactor rename ns alias -*- lexical-binding: t; -*- + +;; This file is not part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Code: + +(require 'clojure-mode) +(require 'ert) + +(def-refactor-test test-rename-ns-alias + "(ns cljr.core + (:require [my.lib :as lib])) + + (def m #::lib{:kw 1, :n/kw 2, :_/bare 3, 0 4}) + + (+ (lib/a 1) (b 2))" + "(ns cljr.core + (:require [my.lib :as foo])) + + (def m #::foo{:kw 1, :n/kw 2, :_/bare 3, 0 4}) + + (+ (foo/a 1) (b 2))" + (clojure--rename-ns-alias-internal "lib" "foo")) + +(def-refactor-test test-rename-ns-alias-with-missing-as + "(ns cljr.core + (:require [my.lib :as lib])) + + (def m #::lib{:kw 1, :n/kw 2, :_/bare 3, 0 4}) + + (+ (lib/a 1) (b 2))" + "(ns cljr.core + (:require [my.lib :as lib])) + + (def m #::lib{:kw 1, :n/kw 2, :_/bare 3, 0 4}) + + (+ (lib/a 1) (b 2))" + (clojure--rename-ns-alias-internal "foo" "bar")) + +(provide 'clojure-mode-refactor-rename-ns-alias-test) + +;;; clojure-mode-refactor-rename-ns-alias-test.el ends here