How to display numeric json arrays horizontally in Visual Studio Code? - visual-studio-code

After I saved a json file in Visual Studio Code, it automatically formats the document, that arrays are displayed vertically (by adding line breaks). Since I have giant integer arrays, it makes a quick look into the file nearly impossible. Example:
{
"big_integer_array": [
12,
15,
13,
1,
5,
8,
15,
14,
12,
...
],
"this_value_is_in_line_million": true
}
How can I tell the program, to display numeric arrays horizontally like this:
{
"big_integer_array": [12,15,13,1,5,8,15,14,12, ...],
"this_value_is_in_line_three": true
}
Solution
Use the extension esbenp.prettier-vscode
Set the prettier.printwidth to 99999999999

There is a new setting built-in to vscode v1.70 specifically for this situation:
JSON > Format: Keep Lines <= enable this in your Settings
"json.format.keepLines": true <= or use that setting in your settings.json
This feature allows one to keep the initial line positions upon line
formatting of JSON documents. For example an array containing values
on one line will still contain these values on the same line after
formatting. To enable this feature, enable the option JSON > Format: Keep Lines in the settings.
from https://github.com/microsoft/vscode-docs/blob/vnext/release-notes/v1_70.md#keep-newlines-when-formatting-json
Demo using the Insiders Build - first without the setting enabled and then after enabling the setting:

