fix(clj) Fix broken/inconsistent highlighting for $, Numbers, namespaced maps, HINT mode. Add charachter, regex and punctuation modes.#3397
Conversation
$ is the seperator for class names
It is inconsistent with itself and other highlighters. Also applies the wrong semantic mode
What is the purpose of metadata hints in Clojure? |
Please, the more detail the better though if you did a "lots of fixes" with a second level bullet list under that that would be even better. |
General meta information. Anything really. The (defn my-function
"this function adds two numbers"
{:test #(do
(assert (= (my-function 2 3) 5))
(assert (= (my-function 4 4) 8)))}
([x y] (+ x y)))
(meta #'my-function)
; => {:arglists ([x y]),
; :doc "this function adds two numbers",
; :test #object[user$fn__143 0x4482469c "user$fn__143@4482469c"],
; :line 1, :column 1, :file "NO_SOURCE_PATH",
; :name my-function,
; :ns #object[clojure.lang.Namespace 0x3703bf3c "user"]}
(test #'my-function)
; => :okclojure.core uses it for documentation and compiler hints. CIDER the Clojure Emacs IDE uses it for breakpoints. (dotimes [i 10]
#dbg ^{:break/when (= i 7)}
(prn i))koacha, a test runner, uses them to focus on specific sets of tests (deftest ^:yyy other-test
(is (= 3 3)))meta-merge uses keys in metadata to specify per-key merge behaviour. (meta-merge {:a [:b :c]} {:a ^:prepend [:d]})
; => {:a [:d :b :c]}
(meta-merge {:a [:b :c]} {:a ^:replace [:d]})
; => {:a [:d]}
(meta-merge {:a [:b :c]} {:a ^:displace [:d]})
; => {:a [:b :c]}https://clojure.org/reference/reader#_metadata
|
I noticed that other highlighters make mistakes with these, maybe this is close enough to a universal test set?
|
highlight.js does not have regex languages, does it? Maybe an idea for the future, as GitHub supports regex highlighting. #"\bMy\sRegex!\b" ; Special regex stuff is highlighted
"\bMy\sRegex!\b" But not in all languages 🤔 const RE = /\bMy\sRegex!\b/; |
See the history behind #2751. I'm open to this, but we do not need (or want) a whole regex grammar. (there is sadly no good way to reuse it properly at the moment). If we picked a few key things to focus on and decided to do that within our existing regex support, I think that could be nice. And it would only involve changing: One easy start would be start by moving the existing escapes we recognize into |
src/languages/clojure.js
Outdated
| {match: /\\o[0-3]?[0-7]{1,2}/}, // Unicode Octal 0 - 377 | ||
| {match: /\\u[0-9a-fA-F]{4}/}, // Unicode Hex 0000 - FFFF | ||
| {match: /\\(newline|space|tab|formfeed|backspace|return)/}, // special characters | ||
| {match: /\\\S/} // any non-whitespace char |
There was a problem hiding this comment.
This is so tiny a match... can we do any looking forward to qualify it? I'm imagining false positives with any language that allows \SOMETHING style tags... if we can't qualify it I think we should make it relevance: 0.
There was a problem hiding this comment.
Oh wait, it's [literal \][non space] (even broader than I was first reading it)... yeah I think we should add relevance: 0.
There was a problem hiding this comment.
It is a literal and can appear anywhere, so you are right with relevance: 0.
I didn't put any thought in this or the other modes, what the relevance may be. What is "typically Clojure"?
It would be a nice exercise to generate possible values for modes and try to match them against other languages to automatically calculate the relevance. 🤔
There was a problem hiding this comment.
I added relevance: 0.
Although, I am not sure how many programming languages support the full first Unicode plane. \⠓ is a valid Clojure literal.
|
Looking good, almost there! |
src/languages/clojure.js
Outdated
| {match: /\\o[0-3]?[0-7]{1,2}/}, // Unicode Octal 0 - 377 | ||
| {match: /\\u[0-9a-fA-F]{4}/}, // Unicode Hex 0000 - FFFF | ||
| {match: /\\(newline|space|tab|formfeed|backspace|return)/}, // special characters | ||
| {match: /\\\S/} // any non-whitespace char |
There was a problem hiding this comment.
Oh wait, it's [literal \][non space] (even broader than I was first reading it)... yeah I think we should add relevance: 0.
|
@MrEbbinghaus Thanks so much for help on this! |
|
@joshgoebel Thank you for the clear and fast review. :-) |


Hey, it's me again.
I added some more fixes to Clojure highlighting. Sorry if the scope of this PR is too big, but I couldn't be bothered to open 7 different PRs. :-)
Here is a write-down in your format. I don't know if I should add this to the
CHANGES.mdin this format? Or everything together with my last line into oneenh(clj) Fixup a lot of things.?Checklist
CHANGES.mdFollowing is the list of stuff this PR fixes, together with reference images and my reasoning.
$in symbol breaks highlightingClojure symbols can contain

$. I fixed it.Current:
GitHub:
Number highlighting just matched integer.
This is how valid Clojure numbers are highlighted currently:

I added a regex to include them all.
GitHub does it wrong as well:
Missing character literals
Clojure has different character literals, they were highlighted not at all or wrong. I added the

charactermode to them.Current:
Namespaced map keys highlighting inconsistent with itself and other highlighters
Current:

#:shipand#:personhave different colours.I changed it to be always not coloured.
GitHub:
#:person{:first "Han" :last "Solo" :ship #:ship{:name "Millennium Falcon"}} #::{:a 1, :b 2}Cursive for IntelliJ:


Calva for VS Code highlights them in the colour of the rainbow parentheses:
Add Regex Highlighting
Clojure has a regex literal
#"My\sRegex!", I added theregexscope for this.GitHub:
Remove HINT mode.
Metadata (which can be a keyword, symbol, collection, ...) was highlighted like a comment, and it wasn't consistent.

I removed this mode. You can have huge nested maps of metadata if you like. Removing highlighting from them doesn't make sense.
GitHub:
Cursive:


Calva:
Add
punctuationscope for,In Clojure, the comma
,is treated like a whitespace. It is sometimes used to make compact maps more readable:{:a 1, :b 2}is equal to:{:a 1 :b 2}I have seen editor themes that made them slightly opaque.