Skip to content

Commit d698390

Browse files
committed
Fix clojure-update-ns and add tests
clojure-update-ns was broken because it used replace-match with group 4 from the old clojure-namespace-name-regex, but clojure-find-ns uses clojure-namespace-regexp which has no capture groups. Replace the broken replace-match approach with direct sexp navigation to find and replace the namespace name.
1 parent 6d9d81b commit d698390

2 files changed

Lines changed: 87 additions & 1 deletion

File tree

clojure-mode.el

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2116,7 +2116,16 @@ Useful if a file has been renamed."
21162116
(save-match-data
21172117
(if (clojure-find-ns)
21182118
(progn
2119-
(replace-match nsname nil nil nil 4)
2119+
;; Move to end of the ns/in-ns keyword, then forward
2120+
;; to the namespace name sexp and replace it.
2121+
(goto-char (match-end 0))
2122+
(clojure-forward-logical-sexp)
2123+
(let ((end (point)))
2124+
(backward-sexp)
2125+
;; Skip past quote in (in-ns 'foo)
2126+
(skip-chars-forward "'")
2127+
(delete-region (point) end)
2128+
(insert nsname))
21202129
(message "ns form updated to `%s'" nsname)
21212130
(setq clojure-cached-ns nsname))
21222131
(user-error "Can't find ns form")))))))
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
;;; clojure-mode-update-ns-test.el --- Clojure Mode: update-ns tests -*- lexical-binding: t; -*-
2+
3+
;; Copyright (C) 2026 Bozhidar Batsov <bozhidar@batsov.dev>
4+
5+
;; This file is not part of GNU Emacs.
6+
7+
;; This program is free software; you can redistribute it and/or modify
8+
;; it under the terms of the GNU General Public License as published by
9+
;; the Free Software Foundation, either version 3 of the License, or
10+
;; (at your option) any later version.
11+
12+
;; This program is distributed in the hope that it will be useful,
13+
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
;; GNU General Public License for more details.
16+
17+
;; You should have received a copy of the GNU General Public License
18+
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
19+
20+
;;; Commentary:
21+
22+
;; Tests for clojure-update-ns.
23+
24+
;;; Code:
25+
26+
(require 'clojure-mode)
27+
(require 'buttercup)
28+
(require 'test-helper "test/utils/test-helper")
29+
30+
(describe "clojure-update-ns"
31+
32+
(it "should update a simple ns form"
33+
(with-clojure-buffer "(ns old.name)"
34+
(let ((clojure-expected-ns-function (lambda () "new.name")))
35+
(clojure-update-ns)
36+
(expect (buffer-string) :to-equal "(ns new.name)"))))
37+
38+
(it "should update ns with metadata"
39+
(with-clojure-buffer "(ns ^:bar old.name)"
40+
(let ((clojure-expected-ns-function (lambda () "new.name")))
41+
(clojure-update-ns)
42+
(expect (buffer-string) :to-equal "(ns ^:bar new.name)"))))
43+
44+
(it "should update ns with map metadata"
45+
(with-clojure-buffer "(ns ^{:doc \"hello\"} old.name)"
46+
(let ((clojure-expected-ns-function (lambda () "new.name")))
47+
(clojure-update-ns)
48+
(expect (buffer-string) :to-equal "(ns ^{:doc \"hello\"} new.name)"))))
49+
50+
(it "should update ns with require forms"
51+
(with-clojure-buffer "(ns old.name
52+
(:require [clojure.string :as str]))"
53+
(let ((clojure-expected-ns-function (lambda () "new.name")))
54+
(clojure-update-ns)
55+
(expect (buffer-string) :to-equal "(ns new.name
56+
(:require [clojure.string :as str]))"))))
57+
58+
(it "should update in-ns forms"
59+
(with-clojure-buffer "(in-ns 'old.name)"
60+
(let ((clojure-expected-ns-function (lambda () "new.name")))
61+
(clojure-update-ns)
62+
(expect (buffer-string) :to-equal "(in-ns 'new.name)"))))
63+
64+
(it "should update the cached namespace"
65+
(with-clojure-buffer "(ns old.name)"
66+
(let ((clojure-expected-ns-function (lambda () "new.name")))
67+
(clojure-update-ns)
68+
(expect clojure-cached-ns :to-equal "new.name"))))
69+
70+
(it "should signal an error when no ns form is found"
71+
(with-clojure-buffer "(defn foo [] 1)"
72+
(let ((clojure-expected-ns-function (lambda () "new.name")))
73+
(expect (clojure-update-ns) :to-throw 'user-error)))))
74+
75+
(provide 'clojure-mode-update-ns-test)
76+
77+
;;; clojure-mode-update-ns-test.el ends here

0 commit comments

Comments
 (0)