There is currently no way to customize the VS Code native formatter to format arrays in the way you suggest, however, the prettier formatter will configure them as you suggest. Prettier is a widely used formatter, and is used by a good majority of VS Code users.
The ID for the official prettier extension is: esbenp.prettier-vscode
It's important to note that Prettier will take care of arrays that have a single type of input for you. So if an array is all numbers, or all strings, however; if an array consist of mixed types, numbers, objects, arrays in arrays, strings, boolean values, etc...
Then the way prettier formats the array is contingent on how you place the brackets initially.
Formatting Mixed arrays with Prettier
For this example's sake, lets say have the following array in a json file.
{
"obj": {
"Array": [
"Apple",
"Broccoli",
"Coconut",
"Orange",
"Carrot",
{
"foo": "apple"
}
]
}
}
If you change the brackets in the array, so that the array looks like the following:
{
"obj": {
"Array": [
"Apple",
"Broccoli",
"Coconut",
"Orange",
"Carrot",
{"foo": "apple"}
]
}
}
Your basically telling prettier that you don't want to break up your embedded objects and arrays vertically, but rather, you want to keep them horizontally. Formatting the example above (using prettier) will result in your file looking like the example below:
{
"obj": {
"Array": ["Apple", "Broccoli", "Coconut", "Orange", "Carrot", { "foo": "apple" }]
}
}
However, if you format your array like this:
{
"obj": {
"Array": ["Apple", "Broccoli", "Coconut", "Orange", "Carrot", {
"foo": "apple"
}]
}
Then when you format the above example using prettier, you will produce the output below:
{
"obj": {
"Array": [
"Apple",
"Broccoli",
"Coconut",
"Orange",
"Carrot",
{
"foo": "apple"
}
]
}
}
Also note than the following settings in your VS Code's settings.json file can affect how prettier formats JSON as well:
"prettier.useTabs": true|false (says to use tab, or spaces)
"prettier.tabWidth": Numeric Value (Sets tab spacing qty)
"prettier.printWidth": Numeric Value (Sets line length)
"prettier.bracketSpacing": True|False (Adds/Removes spacing in brackets)

Related

Kafka connect transformations ExtractField$Value while preserving more keys

I have the following message structure:
{
"payload" {
"a": 1,
"b": {"X": 1, "Y":2}
},
"timestamp": 1659692671
}
I want to use SMTs to get the following structure:
{
"a": 1,
"b": {"X": 1, "Y":2},
"timestamp": 1659692671
}
When I use ExtractField$Value for payload, I cannot preserve timestamp.
I cannot use Flatten because "b"'s structure should not be flatten.
Any ideas?
Thanks
Unfortunately, moving a field into another Struct isn't possible with the built-in transforms. You'd have to write your own, or use a stream-processing library before the data reaches the connector.
Note that Kafka records themselves have a timestamp, so do you really need the timestamp as a field in the value? One option is to extract the timestamp, then flatten, then add it back. However, this will override the timestamp that the producer had set with that value.

How would I make a VSCode syntax highlighter that is not extremely hard to understand?

I'm trying to make a custom syntax highlighter for my own markup language. All the examples are complicated, missing steps and are very, very hard to understand.
Is there anything that fully documents how to make a syntax highlighter?
(for VSCode, by the way)
For example, this video https://www.youtube.com/watch?v=5msZv-nKebI which has an extremely large skip in the middle and doesn't really explain much.
My current code, made with Yeoman generator is:
{
"$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
"name": "BetterMarkupLanguage",
"patterns": [
{
"include": "#keywords"
},
{
"include": "#strings"
}
],
"repository": {
"keywords": {
"patterns": [{
"name": "entity.other.bml",
"match": "\\b({|}|\\\\|//)\\b"
}]
},
"strings": {
"name": "string.quoted.double.bml",
"begin": "`",
"end": "`"
}
},
"scopeName": "source.bml"
}
Synopsis
I'm not sure at what level you're approaching the problem, but there are basically two kinds of syntax-highlighting:
Just identify little nuggets of canonically identifiable tokens (strings, numbers, maybe operators, reserved words, comments) and highlight those, OR
Do the former, and also add in context awareness.
tmLanguage engines basically have two jobs:
Assign scopes.
Maintain a stack of contexts.
Samples
Lets say you make a definition for integers with this pattern:
"integers": {
"patterns": [{
"name": "constant.numeric.integer.bml",
"match": "[+-]\\d+"
}]
},
When the engine matches an integer like that, it will match to the end of the regex, assign the scope from "name", and then continue matching things in this same context.
Compare that to your "strings" definition:
"strings": {
"name": "string.quoted.double.bml", // should be string.quoted.backtick.bml
"begin": "`",
"end": "`"
},
Those "begin" and "end" markers denote a change in the tmLanguage stack. You have pushed into a new context inside of a string.
Right now, there are no matches configured in this context, but you could do that by adding a "patterns" key with some "match"es or "include"s. "include"s are other sets of matches like "integers" that you've defined elsewhere. You can add it to the "strings" patterns to match integers inside strings. Matching integers might be silly, but think about escaped backticks: You want to scope those and stay in the same context within "strings". You don't want those popping back out prematurely.
Order of operations
You'll eventually notice that the first pattern encountered is matched. Remember the integers set? What happens when you have 45.125? It will decide to match the 45 and the 125 as integers and ignore the . entirely. If you have a "floats" pattern, you want to include that before your naïve integer pattern. Both these "numbers" definitions below are equivalent, but one lets you re-use floats and integers independently (if that's useful for your language):
"numbers": {
"patterns": [
{"include": "#floats"},
{"include": "#integers"}
]
},
"integers": {
"patterns": [{
"name": "constant.numeric.integer.bml",
"match": "[+-]\\d+"
}]
},
"floats": {
"patterns": [{
"name": "constant.numeric.float.bml",
"match": "[+-]\\d+\\.\\d*"
}]
},
"numbers": {
"patterns": [{
"name": "constant.numeric.float.bml",
"match": "[+-]\\d+\\.\\d*"
}, {
"name": "constant.numeric.integer.bml",
"match": "[+-]\\d+"
}]
},
Doing it right
The "numbers"/"integers"/"floats" thing was trivial, but well-designed syntax definitions will define utility groups that "include" equivalent things together for re-usability:
A normal programming language will have things like
A "statements" group of all things that can be directly executed. This then may or may not (language-dependent) include...
An "expressions" group of things you can put on the right-hand-side of an assignment, which will definitely include...
An "atoms" group of strings, numbers, chars, etc. that might also be valid statements, but that also depends on your language.
"function-definitions" probably won't be in "expressions" (unless they are lambdas) but probably would be in "statements." Function definitions might push into a context that lets you return and so on.
A markup language like yours might have
An "inline" group to keep track of all the markup one can have within a block.
A "block" group to hold lists, quotes, paragraphs, headers.
...
Though there is more you could learn (capture groups, injections, scope conventions, etc.), this is hopefully a practical overview for getting started.
Conclusion
When you write your syntax highlighting, think to yourself: Does matching this token put me in a place where things like it can be matched again? Or does it put me in a different place where different things (more or fewer) ought to be matched? If the latter, what returns me to the original set of matches?

