You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Update styleguide with cypherfmt rules and recommend its usage (#1289)
## Description
Hey, docs team! For the past few months, as a master's thesis project,
@simonthuresson and I have been working on a formatter for Cypher. In
short, the formatter formats a Cypher query so that it follows the
styleguide recommendations. During development, we found that the
styleguide is quite far from comprehensive, and also some of the cypher
snippets in the docs disagree with it as well. Filling out the missing
pieces and addressing any ambiguity became a fairly large part of our
project, and we wrote extensively about how we did so in our thesis,
which you can find here:
- [An Evaluation of Approaches to Code
Formatting](https://lup.lub.lu.se/luur/download?func=downloadFile&recordOId=9188816&fileOId=9188817)
In short, we did a survey on styling preferences, and talked to Cypher
users to try and figure out what the most preferred way of writing
Cypher was. We then took those learnings and implemented it in our
formatter so that it could automatically enforce the rules.
This PR is a draft of how we think the styleguide should be updated in
accordance with the new rules. I did not put a lot of time into the
wording and structure of the recommendations, as I would prefer to leave
that to the professionals (you), but I provided some examples which
hopefully illustrate the ideas well. If you want more detailed context
on the rules, refer to the thesis (chapter 4 specifically). I also
included a recommendation at the start of the style guide that users
should use our formatter, as manual formatting is generally not a great
idea.
#### Note
I included a link to the language support npm package that I claim
provides a command-line tool. This is not actually live yet, but will be
soon: neo4j/cypher-language-support#518
## Try it out
If you want to get a better feel for how the formatter works and how it
applies the rules, you can try it out in:
- Query in the Aura console (the ... menu -> format query)
- [The Cypher Language Support CodeMirror
playground](https://neo4j.github.io/cypher-language-support/)
- [VS
Code](https://marketplace.visualstudio.com/items?itemName=neo4j-extensions.neo4j-for-vscode)
I would also recommend running any Cypher queries you add to the docs
through the formatter first, to ensure that the styling is always
consistent across all documentation.
## Note
This is my last day at Neo4j, so I probably will not be able to respond
to any comments on this PR. If you have questions, direct them at the
language support team (#team-cypher-language-support), they have
reviewed every line of code in the formatter, and are well aware of how
it works. Feel free to completely change the wording I have used, this
is just a first draft that I wanted to get in before leaving.
---------
Co-authored-by: Jens Pryce-Åklundh <[email protected]>
Copy file name to clipboardExpand all lines: modules/ROOT/pages/styleguide.adoc
+123-1Lines changed: 123 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,6 +9,9 @@ The purpose of the Cypher styleguide is to make queries as easy to read as possi
9
9
10
10
For rules and recommendations for naming of labels, relationship types and properties, please see the xref::syntax/naming.adoc[Naming rules and recommendations].
11
11
12
+
The best way to make sure your queries follow the styling rules is to use `cypherfmt`, the official Cypher formatter.
13
+
It is available as part of the https://marketplace.visualstudio.com/items?itemName=neo4j-extensions.neo4j-for-vscode[Neo4j VS Code Extension], and as a command line tool through the https://www.npmjs.com/package/@neo4j-cypher/language-support[Neo4j Cypher Language Support npm package].
14
+
12
15
[[cypher-styleguide-general-recommendations]]
13
16
== General recommendations
14
17
@@ -18,7 +21,6 @@ For rules and recommendations for naming of labels, relationship types and prope
18
21
For example: `toString()`.
19
22
* If you are storing Cypher statements in a separate file, use the file extension `.cypher`.
20
23
21
-
22
24
[[cypher-styleguide-indentation-and-line-breaks]]
23
25
== Indentation and line breaks
24
26
@@ -115,6 +117,126 @@ WHERE EXISTS { (a)-->(b:B) }
115
117
RETURN a.prop
116
118
----
117
119
120
+
* Limit line length to 80 characters if possible.
121
+
Line breaks should be applied starting from the outermost group, with each nested group breaking until either the line fits or no more line breaks can be inserted.
122
+
Add two spaces of indentation for each nested broken group.
123
+
124
+
.Bad
125
+
[source, cypher]
126
+
----
127
+
MATCH (n)
128
+
WHERE n.prop <> 'a' AND n.prop <> 'b' AND n.prop <> 'c' AND n.prop <> 'd' AND n.prop <> 'e'
129
+
RETURN n
130
+
----
131
+
132
+
.Good
133
+
[source, cypher]
134
+
----
135
+
MATCH (n)
136
+
WHERE
137
+
n.prop <> 'a' AND
138
+
n.prop <> 'b' AND
139
+
n.prop <> 'c' AND
140
+
n.prop <> 'd' AND
141
+
n.prop <> 'e'
142
+
RETURN n
143
+
----
144
+
145
+
* Start `ORDER BY` and `LIMIT` clauses on new lines.
146
+
147
+
.Bad
148
+
[source, cypher]
149
+
----
150
+
MATCH (n)
151
+
RETURN 5 ORDER BY n.prop LIMIT 10
152
+
----
153
+
154
+
.Good
155
+
[source, cypher]
156
+
----
157
+
MATCH (n)
158
+
RETURN 5
159
+
ORDER BY n.prop
160
+
LIMIT 10
161
+
----
162
+
163
+
* A group containing a `CASE` expression should always break, and each `WHEN`, `ELSE`, and `END` should be put on a new line.
164
+
Additionally, `WHEN` and `ELSE` should add two spaces of indentation.
165
+
166
+
.Bad
167
+
[source, cypher]
168
+
----
169
+
MATCH (n:Person {name: 'Alice'})
170
+
RETURN CASE WHEN n.age >= 18 THEN 'Adult' ELSE 'Minor' END AS ageGroup
171
+
----
172
+
173
+
.Good
174
+
[source, cypher]
175
+
----
176
+
MATCH (n:Person {name: 'Alice'})
177
+
RETURN
178
+
CASE
179
+
WHEN n.age >= 18 THEN 'Adult'
180
+
ELSE 'Minor'
181
+
END AS ageGroup
182
+
----
183
+
184
+
* When a line ends with a list or map literal that does not fit within the maximum line width, place the opening bracket or brace on the same line as the clause that introduces it.
185
+
Start each element of the literal on a new line, indented two spaces further than the line containing the opening bracket or brace.
186
+
Close the literal at the original indentation level.
187
+
188
+
.Bad
189
+
[source, cypher]
190
+
----
191
+
RETURN
192
+
[
193
+
"Alice",
194
+
"Bob",
195
+
"Charlie",
196
+
"David",
197
+
"Eve",
198
+
"Frank",
199
+
"Grace",
200
+
"Heidi",
201
+
"Ivan",
202
+
"Judy"
203
+
]
204
+
----
205
+
206
+
.Good
207
+
[source, cypher]
208
+
----
209
+
RETURN [
210
+
"Alice",
211
+
"Bob",
212
+
"Charlie",
213
+
"David",
214
+
"Eve",
215
+
"Frank",
216
+
"Grace",
217
+
"Heidi",
218
+
"Ivan",
219
+
"Judy"
220
+
]
221
+
----
222
+
223
+
* A single blank line may be used to separate clauses, queries or comments.
0 commit comments