Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.

Any form of [namespace/]def* to define entity.global.clojure#65

Merged
winstliu merged 3 commits intoatom:masterfrom
tonsky:patch-1
Apr 28, 2017
Merged

Any form of [namespace/]def* to define entity.global.clojure#65
winstliu merged 3 commits intoatom:masterfrom
tonsky:patch-1

Conversation

@tonsky
Copy link
Contributor

@tonsky tonsky commented Apr 28, 2017

Description of the Change

It’s a convention in Clojure to use macros whose name starts with def to 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)
  • etc

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.

{
'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+'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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=>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@winstliu
Copy link
Contributor

Can you add some specs to cover this change please?

@tonsky
Copy link
Contributor Author

tonsky commented Apr 28, 2017

How do I run specs locally?

@tonsky
Copy link
Contributor Author

tonsky commented Apr 28, 2017

Done. Added some specs

@winstliu
Copy link
Contributor

Cool, thanks!

@winstliu winstliu merged commit 718c3bd into atom:master Apr 28, 2017
Slowki pushed a commit to Slowki/hy.tmLanguage that referenced this pull request Sep 14, 2018
Any form of [namespace/]def* to define entity.global.clojure
Slowki pushed a commit to Slowki/hy.tmLanguage that referenced this pull request Sep 14, 2018
Any form of [namespace/]def* to define entity.global.clojure
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants