Skip to content

Commit d1e0a6e

Browse files
Bostbbatsov
authored andcommitted
Numerous font-locking fixes and improvements
* s/clojure-interop-method-face/font-lock-type-face * keyword font-locking * visual examples w/ ert tests * fix failing ert tests
1 parent acb0174 commit d1e0a6e

File tree

4 files changed

+771
-161
lines changed

4 files changed

+771
-161
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
* [#429](https://github.com/clojure-emacs/clojure-mode/issues/429): Fix a bug causing last occurrence of expression sometimes is not replaced when using `move-to-let`.
2828
* [#423](https://github.com/clojure-emacs/clojure-mode/issues/423): Make `clojure-match-next-def` more robust against zero-arity def-like forms.
2929
* [#451](https://github.com/clojure-emacs/clojure-mode/issues/451): Make project root directory calculation customized by `clojure-project-root-function`.
30+
* Stop distinctive font-locking of java interop methods & constants: There is no semantic distinction between interop methods, constants and global vars in clojure.
31+
* Fix namespace font-locking: namespaces may also contain non alphanumeric chars.
32+
3033

3134
## 5.6.1 (2016-12-21)
3235

clojure-mode.el

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,6 @@
9292
"Face used to font-lock Clojure character literals."
9393
:package-version '(clojure-mode . "3.0.0"))
9494

95-
(defface clojure-interop-method-face
96-
'((t (:inherit font-lock-preprocessor-face)))
97-
"Face used to font-lock interop method names (camelCase)."
98-
:package-version '(clojure-mode . "3.0.0"))
99-
10095
(defcustom clojure-indent-style :always-align
10196
"Indentation style to use for function forms and macro forms.
10297
There are two cases of interest configured by this variable.
@@ -848,29 +843,45 @@ any number of matches of `clojure--sym-forbidden-rest-chars'."))
848843
0 font-lock-constant-face)
849844
;; Character literals - \1, \a, \newline, \u0000
850845
("\\\\\\([[:punct:]]\\|[a-z0-9]+\\>\\)" 0 'clojure-character-face)
851-
;; foo/ Foo/ @Foo/ /FooBar
852-
(,(concat "\\(?:\\<:?\\|\\.\\)@?\\(" clojure--sym-regexp "\\)\\(/\\)")
853-
(1 font-lock-type-face) (2 'default))
854-
;; Constant values (keywords), including as metadata e.g. ^:static
855-
("\\<^?\\(:\\(\\sw\\|\\s_\\)+\\(\\>\\|\\_>\\)\\)" 1 'clojure-keyword-face append)
856-
;; Java interop highlighting
857-
;; CONST SOME_CONST (optionally prefixed by /)
858-
("\\(?:\\<\\|/\\)\\([A-Z]+\\|\\([A-Z]+_[A-Z1-9_]+\\)\\)\\>" 1 font-lock-constant-face)
859-
;; .foo .barBaz .qux01 .-flibble .-flibbleWobble
860-
("\\<\\.-?[a-z][a-zA-Z0-9]*\\>" 0 'clojure-interop-method-face)
861-
;; Foo Bar$Baz Qux_ World_OpenUDP Foo. Babylon15.
862-
("\\(?:\\<\\|\\.\\|/\\|#?^\\)\\([A-Z][a-zA-Z0-9_]*[a-zA-Z0-9$_]+\\.?\\>\\)" 1 font-lock-type-face)
863-
;; foo.bar.baz
864-
("\\<^?\\([a-z][a-z0-9_-]+\\.\\([a-z][a-z0-9_-]*\\.?\\)+\\)" 1 font-lock-type-face)
865-
;; (ns namespace) - special handling for single segment namespaces
846+
847+
;; namespace definitions: (ns foo.bar)
866848
(,(concat "(\\<ns\\>[ \r\n\t]*"
867849
;; Possibly metadata
868850
"\\(?:\\^?{[^}]+}[ \r\n\t]*\\)*"
869851
;; namespace
870-
"\\([a-z0-9-]+\\)")
871-
(1 font-lock-type-face nil t))
872-
;; fooBar
873-
("\\(?:\\<\\|/\\)\\([a-z]+[A-Z]+[a-zA-Z0-9$]*\\>\\)" 1 'clojure-interop-method-face)
852+
"\\(" clojure--sym-regexp "\\)")
853+
(1 font-lock-type-face))
854+
855+
;; TODO dedupe the code for matching of keywords, type-hints and unmatched symbols
856+
857+
;; keywords: {:oneword/veryCom|pLex.stu-ff 0}
858+
(,(concat "\\(:\\)\\(" clojure--sym-regexp "\\)\\(/\\)\\(" clojure--sym-regexp "\\)")
859+
(1 'clojure-keyword-face)
860+
(2 font-lock-type-face)
861+
(3 'default)
862+
(4 'clojure-keyword-face))
863+
(,(concat "\\(:\\)\\(" clojure--sym-regexp "\\)")
864+
(1 'clojure-keyword-face)
865+
(2 'clojure-keyword-face))
866+
867+
;; type-hints: #^oneword
868+
(,(concat "\\(#^\\)\\(" clojure--sym-regexp "\\)\\(/\\)\\(" clojure--sym-regexp "\\)")
869+
(1 'default)
870+
(2 font-lock-type-face)
871+
(3 'default)
872+
(4 'default))
873+
(,(concat "\\(#^\\)\\(" clojure--sym-regexp "\\)")
874+
(1 'default)
875+
(2 font-lock-type-face))
876+
877+
;; clojure symbols not matched by the previous regexps
878+
(,(concat "\\(" clojure--sym-regexp "\\)\\(/\\)\\(" clojure--sym-regexp "\\)")
879+
(1 font-lock-type-face)
880+
(2 'default)
881+
(3 'default))
882+
(,(concat "\\(" clojure--sym-regexp "\\)")
883+
(1 'default))
884+
874885
;; #_ and (comment ...) macros.
875886
(clojure--search-comment-macro 1 font-lock-comment-face t)
876887
;; Highlight `code` marks, just like `elisp'.

test.clj

Lines changed: 167 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,43 @@
11
;;; font locking
22
(ns clojure-mode.demo
3-
(:require [clojure.something]
4-
[something.s]))
3+
(:require
4+
[oneword]
5+
[seg.mnt]
6+
[mxdCase]
7+
[CmlCase]
8+
[veryCom|pLex.stu-ff]))
9+
10+
(defn foo [x] x)
11+
;; try to byte-recompile the clojure-mode.el when the face of 'fn' is 't'
12+
(fn foo [x] x)
13+
14+
#_
15+
;; the myfn sexp should have a comment face
16+
(mysfn 101
17+
foo
18+
19+
0 0i)
20+
21+
;; examples of valid namespace definitions
22+
(comment
23+
(ns .validns)
24+
(ns =validns)
25+
(ns .ValidNs=<>?+|?*.)
26+
(ns ValidNs<>?+|?*.b*ar.ba*z)
27+
(ns other.valid.ns)
28+
(ns oneword)
29+
(ns one.X)
30+
(ns foo.bar)
31+
(ns Foo.bar)
32+
(ns Foo.Bar)
33+
(ns foo.Bar)
34+
(ns Foo-bar)
35+
(ns Foo-Bar)
36+
(ns foo-Bar))
537

638
(comment ;; for indentation
39+
'some/symbol
40+
741
(with-hi heya
842
somebuddy)
943

@@ -19,11 +53,137 @@
1953
;; character literals
2054
[\a \newline \u0032 \/ \+ \,, \;]
2155

22-
;; namespaced/static calls/references
23-
(core.foo-baz/bar)
24-
@foo-bar/bar
25-
(FooBar/bar)
26-
(some.package.FooBar/baz)
56+
;; TODO change font-face for sexps starting with @,#
57+
(comment ;; examples
58+
59+
SCREAMING_UPPER_CASE
60+
veryCom|pLex.stu-ff/.SCREAMING_UPPER_CASE
61+
62+
oneword
63+
@oneword
64+
#oneword
65+
#^oneword ;; type-hint
66+
.oneword
67+
(oneword)
68+
(oneword/oneword)
69+
(oneword/seg.mnt)
70+
(oneword/CmlCase)
71+
(oneword/mxdCase)
72+
(oneword/veryCom|pLex.stu-ff)
73+
(oneword/.veryCom|pLex.stu-ff)
74+
75+
seg.mnt
76+
@seg.mnt
77+
#seg.mnt
78+
#^seg.mnt ;; type-hint
79+
.seg.mnt
80+
(seg.mnt)
81+
(seg.mnt/oneword)
82+
(seg.mnt/seg.mnt)
83+
(seg.mnt/CmlCase)
84+
(seg.mnt/mxdCase)
85+
(seg.mnt/veryCom|pLex.stu-ff)
86+
(seg.mnt/.veryCom|pLex.stu-ff)
87+
88+
CmlCase
89+
@CmlCase
90+
#CmlCase
91+
#^CmlCase ;; type-hint
92+
.CmlCase
93+
(CmlCase)
94+
(CmlCase/oneword)
95+
(CmlCase/seg.mnt)
96+
(CmlCase/CmlCase)
97+
(CmlCase/mxdCase)
98+
(CmlCase/veryCom|pLex.stu-ff)
99+
(CmlCase/.veryCom|pLex.stu-ff)
100+
101+
mxdCase
102+
@mxdCase
103+
#mxdCase
104+
#^mxdCase ;; type-hint
105+
.mxdCase
106+
(mxdCase)
107+
(mxdCase/oneword)
108+
(mxdCase/seg.mnt)
109+
(mxdCase/CmlCase)
110+
(mxdCase/mxdCase)
111+
(mxdCase/veryCom|pLex.stu-ff)
112+
(mxdCase/.veryCom|pLex.stu-ff)
113+
114+
veryCom|pLex.stu-ff
115+
@veryCom|pLex.stu-ff
116+
#veryCom|pLex.stu-ff
117+
#^veryCom|pLex.stu-ff ;; type-hint
118+
.veryCom|pLex.stu-ff
119+
(veryCom|pLex.stu-ff)
120+
(veryCom|pLex.stu-ff/oneword)
121+
(veryCom|pLex.stu-ff/seg.mnt)
122+
(veryCom|pLex.stu-ff/CmlCase)
123+
(veryCom|pLex.stu-ff/mxdCase)
124+
(veryCom|pLex.stu-ff/veryCom|pLex.stu-ff)
125+
(veryCom|pLex.stu-ff/.veryCom|pLex.stu-ff)
126+
127+
:oneword
128+
{:oneword 0}
129+
;; {:@oneword 0} ; not allowed
130+
{:#oneword 0}
131+
{:.oneword 0}
132+
{:oneword/oneword 0}
133+
{:oneword/seg.mnt 0}
134+
{:oneword/CmlCase 0}
135+
{:oneword/mxdCase 0}
136+
{:oneword/veryCom|pLex.stu-ff 0}
137+
{:oneword/.veryCom|pLex.stu-ff 0}
138+
139+
{:seg.mnt 0}
140+
;; {:@seg.mnt 0} ; not allowed
141+
{:#seg.mnt 0}
142+
{:.seg.mnt 0}
143+
{:seg.mnt/oneword 0}
144+
{:seg.mnt/seg.mnt 0}
145+
{:seg.mnt/CmlCase 0}
146+
{:seg.mnt/mxdCase 0}
147+
{:seg.mnt/veryCom|pLex.stu-ff 0}
148+
{:seg.mnt/.veryCom|pLex.stu-ff 0}
149+
150+
:CmlCase
151+
{:CmlCase 0}
152+
;; {:@CmlCase 0} ; not allowed
153+
{:#CmlCase 0}
154+
{:.CmlCase 0}
155+
{:CmlCase/oneword 0}
156+
{:CmlCase/seg.mnt 0}
157+
{:CmlCase/CmlCase 0}
158+
{:CmlCase/mxdCase 0}
159+
{:CmlCase/veryCom|pLex.stu-ff 0}
160+
{:CmlCase/.veryCom|pLex.stu-ff 0}
161+
162+
:mxdCase
163+
{:mxdCase 0}
164+
;; {:@mxdCase 0} ; not allowed
165+
{:#mxdCase 0}
166+
{:.mxdCase 0}
167+
{:mxdCase/oneword 0}
168+
{:mxdCase/seg.mnt 0}
169+
{:mxdCase/CmlCase 0}
170+
{:mxdCase/mxdCase 0}
171+
{:mxdCase/veryCom|pLex.stu-ff 0}
172+
{:mxdCase/.veryCom|pLex.stu-ff 0}
173+
174+
:veryCom|pLex.stu-ff
175+
{:veryCom|pLex.stu-ff 0}
176+
;; {:@veryCom|pLex.stu-ff 0} ; not allowed
177+
{:#veryCom|pLex.stu-ff 0}
178+
{:.veryCom|pLex.stu-ff 0}
179+
{:veryCom|pLex.stu-ff 0}
180+
{:veryCom|pLex.stu-ff/oneword 0}
181+
{:veryCom|pLex.stu-ff/seg.mnt 0}
182+
{:veryCom|pLex.stu-ff/CmlCase 0}
183+
{:veryCom|pLex.stu-ff/mxdCase 0}
184+
{:veryCom|pLex.stu-ff/veryCom|pLex.stu-ff 0}
185+
{:veryCom|pLex.stu-ff/.veryCom|pLex.stu-ff 0}
186+
)
27187

28188
;; metadata doesn't break docstrings
29189
(defn max

0 commit comments

Comments
 (0)