Any form of [namespace/]def* to define entity.global.clojure#65
Any form of [namespace/]def* to define entity.global.clojure#65winstliu merged 3 commits intoatom:masterfrom tonsky:patch-1
Conversation
grammars/clojure.cson
Outdated
| { | ||
| 'begin': '(?<=\\()(ns|def|def-|defn|defn-|defvar|defvar-|defmacro|defmacro-|deftest)\\s+' | ||
| # ns, declare and everything that starts with def* or namespace/def* | ||
| 'begin': '(?<=\\()(ns|declare|def[\\w\\.\\-\\_\\:\\+\\=\\>\\<\\!\\?\\*\\d]*|[\\w\\.\\-\\_\\:\\+\\=\\>\\<\\!\\?\\*][\\w\\.\\-\\_\\:\\+\\=\\>\\<\\!\\?\\*\\d]*/def[\\w\\.\\-\\_\\:\\+\\=\\>\\<\\!\\?\\*\\d]*)\\s+' |
There was a problem hiding this comment.
The majority of the symbols in the character class don't need to be escaped (in fact, everything but \\w and \\d don't need to be escaped, and you can put the - at the end of the character class.
In addition, if I'm reading this correctly, something like def+!.?abc8<>: is a valid macro?
There was a problem hiding this comment.
I know, I just decided to be consistent with the rest of the file. This regexp is used in multiple other places to match for valid symbols
There was a problem hiding this comment.
And yes, colon can’t be the last char in symbol name, but everything else is a valid:
user=> (defmacro def+!.?abc8:<> [arg] `(def ~arg))
#'user/def+!.?abc8:<>
user=> (def+!.?abc8:<> x)
#'user/x
user=>There was a problem hiding this comment.
I know, I just decided to be consistent with the rest of the file.
👍. I might create a separate cleanup PR for that then.
but everything else is a valid
Yikes! Looks like I'll need to improve my nonexistent knowledge of Clojure then.
|
Can you add some specs to cover this change please? |
|
How do I run specs locally? |
|
Done. Added some specs |
|
Cool, thanks! |
Any form of [namespace/]def* to define entity.global.clojure
Any form of [namespace/]def* to define entity.global.clojure
Description of the Change
It’s a convention in Clojure to use macros whose name starts with
defto define something. Libraries often define their own custom macros for this:defroutes(Compojure)deftemplate,defsnippet(Enlive)defc,defcs,defcc(Rum)defnav,defcollector,defprotocolpath(Specter)defproject(lein)clojure.spec/def(clojure.spec)schema.core/defn,schema.core/defrecord(Prismatic Schema)Another problem is that many people like to use def* macros from external libraries with namespace aliases (
enlive/deftemplate,rum/defc). Sometimes you just have to, as in Clojure Spec or Prismatic Schema whose names conflict with clojure.core equivalents.This PR adds regular expression that treats all forms whose name starts with
def(with optional namespace) similarly.Alternate Designs
The old way (before change) was whitelisting only def macros from clojure.core. It wasn’t working because it will detect standard vars and functions but will fail to detect custom
def*-like macros.Benefits
Detect and highlight more entities from custom def-like macros.
Possible Drawbacks
Mistakenly detect as entity definition a macro which isn’t entity definition but whose name starts with
def(highly unlikely)Applicable Issues
This convention is very well established so it shouldn’t hurt anyone.