mongodb-ace-mode ![](https://img.shields.io/npm/v/mongodb-ace-mode.svg?style=flat-square)
ACE mode that provides highlighting for MongoDB
Installation
npm install --save mongodb-ace-mode
Related
Highlighting Rules
Operators -> ace_function
![MongoDB operator highlighting](https://user-images.githubusercontent.com/23074/53835489-9ec81f80-3f5b-11e9-9859-419879321d64.png)
Why? Mental model of operators to functions. (e.g. $avg: 'a'
, avg(a)
)
Given:
max_cpi: {$max: "$trends.icecream_cpi"}
<div class="ace_line" style="height:15px">
<span class="ace_identifier">max_cpi</span>
<span class="ace_punctuation ace_operator">:</span>
<span class="ace_paren ace_lparen">{</span>
<span class="ace_support ace_function">$max</span>
<span class="ace_punctuation ace_operator">:</span>
<span class="ace_string ace_quasi ace_start">"</span>
<span class="ace_variable ace_language">$trends.icecream_cpi</span>
<span class="ace_string ace_quasi ace_end">"</span>
<span class="ace_paren ace_rparen">}</span>
</div>
Field usage -> ace_variable
![MongoDB field highlighting](https://user-images.githubusercontent.com/23074/53902120-806f2c00-400e-11e9-9bb1-5a89829de189.png)
Why? Nothing worse than off by one typos... So now really easy to catch because "field"
and "$field"
will be styled differently.
Given:
type: "$type"
<div class="ace_line" style="height:15px">
<span class="ace_identifier">type</span>
<span class="ace_punctuation ace_operator">:</span>
<span class="ace_string ace_quasi ace_start">"</span>
<span class="ace_variable ace_parameter">$type</span>
<span class="ace_punctuation ace_operator">"</span>
</div>
Discovery
Thinking
db.icecream_data.aggregate([
{
_id: 0,
average_cpi: {
$avg: "$trends.icecream_cpi"
},
max_cpi: {
$max: "$trends.icecream_cpi"
},
min_cpi: {
$min: "$trends.icecream_cpi"
},
cpi_deviation: {
$stdDevPop: "$trends.icecream_cpi"
}
}
]);
db.icecream_data.aggregate([{
_id: include(false),
average_cpi: avg('trends.icecream_cpi'),
max_cpi: max('trends.icecream_cpi'),
min_cpi: min('trends.icecream_cpi'),
cpi_deviation: stdDevPop('trends.icecream_cpi')
}]);
db.icecream_data.aggregate([{
_id: include(false),
average_cpi: avg(`${trends.icecream_cpi}`),
max_cpi: max(`${trends.icecream_cpi}`),
min_cpi: min(`${trends.icecream_cpi}`),
cpi_deviation: stdDevPop(`${trends.icecream_cpi}`)
}]);
There are 3 different ways I was thinking about this to get as close to what a developer would expect. (Top left editor panel in screenshot).
Case #3
of js template strings: We can discriminate between "|'
and $field
in aggregation styling, just like `\
, ${|}
, and field
for a template string. The power here is:
field
links back visually to the property on the left- Avoid typos of 'field' instead of '$field' (especially when creating a view!) by distinguishing those two.
![](https://www.dropbox.com/s/7soe72zzc062kfm/Screenshot%202019-03-01%2010.20.14.png?dl=1)
Data
The Best Visual Studio Code Dark and Light Themes (Updated Feb 2019)
OneDark Pro Most installed by a giant margin
Pertsonal preference: Monokai Used for more than a decade as Editor of choice has changed (TextMate :arrow_right: SublimeText :arrow_right: Atom :arrow_right: VSCode)
Links
Basic
Given:
average_cpi: {$avg: "$trends.icecream_cpi" }
Want to highlight:
$trends.icecream_cpi
$avg
"
around $trends.icecream_cpi
separated
See
HTML we want looks something like:
<div class="ace_line" style="height: 16px; top: 32px;">
<span class="ace_identifier">average_cpi</span>
<span class="ace_punctuation ace_operator">:</span>
<span class="ace_paren ace_lparen">{</span>
<span class="ace_identifier ace_support ace_function">$avg</span>
<span class="ace_punctuation ace_operator">:</span>
<span class="ace_string ace_quasi ace_start">"</span>
<span class="ace_variable">$trends.icecream_cpi</span>
<span class="ace_string ace_quasi ace_end">"</span>
<span class="ace_paren ace_rparen">}</span>
</div>
$avg
Agg Operator:
- ace_support.ace_function
- ace_keyword.ace_operator
- ace_function
$trends.icecream_cpi Field:
- ace_variable
- ace_identifier -> nice as it links back to semantics of
average_cpi
Base on interpolated strings. JSX mode kind of implements this:
https://github.com/ajaxorg/ace/blob/master/lib/ace/mode/javascript_highlight_rules.js#L375-L391
{
token : "string.quasi.start",
regex : /`/,
push : [{
token : "constant.language.escape",
regex : escapedRe
}, {
token : "paren.quasi.start",
regex : /\${/,
push : "start"
}, {
token : "string.quasi.end",
regex : /`/,
next : "pop"
}, {
defaultToken: "string.quasi"
}]
}
average_cpi
- ace_identifier
- ace_variable.ace_parameter?
Advanced
$lookup:
- special props at top level:
from
, let
, pipeline
...
stageOperator: '$lookup',
stage: `{
from: "air_airlines",
let: { maybe_name: "$airlines" },
pipeline: [
{
$match: {
...
$and $or conditionals:
- ace_keyword.ace_operator
- ace_keyword.ace_control -> flow control keywords
https://codepen.io/imlucas/pen/eXJOrm
/**
* Parens
* {}[]()
*/
.ace-mongodb .ace_paren {
font-weight: normal;
color: blue;
}
/**
* Quotes around a "field name"
* "$trends.icecream_cpi"
*/
.ace_string.ace_quasi{
color: magenta !important;
}
/**
* Field names
* _id, average_cpi, etc.
*/
.ace_identifier {
color: green;
}
/**
* Aggregation Operators
* $avg $min $max
*/
.ace-mongodb .ace_support.ace_function {
color: orange;
}
/**
* BOILERPLATE BELOW
*/
.ace-mongodb .ace_gutter {
background: #f5f6f7;
color: #999999;
}
.ace-mongodb {
border: 1px solid #eee;
padding: 10px;
//background: #f5f6f7;
color: #000;
font-family: Monaco;
}
.ace-mongodb .ace_keyword {
color: #999999;
font-weight: normal;
}
.ace-mongodb .ace_gutter-cell {
padding-left: 5px;
padding-right: 10px;
}
.ace-mongodb .ace_string {
color: #5b81a9;
}
.ace-mongodb .ace_boolean {
color: #5b81a9;
font-weight: normal;
}
.ace-mongodb .ace_constant.ace_numeric {
color: #5b81a9;
}
.ace-mongodb .ace_string.ace_regexp {
color: #5b81a9;
}
.ace-mongodb .ace_variable.ace_class {
color: teal;
}
.ace-mongodb .ace_constant.ace_buildin {
color: #0086B3;
}
/*
.ace-mongodb .ace_support.ace_function {
color: #0086B3;
}
*/
.ace-mongodb .ace_comment {
color: #998;
font-style: italic;
}
.ace-mongodb .ace_variable.ace_language {
color: #0086B3;
}
<div class="ace-mongodb">
<div class="ace_layer ace_text-layer" style="padding: 0px 4px;">
<div class="ace_line" style="height:15px">
<span class="ace_paren ace_lparen">{</span>
</div>
<div class="ace_line" style="height:15px"> <span class="ace_identifier">_id</span><span class="ace_punctuation ace_operator">:</span><span class="ace_constant ace_numeric"> 0</span><span class="ace_punctuation ace_operator">,</span></div>
<div class="ace_line" style="height:15px"> <span class="ace_identifier">average_cpi</span><span class="ace_punctuation ace_operator">:</span> <span class="ace_paren ace_lparen">{</span><span class="ace_support ace_function">$avg</span><span class="ace_punctuation ace_operator">:</span><span class="ace_string ace_quasi ace_start">"</span><span class="ace_variable ace_language">$trends.icecream_cpi</span><span class="ace_string ace_quasi ace_end">"</span><span class="ace_paren ace_rparen">}</span><span class="ace_punctuation ace_operator">,</span></div>
<div class="ace_line" style="height:15px"> <span class="ace_identifier">max_cpi</span><span class="ace_punctuation ace_operator">:</span><span class="ace_paren ace_lparen">{</span><span class="ace_support ace_function">$max</span><span class="ace_punctuation ace_operator">:</span><span class="ace_string ace_quasi ace_start">"</span><span class="ace_variable ace_language">$trends.icecream_cpi</span><span class="ace_string ace_quasi ace_end">"</span><span class="ace_paren ace_rparen">}</span><span class="ace_punctuation ace_operator">,</span>
</div>
<div class="ace_line" style="height:15px">
<span class="ace_identifier">min_cpi</span><span class="ace_punctuation ace_operator">:</span><span class="ace_paren ace_lparen">{</span><span class="ace_support ace_function">$min</span><span class="ace_punctuation ace_operator">:</span><span class="ace_string ace_quasi ace_start">"</span><span class="ace_variable ace_language">$trends.icecream_cpi</span><span class="ace_string ace_quasi ace_end">"</span><span class="ace_paren ace_rparen">}</span><span class="ace_punctuation ace_operator">,</span></div>
<div class="ace_line" style="height:15px">
<span class="ace_identifier">cpi_deviation</span><span class="ace_punctuation ace_operator">:</span><span class="ace_paren ace_lparen">{</span><span class="ace_support ace_function">$stdDevPop</span><span class="ace_punctuation ace_operator">:</span><span class="ace_string ace_quasi ace_start">"</span><span class="ace_variable ace_language">$trends.icecream_cpi</span><span class="ace_string ace_quasi ace_end">"</span><span class="ace_paren ace_rparen">}</span></div>
<div class="ace_line" style="height:15px"><span class="ace_paren ace_rparen">}</span>
</div>
</div>
</div>