0
# Code Formatting
1
2
Jsonnet provides powerful code formatting capabilities through both a C library API and the `jsonnetfmt` command-line tool. The formatter offers extensive customization options for indentation, spacing, comment styles, string literal preferences, and import organization.
3
4
## Capabilities
5
6
### Formatting Configuration Functions
7
8
Functions for configuring the formatter's style and behavior options.
9
10
```c { .api }
11
/**
12
* Set indentation level when reformatting (number of spaces).
13
* @param vm VM instance
14
* @param n Number of spaces, must be > 0
15
*/
16
void jsonnet_fmt_indent(struct JsonnetVm *vm, int n);
17
18
/**
19
* Set maximum number of consecutive blank lines allowed.
20
* @param vm VM instance
21
* @param n Number of blank lines, must be > 0
22
*/
23
void jsonnet_fmt_max_blank_lines(struct JsonnetVm *vm, int n);
24
25
/**
26
* Set preferred style for string literals.
27
* @param vm VM instance
28
* @param c String style: 'd' (double quotes), 's' (single quotes), 'l' (leave as-is)
29
*/
30
void jsonnet_fmt_string(struct JsonnetVm *vm, int c);
31
32
/**
33
* Set preferred style for line comments.
34
* @param vm VM instance
35
* @param c Comment style: 'h' (hash #), 's' (slash //), 'l' (leave as-is)
36
*/
37
void jsonnet_fmt_comment(struct JsonnetVm *vm, int c);
38
39
/**
40
* Set whether to add extra space on the inside of arrays.
41
* @param vm VM instance
42
* @param v 1 to enable array padding, 0 to disable
43
*/
44
void jsonnet_fmt_pad_arrays(struct JsonnetVm *vm, int v);
45
46
/**
47
* Set whether to add extra space on the inside of objects.
48
* @param vm VM instance
49
* @param v 1 to enable object padding, 0 to disable
50
*/
51
void jsonnet_fmt_pad_objects(struct JsonnetVm *vm, int v);
52
53
/**
54
* Use syntax sugar where possible with field names.
55
* @param vm VM instance
56
* @param v 1 to enable pretty field names, 0 to disable
57
*/
58
void jsonnet_fmt_pretty_field_names(struct JsonnetVm *vm, int v);
59
60
/**
61
* Sort top-level imports in alphabetical order.
62
* @param vm VM instance
63
* @param v 1 to enable import sorting, 0 to disable
64
*/
65
void jsonnet_fmt_sort_imports(struct JsonnetVm *vm, int v);
66
67
/**
68
* Reformat after desugaring for debugging purposes.
69
* @param vm VM instance
70
* @param v 1 to enable debug desugaring output, 0 to disable
71
*/
72
void jsonnet_fmt_debug_desugaring(struct JsonnetVm *vm, int v);
73
```
74
75
### Core Formatting Functions
76
77
Primary functions for formatting Jsonnet code from files or strings.
78
79
```c { .api }
80
/**
81
* Reformat a file containing Jsonnet code.
82
* @param vm VM instance
83
* @param filename Path to file containing Jsonnet code
84
* @param error Output parameter set to 1 on error, 0 on success
85
* @returns Formatted Jsonnet code on success, error message on failure (use jsonnet_realloc to free)
86
*/
87
char *jsonnet_fmt_file(struct JsonnetVm *vm, const char *filename, int *error);
88
89
/**
90
* Reformat a string containing Jsonnet code.
91
* @param vm VM instance
92
* @param filename Path to file (used in error messages)
93
* @param snippet Jsonnet code to format
94
* @param error Output parameter set to 1 on error, 0 on success
95
* @returns Formatted Jsonnet code on success, error message on failure (use jsonnet_realloc to free)
96
*/
97
char *jsonnet_fmt_snippet(struct JsonnetVm *vm, const char *filename, const char *snippet, int *error);
98
```
99
100
## Formatting Options
101
102
### Indentation Styles
103
104
```c
105
// 2-space indentation (default)
106
jsonnet_fmt_indent(vm, 2);
107
108
// 4-space indentation
109
jsonnet_fmt_indent(vm, 4);
110
111
// Tab indentation not supported - use spaces only
112
```
113
114
**Example output with different indentation:**
115
```jsonnet
116
// 2-space indentation
117
{
118
name: "example",
119
config: {
120
port: 8080,
121
ssl: true
122
}
123
}
124
125
// 4-space indentation
126
{
127
name: "example",
128
config: {
129
port: 8080,
130
ssl: true
131
}
132
}
133
```
134
135
### String Literal Styles
136
137
```c
138
// Double quotes (default)
139
jsonnet_fmt_string(vm, 'd');
140
141
// Single quotes
142
jsonnet_fmt_string(vm, 's');
143
144
// Leave as-is
145
jsonnet_fmt_string(vm, 'l');
146
```
147
148
**Example transformations:**
149
```jsonnet
150
// Original mixed style
151
{ name: 'Alice', message: "Hello World!" }
152
153
// After double quote formatting
154
{ name: "Alice", message: "Hello World!" }
155
156
// After single quote formatting
157
{ name: 'Alice', message: 'Hello World!' }
158
```
159
160
### Comment Styles
161
162
```c
163
// Hash comments (default)
164
jsonnet_fmt_comment(vm, 'h');
165
166
// Slash comments
167
jsonnet_fmt_comment(vm, 's');
168
169
// Leave as-is
170
jsonnet_fmt_comment(vm, 'l');
171
```
172
173
**Example transformations:**
174
```jsonnet
175
// Original mixed comments
176
{
177
// This is a slash comment
178
name: "app",
179
# This is a hash comment
180
version: "1.0"
181
}
182
183
// After hash comment formatting
184
{
185
# This is a slash comment
186
name: "app",
187
# This is a hash comment
188
version: "1.0"
189
}
190
```
191
192
### Padding Options
193
194
```c
195
// Enable array padding
196
jsonnet_fmt_pad_arrays(vm, 1);
197
198
// Enable object padding
199
jsonnet_fmt_pad_objects(vm, 1);
200
```
201
202
**Example output with padding:**
203
```jsonnet
204
// Without padding (default)
205
{
206
items: [1, 2, 3],
207
config: {name: "app", port: 8080}
208
}
209
210
// With padding enabled
211
{
212
items: [ 1, 2, 3 ],
213
config: { name: "app", port: 8080 }
214
}
215
```
216
217
### Field Name Formatting
218
219
```c
220
// Enable pretty field names
221
jsonnet_fmt_pretty_field_names(vm, 1);
222
```
223
224
**Example transformations:**
225
```jsonnet
226
// Original quoted field names
227
{
228
"simple_name": "value1",
229
"name-with-dashes": "value2",
230
"123numeric": "value3"
231
}
232
233
// After pretty field name formatting
234
{
235
simple_name: "value1", // Quotes removed
236
"name-with-dashes": "value2", // Quotes kept (contains dashes)
237
"123numeric": "value3" // Quotes kept (starts with number)
238
}
239
```
240
241
### Import Sorting
242
243
```c
244
// Enable import sorting
245
jsonnet_fmt_sort_imports(vm, 1);
246
```
247
248
**Example transformation:**
249
```jsonnet
250
// Original unsorted imports
251
local utils = import "utils.jsonnet";
252
local config = import "config.jsonnet";
253
local base = import "base.jsonnet";
254
255
// After sorting
256
local base = import "base.jsonnet";
257
local config = import "config.jsonnet";
258
local utils = import "utils.jsonnet";
259
```
260
261
## Usage Examples
262
263
### Basic C API Usage
264
265
```c
266
#include "libjsonnet.h"
267
#include "libjsonnet_fmt.h"
268
269
int main() {
270
struct JsonnetVm *vm = jsonnet_make();
271
272
// Configure formatting options
273
jsonnet_fmt_indent(vm, 4);
274
jsonnet_fmt_string(vm, 's'); // Single quotes
275
jsonnet_fmt_comment(vm, 'h'); // Hash comments
276
jsonnet_fmt_pad_arrays(vm, 1); // Pad arrays
277
jsonnet_fmt_pad_objects(vm, 1); // Pad objects
278
jsonnet_fmt_pretty_field_names(vm, 1); // Pretty field names
279
jsonnet_fmt_sort_imports(vm, 1); // Sort imports
280
281
int error;
282
char *formatted = jsonnet_fmt_file(vm, "config.jsonnet", &error);
283
284
if (error) {
285
fprintf(stderr, "Formatting error: %s\n", formatted);
286
} else {
287
printf("%s", formatted);
288
}
289
290
jsonnet_realloc(vm, formatted, 0); // Free result
291
jsonnet_destroy(vm);
292
return error;
293
}
294
```
295
296
### Format Code Snippet
297
298
```c
299
struct JsonnetVm *vm = jsonnet_make();
300
jsonnet_fmt_indent(vm, 2);
301
302
const char* code = "{ name:'Alice',age:30,config:{port:8080,ssl:true} }";
303
304
int error;
305
char *formatted = jsonnet_fmt_snippet(vm, "snippet.jsonnet", code, &error);
306
307
if (!error) {
308
printf("Formatted code:\n%s\n", formatted);
309
// Output:
310
// {
311
// name: 'Alice',
312
// age: 30,
313
// config: {
314
// port: 8080,
315
// ssl: true
316
// }
317
// }
318
}
319
320
jsonnet_realloc(vm, formatted, 0);
321
jsonnet_destroy(vm);
322
```
323
324
### Complete Formatting Configuration
325
326
```c
327
void configure_formatter(struct JsonnetVm *vm) {
328
// Indentation: 4 spaces
329
jsonnet_fmt_indent(vm, 4);
330
331
// Maximum 1 consecutive blank line
332
jsonnet_fmt_max_blank_lines(vm, 1);
333
334
// String style: double quotes
335
jsonnet_fmt_string(vm, 'd');
336
337
// Comment style: slash comments
338
jsonnet_fmt_comment(vm, 's');
339
340
// Enable padding for arrays and objects
341
jsonnet_fmt_pad_arrays(vm, 1);
342
jsonnet_fmt_pad_objects(vm, 1);
343
344
// Enable pretty field names and import sorting
345
jsonnet_fmt_pretty_field_names(vm, 1);
346
jsonnet_fmt_sort_imports(vm, 1);
347
}
348
349
int format_file(const char *filename) {
350
struct JsonnetVm *vm = jsonnet_make();
351
configure_formatter(vm);
352
353
int error;
354
char *result = jsonnet_fmt_file(vm, filename, &error);
355
356
if (!error) {
357
// Write to output file or stdout
358
FILE *out = fopen("formatted_output.jsonnet", "w");
359
fprintf(out, "%s", result);
360
fclose(out);
361
}
362
363
jsonnet_realloc(vm, result, 0);
364
jsonnet_destroy(vm);
365
return error;
366
}
367
```
368
369
### Batch Formatting
370
371
```c
372
#include <dirent.h>
373
#include <string.h>
374
375
int format_directory(const char *dir_path) {
376
struct JsonnetVm *vm = jsonnet_make();
377
378
// Configure consistent style
379
jsonnet_fmt_indent(vm, 2);
380
jsonnet_fmt_string(vm, 'd');
381
jsonnet_fmt_sort_imports(vm, 1);
382
jsonnet_fmt_pretty_field_names(vm, 1);
383
384
DIR *dir = opendir(dir_path);
385
struct dirent *entry;
386
387
while ((entry = readdir(dir)) != NULL) {
388
if (strstr(entry->d_name, ".jsonnet") != NULL) {
389
char filepath[256];
390
snprintf(filepath, sizeof(filepath), "%s/%s", dir_path, entry->d_name);
391
392
int error;
393
char *formatted = jsonnet_fmt_file(vm, filepath, &error);
394
395
if (!error) {
396
// Write back to original file
397
FILE *file = fopen(filepath, "w");
398
fprintf(file, "%s", formatted);
399
fclose(file);
400
printf("Formatted: %s\n", filepath);
401
} else {
402
fprintf(stderr, "Error formatting %s: %s\n", filepath, formatted);
403
}
404
405
jsonnet_realloc(vm, formatted, 0);
406
}
407
}
408
409
closedir(dir);
410
jsonnet_destroy(vm);
411
return 0;
412
}
413
```
414
415
### Debug Desugaring
416
417
```c
418
// Enable debug desugaring to see expanded syntax
419
struct JsonnetVm *vm = jsonnet_make();
420
jsonnet_fmt_debug_desugaring(vm, 1);
421
422
const char* code = "{ [x]: x for x in ['a', 'b', 'c'] }";
423
424
int error;
425
char *result = jsonnet_fmt_snippet(vm, "debug.jsonnet", code, &error);
426
427
if (!error) {
428
printf("Desugared output:\n%s\n", result);
429
// Shows the expanded form of comprehensions and other sugar
430
}
431
```
432
433
### Integration with Build Systems
434
435
**Makefile example:**
436
```makefile
437
format:
438
@for file in $$(find . -name "*.jsonnet"); do \
439
echo "Formatting $$file"; \
440
jsonnetfmt -i $$file; \
441
done
442
443
check-format:
444
@for file in $$(find . -name "*.jsonnet"); do \
445
if ! jsonnetfmt --test $$file; then \
446
echo "$$file needs formatting"; \
447
exit 1; \
448
fi; \
449
done
450
```
451
452
**Pre-commit hook:**
453
```bash
454
#!/bin/bash
455
# .git/hooks/pre-commit
456
457
echo "Checking Jsonnet formatting..."
458
459
files=$(git diff --cached --name-only --diff-filter=ACM | grep '\.jsonnet$')
460
461
if [ -n "$files" ]; then
462
for file in $files; do
463
if ! jsonnetfmt --test "$file"; then
464
echo "Error: $file is not properly formatted"
465
echo "Run: jsonnetfmt -i $file"
466
exit 1
467
fi
468
done
469
fi
470
471
echo "Jsonnet formatting check passed"
472
```