JSON data getting retrieved from mongodb with formats added explicitly inside field e.g.({"field": {$numberInt: "20"}}). How to process that data?

I have used mongo import to import data into mongodb from csv files. I am trying to retrieve data from an Mongodb realm service. The returned data for the entry is as follows:
{
"_id": "6124edd04543fb222e",
"Field1": "some string",
"Field2": {
"$numberDouble": "145.81"
},
"Field3": {
"$numberInt": "0"
},
"Field4": {
"$numberInt": "15"
},
"Field5": {
"$numberInt": "0"
}
How do I convert this into normal JSON by removing $numberInt and $numberDouble like :
{
"_id": "6124edd04543fb222e",
"Field1": "some string",
"Field2": 145.8,
"Field3": 0,
"Field4": 15,
"Field5": 0
}
The fields are also different for different documents so cannot use Mongoose directly. Are there any solutions to this?
Also would help to know why the numbers are being stored as $numberInt:"".
Edit:
For anyone with the same problem this is how I solved it.
The array of documents is in EJSON format instead of JSON like said in the upvoted answer. To covert it back into normal JSON, I used JSON.stringify to first convert each document I got from map function into string and then parsed it using EJSON.parse with
{strict:false} (this option is important)
option to convert it into normal JSON.
{restaurants.map((restaurant) => {
restaurant=EJSON.parse(JSON.stringify(restaurant),{strict:false});
}
EJSON.parse documentation here. The module to be installed and imported is mongodb-extjson.
The format with $numberInt etc. is called (MongoDB) Extended JSON.
You are getting it on the output side either because this is how you inserted your data (meaning your inserted data was incorrect, you need to fix the ingestion side) or because you requested extended JSON serialization.
If the data in the database is correct, and you want non-extended JSON output, you generally need to write your own serializers to JSON since there are multiple possibilities of how to format the data. MongoDB's JSON output format is the Extended JSON you're seeing in your first quote.

Regular expression for detecting !this not working

I'm trying to implement support for a new language in VS Code, using a tmGrammar json file. In this language variables start with !, and there is a special reserved variable called !this in this language.
I want to apply one class to all common variables and other for the !this variable. I'm doing this in my json file:
"repository": {
"keywords": {
"patterns": [
{
"name": "constant.character",
"match": "(?i)\\b(!this)\\b"
},
{
"name": "variable.other",
"match": "(?i)\\![a-z0-9]+"
},
}
}
But this is coloring both !this and !someVar to the same color.
If I change the first rule to (?i)\\b(this)\\b, without the ! the word this get colored correctly.
I also tried do change the order of the rules, but now matter what I do makes !this the same color as common variables.
Is there a problem with the first regular expression?

Expand a date range in mongodb

I have a document structure like
{
"startDate": ISODate("2015-01-01T00:00:00Z"),
"endDate" : ISODate("2015-01-10T00:00:00Z"),
"foo" : "bar"
}
Is it possible to expand the date range like this?
{
"dates": [
ISODate("2015-01-01T00:00:00Z"),
ISODate("2015-01-02T00:00:00Z"),
ISODate("2015-01-03T00:00:00Z"),
ISODate("2015-01-04T00:00:00Z"),
ISODate("2015-01-05T00:00:00Z"),
ISODate("2015-01-06T00:00:00Z"),
ISODate("2015-01-07T00:00:00Z"),
ISODate("2015-01-08T00:00:00Z"),
ISODate("2015-01-09T00:00:00Z"),
ISODate("2015-01-10T00:00:00Z")
]
}
As far as I understood you want to add field dates for all your documents. Here is an approach I would use (you can do this in mongoshell):
1) iterate over all the documents modifying them
db.coll.find()..snapshot().forEach(function(o){
o.dates = func(o.startDate, o.endDate);
db.coll.save(o);
});
2) where you function func is something similar to this answer (you need to modify it a little bit because it looks like you need only dates without time included there.