Skip to content

Commit 0f73808

Browse files
authored
fix(clojure) Several issues with Clojure highlighting (#3397)
- fix(clojure) `$` in symbol breaks highlighting - fix(clojure) Add complete regex for number detection - enh(clojure) Add character mode for character literals - fix(clojure) Inconsistent namespaced map highlighting - enh(clojure) Add `regex` mode to regex literal - fix(clojure) Remove inconsistent/broken highlighting for metadata - enh(clojure) Add `punctuation` mode for commas.
1 parent 1d8031b commit 0f73808

13 files changed

+225
-101
lines changed

CHANGES.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,15 @@ Grammars:
55
- fix(python) Fix recognition of numeric literals followed by keywords without whitespace (#2985) [Richard Gibson][]
66
- enh(swift) add SE-0290 unavailability condition (#3382) [Bradley Mackey][]
77
- enh(java) add `sealed` and `non-sealed` keywords (#3386) [Bradley Mackey][]
8-
- fix(clojure) `comment` macro catches more than it should [Björn Ebbinghaus][]
8+
- fix(clojure) Several issues with Clojure highlighting (#3397) [Björn Ebbinghaus][]
9+
- fix(clojure) `comment` macro catches more than it should (#3395)
10+
- fix(clojure) `$` in symbol breaks highlighting
11+
- fix(clojure) Add complete regex for number detection
12+
- enh(clojure) Add character mode for character literals
13+
- fix(clojure) Inconsistent namespaced map highlighting
14+
- enh(clojure) Add `regex` mode to regex literal
15+
- fix(clojure) Remove inconsistent/broken highlighting for metadata
16+
- enh(clojure) Add `punctuation` mode for commas.
917

1018
[Richard Gibson]: https://github.com/gibson042
1119
[Bradley Mackey]: https://github.com/bradleymackey

src/languages/clojure.js

+38-18
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ Category: lisp
88

99
/** @type LanguageFn */
1010
export default function(hljs) {
11-
const SYMBOLSTART = 'a-zA-Z_\\-!.?+*=<>&#\'';
12-
const SYMBOL_RE = '[' + SYMBOLSTART + '][' + SYMBOLSTART + '0-9/;:]*';
11+
const SYMBOLSTART = 'a-zA-Z_\\-!.?+*=<>&\'';
12+
const SYMBOL_RE = '[#]?[' + SYMBOLSTART + '][' + SYMBOLSTART + '0-9/;:$#]*';
1313
const globals = 'def defonce defprotocol defstruct defmulti defmethod defn- defn defmacro deftype defrecord';
1414
const keywords = {
1515
$pattern: SYMBOL_RE,
@@ -45,20 +45,44 @@ export default function(hljs) {
4545
'lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize'
4646
};
4747

48-
const SIMPLE_NUMBER_RE = '[-+]?\\d+(\\.\\d+)?';
49-
5048
const SYMBOL = {
5149
begin: SYMBOL_RE,
5250
relevance: 0
5351
};
5452
const NUMBER = {
55-
className: 'number',
56-
begin: SIMPLE_NUMBER_RE,
57-
relevance: 0
53+
scope: 'number',
54+
relevance: 0,
55+
variants: [
56+
{match: /[-+]?0[xX][0-9a-fA-F]+N?/}, // hexadecimal // 0x2a
57+
{match: /[-+]?0[0-7]+N?/}, // octal // 052
58+
{match: /[-+]?[1-9][0-9]?[rR][0-9a-zA-Z]+N?/}, // variable radix from 2 to 36 // 2r101010, 8r52, 36r16
59+
{match: /[-+]?[0-9]+\/[0-9]+N?/}, // ratio // 1/2
60+
{match: /[-+]?[0-9]+((\.[0-9]*([eE][+-]?[0-9]+)?M?)|([eE][+-]?[0-9]+M?|M))/}, // float // 0.42 4.2E-1M 42E1 42M
61+
{match: /[-+]?([1-9][0-9]*|0)N?/}, // int (don't match leading 0) // 42 42N
62+
]
5863
};
64+
const CHARACTER = {
65+
scope: 'character',
66+
variants: [
67+
{match: /\\o[0-3]?[0-7]{1,2}/}, // Unicode Octal 0 - 377
68+
{match: /\\u[0-9a-fA-F]{4}/}, // Unicode Hex 0000 - FFFF
69+
{match: /\\(newline|space|tab|formfeed|backspace|return)/}, // special characters
70+
{match: /\\\S/, relevance: 0} // any non-whitespace char
71+
]
72+
}
73+
const REGEX = {
74+
scope: 'regex',
75+
begin: /#"/,
76+
end: /"/
77+
}
5978
const STRING = hljs.inherit(hljs.QUOTE_STRING_MODE, {
6079
illegal: null
6180
});
81+
const COMMA = {
82+
scope: 'punctuation',
83+
match: /,/,
84+
relevance: 0
85+
}
6286
const COMMENT = hljs.COMMENT(
6387
';',
6488
'$',
@@ -71,15 +95,10 @@ export default function(hljs) {
7195
begin: /\b(true|false|nil)\b/
7296
};
7397
const COLLECTION = {
74-
begin: '[\\[\\{]',
98+
begin: "\\[|(#::?" + SYMBOL_RE + ")?\\{",
7599
end: '[\\]\\}]',
76100
relevance: 0
77101
};
78-
const HINT = {
79-
className: 'comment',
80-
begin: '\\^' + SYMBOL_RE
81-
};
82-
const HINT_COL = hljs.COMMENT('\\^\\{', '\\}');
83102
const KEY = {
84103
className: 'symbol',
85104
begin: '[:]{1,2}' + SYMBOL_RE
@@ -100,10 +119,11 @@ export default function(hljs) {
100119
starts: BODY
101120
};
102121
const DEFAULT_CONTAINS = [
122+
COMMA,
103123
LIST,
124+
CHARACTER,
125+
REGEX,
104126
STRING,
105-
HINT,
106-
HINT_COL,
107127
COMMENT,
108128
KEY,
109129
COLLECTION,
@@ -138,17 +158,17 @@ export default function(hljs) {
138158
];
139159
BODY.contains = DEFAULT_CONTAINS;
140160
COLLECTION.contains = DEFAULT_CONTAINS;
141-
HINT_COL.contains = [ COLLECTION ];
142161

143162
return {
144163
name: 'Clojure',
145164
aliases: [ 'clj', 'edn' ],
146165
illegal: /\S/,
147166
contains: [
167+
COMMA,
148168
LIST,
169+
CHARACTER,
170+
REGEX,
149171
STRING,
150-
HINT,
151-
HINT_COL,
152172
COMMENT,
153173
KEY,
154174
COLLECTION,
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<span class="hljs-character">\A</span>
2+
<span class="hljs-character">\a</span>
3+
<span class="hljs-character">\formfeed</span>
4+
<span class="hljs-character">\u00DF</span>
5+
<span class="hljs-character">\o303</span>

test/markup/clojure/character.txt

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
\A
2+
\a
3+
\formfeed
4+
\u00DF
5+
\o303
+9-9
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
{<span class="hljs-symbol">:aliases</span> {<span class="hljs-symbol">:export</span> {<span class="hljs-symbol">:exec-fn</span> stelcodes.dev-blog.generator/export},
2-
<span class="hljs-symbol">:repl</span> {<span class="hljs-symbol">:extra-deps</span> {cider/cider-nrepl {<span class="hljs-symbol">:mvn/version</span> <span class="hljs-string">&quot;0.25.2&quot;</span>},
3-
nrepl/nrepl {<span class="hljs-symbol">:mvn/version</span> <span class="hljs-string">&quot;0.8.3&quot;</span>}},
4-
<span class="hljs-symbol">:extra-paths</span> [<span class="hljs-string">&quot;dev&quot;</span>],
1+
{<span class="hljs-symbol">:aliases</span> {<span class="hljs-symbol">:export</span> {<span class="hljs-symbol">:exec-fn</span> stelcodes.dev-blog.generator/export}<span class="hljs-punctuation">,</span>
2+
<span class="hljs-symbol">:repl</span> {<span class="hljs-symbol">:extra-deps</span> {cider/cider-nrepl {<span class="hljs-symbol">:mvn/version</span> <span class="hljs-string">&quot;0.25.2&quot;</span>}<span class="hljs-punctuation">,</span>
3+
nrepl/nrepl {<span class="hljs-symbol">:mvn/version</span> <span class="hljs-string">&quot;0.8.3&quot;</span>}}<span class="hljs-punctuation">,</span>
4+
<span class="hljs-symbol">:extra-paths</span> [<span class="hljs-string">&quot;dev&quot;</span>]<span class="hljs-punctuation">,</span>
55
<span class="hljs-symbol">:main-opts</span> [<span class="hljs-string">&quot;-m&quot;</span>
66
<span class="hljs-string">&quot;nrepl.cmdline&quot;</span>
77
<span class="hljs-string">&quot;--middleware&quot;</span>
88
<span class="hljs-string">&quot;[cider.nrepl/cider-middleware]&quot;</span>
9-
<span class="hljs-string">&quot;--interactive&quot;</span>]},
10-
<span class="hljs-symbol">:webhook</span> {<span class="hljs-symbol">:exec-fn</span> stelcodes.dev-blog.webhook/listen}},
11-
<span class="hljs-symbol">:deps</span> {http-kit/http-kit {<span class="hljs-symbol">:mvn/version</span> <span class="hljs-string">&quot;2.5.3&quot;</span>},
12-
org.clojure/clojure {<span class="hljs-symbol">:mvn/version</span> <span class="hljs-string">&quot;1.10.1&quot;</span>},
13-
stasis/stasis {<span class="hljs-symbol">:mvn/version</span> <span class="hljs-string">&quot;2.5.1&quot;</span>}},
9+
<span class="hljs-string">&quot;--interactive&quot;</span>]}<span class="hljs-punctuation">,</span>
10+
<span class="hljs-symbol">:webhook</span> {<span class="hljs-symbol">:exec-fn</span> stelcodes.dev-blog.webhook/listen}}<span class="hljs-punctuation">,</span>
11+
<span class="hljs-symbol">:deps</span> {http-kit/http-kit {<span class="hljs-symbol">:mvn/version</span> <span class="hljs-string">&quot;2.5.3&quot;</span>}<span class="hljs-punctuation">,</span>
12+
org.clojure/clojure {<span class="hljs-symbol">:mvn/version</span> <span class="hljs-string">&quot;1.10.1&quot;</span>}<span class="hljs-punctuation">,</span>
13+
stasis/stasis {<span class="hljs-symbol">:mvn/version</span> <span class="hljs-string">&quot;2.5.1&quot;</span>}}<span class="hljs-punctuation">,</span>
1414
<span class="hljs-symbol">:paths</span> [<span class="hljs-string">&quot;src&quot;</span> <span class="hljs-string">&quot;resources&quot;</span>]}

test/markup/clojure/globals_definition.expect.txt

+9-4
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,26 @@
55
<span class="hljs-comment">; function</span>
66
(<span class="hljs-keyword">defn</span> <span class="hljs-title">clojure-function</span> [args]
77
(<span class="hljs-name"><span class="hljs-built_in">let</span></span> [string <span class="hljs-string">&quot;multiline\nstring&quot;</span>
8-
regexp #<span class="hljs-string">&quot;regexp&quot;</span>
9-
number <span class="hljs-number">100</span>,<span class="hljs-number">000</span>
8+
regexp <span class="hljs-regex">#&quot;regexp&quot;</span>
9+
number <span class="hljs-number">100000</span>
1010
booleans [<span class="hljs-literal">false</span> <span class="hljs-literal">true</span>]
1111
keyword <span class="hljs-symbol">::the-keyword</span>]
1212
<span class="hljs-comment">;; this is comment</span>
1313
(<span class="hljs-name"><span class="hljs-built_in">if</span></span> <span class="hljs-literal">true</span>
1414
(<span class="hljs-name"><span class="hljs-built_in">-&gt;&gt;</span></span>
1515
(<span class="hljs-name"><span class="hljs-built_in">list</span></span> [vector] {<span class="hljs-symbol">:map</span> map} #{&#x27;set})))))
1616

17+
#:person{<span class="hljs-symbol">:first</span> <span class="hljs-string">&quot;Han&quot;</span>
18+
<span class="hljs-symbol">:last</span> <span class="hljs-string">&quot;Solo&quot;</span>
19+
<span class="hljs-symbol">:ship</span> #:ship{<span class="hljs-symbol">:name</span> <span class="hljs-string">&quot;Millenium Falcon&quot;</span>}}
20+
#::{<span class="hljs-symbol">:a</span> <span class="hljs-number">1</span><span class="hljs-punctuation">,</span> <span class="hljs-symbol">:b</span> <span class="hljs-number">2</span>}
21+
1722
<span class="hljs-comment">; global</span>
1823
(<span class="hljs-keyword">def</span> <span class="hljs-title">some-var</span>)
1924
<span class="hljs-comment">; another one</span>
2025
(<span class="hljs-keyword">def</span> <span class="hljs-title">alternative-var</span> <span class="hljs-string">&quot;132&quot;</span>)
2126
<span class="hljs-comment">; defonce</span>
22-
(<span class="hljs-keyword">defonce</span> ^<span class="hljs-symbol">:private</span> <span class="hljs-title">another-var</span> #<span class="hljs-string">&quot;foo&quot;</span>)
27+
(<span class="hljs-keyword">defonce</span> ^<span class="hljs-symbol">:private</span> <span class="hljs-title">another-var</span> <span class="hljs-regex">#&quot;foo&quot;</span>)
2328

2429
<span class="hljs-comment">; private function</span>
2530
(<span class="hljs-keyword">defn-</span> <span class="hljs-title">add</span> [x y] (<span class="hljs-name"><span class="hljs-built_in">+</span></span> x y))
@@ -58,4 +63,4 @@
5863

5964
<span class="hljs-comment">;; create a couple shapes and get their area</span>
6065
(<span class="hljs-keyword">def</span> <span class="hljs-title">myCircle</span> (<span class="hljs-name">Circle.</span> <span class="hljs-number">10</span>))
61-
(<span class="hljs-keyword">def</span> <span class="hljs-title">mySquare</span> (<span class="hljs-name">Square.</span> <span class="hljs-number">5</span> <span class="hljs-number">11</span>))
66+
(<span class="hljs-keyword">def</span> <span class="hljs-title">mySquare</span> (<span class="hljs-name">Square.</span> <span class="hljs-number">5</span> <span class="hljs-number">11</span>))

test/markup/clojure/globals_definition.txt

+6-1
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,19 @@
66
(defn clojure-function [args]
77
(let [string "multiline\nstring"
88
regexp #"regexp"
9-
number 100,000
9+
number 100000
1010
booleans [false true]
1111
keyword ::the-keyword]
1212
;; this is comment
1313
(if true
1414
(->>
1515
(list [vector] {:map map} #{'set})))))
1616

17+
#:person{:first "Han"
18+
:last "Solo"
19+
:ship #:ship{:name "Millenium Falcon"}}
20+
#::{:a 1, :b 2}
21+
1722
; global
1823
(def some-var)
1924
; another one

test/markup/clojure/hint_col.expect.txt

-34
This file was deleted.

test/markup/clojure/hint_col.txt

-34
This file was deleted.

test/markup/clojure/number.expect.txt

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<span class="hljs-comment">; integer</span>
2+
<span class="hljs-number">00</span>
3+
<span class="hljs-number">42</span>
4+
<span class="hljs-number">+42</span>
5+
<span class="hljs-number">-42</span>
6+
7+
<span class="hljs-comment">; BigInt</span>
8+
<span class="hljs-number">42N</span>
9+
<span class="hljs-number">0N</span>
10+
<span class="hljs-number">+42N</span>
11+
<span class="hljs-number">-42N</span>
12+
13+
<span class="hljs-comment">; octal</span>
14+
<span class="hljs-number">052</span>
15+
<span class="hljs-number">00N</span>
16+
<span class="hljs-number">+052</span>
17+
<span class="hljs-number">-00N</span>
18+
19+
<span class="hljs-comment">; hex</span>
20+
<span class="hljs-number">0x2a</span>
21+
<span class="hljs-number">0x0N</span>
22+
<span class="hljs-number">+0x2a</span>
23+
<span class="hljs-number">-0x0N</span>
24+
25+
<span class="hljs-comment">; radix</span>
26+
<span class="hljs-number">2r101010</span>
27+
<span class="hljs-number">8r52</span>
28+
<span class="hljs-number">16r2a</span>
29+
<span class="hljs-number">36r16</span>
30+
<span class="hljs-number">-2r101010</span>
31+
<span class="hljs-number">+36r16</span>
32+
33+
<span class="hljs-comment">; radix BigInt</span>
34+
<span class="hljs-number">2r101010N</span>
35+
<span class="hljs-number">8r52N</span>
36+
<span class="hljs-number">16r2aN</span>
37+
<span class="hljs-number">36r16N</span>
38+
<span class="hljs-number">+8r52N</span>
39+
<span class="hljs-number">-16r2aN</span>
40+
41+
<span class="hljs-comment">;; ratios</span>
42+
<span class="hljs-number">1/2</span>
43+
<span class="hljs-number">-1/2</span>
44+
<span class="hljs-number">+123/224</span>
45+
46+
<span class="hljs-comment">;; floats</span>
47+
<span class="hljs-number">42.0</span>
48+
<span class="hljs-number">-42.0</span>
49+
<span class="hljs-number">+42.0</span>
50+
<span class="hljs-number">42.</span>
51+
<span class="hljs-number">+42.</span>
52+
<span class="hljs-number">-42.</span>
53+
54+
<span class="hljs-comment">; BigDecimal</span>
55+
<span class="hljs-number">42.0M</span>
56+
<span class="hljs-number">-42M</span>
57+
<span class="hljs-number">42.M</span>
58+
<span class="hljs-number">42M</span>
59+
60+
<span class="hljs-comment">; with Exponent</span>
61+
<span class="hljs-number">42.0E2</span>
62+
<span class="hljs-number">-42.0E+9</span>
63+
<span class="hljs-number">42E-0</span>
64+
<span class="hljs-number">+42E-0</span>
65+
66+
<span class="hljs-number">42.0E2M</span>
67+
<span class="hljs-number">42E+9M</span>
68+
<span class="hljs-number">-42E+9M</span>
69+
<span class="hljs-number">+42.0E2M</span>

0 commit comments

Comments
 (0)