(For non-visual user-agents, ‘|’ is the point and ‘*’ is the mark in the following examples.)
If the point is not in a string, each key is interpreted as a command like the vi editor. If the point is in a string, keys are inserted as is:
If the region is active, each key is interpreted as a command.
Moving to the next/previous member (key-value pair), parents, and more:
Key | Command | Description |
---|---|---|
j | json-par-backward-member |
To the next member (key-value pair). |
k | json-par-forward-member |
To the previous member. |
h | json-par-up-backward |
To the beginning of the containing object/array. |
l, }, or ] | json-par-up-forward |
To the end of the containing object/array. |
a | json-par-beginning-of-member |
To the beginning of the member. |
e | json-par-end-of-member |
To the end of the member. |
v | json-par-beginning-of-object-value |
To the beginning of the value. |
J | json-par-backward-record |
To the same key in the previous object. |
K | json-par-forward-record |
To the same key in the next object. |
A | json-par-beginning-of-list |
To the beginning of the first member. |
E | json-par-end-of-list |
To the end of the last member. |
Other commands:
|[ 1, 2, 3 ]
↓ i (‘json-par-down’)
[ |1, 2, 3 ]
[ 1, 2, 3 ]|
↓ i (‘json-par-down’)
[ 1, 2, 3| ]
{
"key|": 123
}
↓ TAB (‘json-par-tab’)
{
"key": |123
}
↓ S-TAB (‘json-par-mark-head-of-member’)
{
"*key|": 123
}
[
"The quick brown |fox jumps over the lazy dog."
]
↓ TAB (‘json-par-tab’)
[
"The quick brown fox jumps over the lazy dog."|
]
{
|"name": "Emacs",
"website": "https://www.gnu.org/software/emacs/",
"written_in": [ "C", "Emacs Lisp" ]
}
↓ g (‘json-par-goto-key’) website RET
{
"name": "Emacs",
|"website": "https://www.gnu.org/software/emacs/",
"written_in": [ "C", "Emacs Lisp" ]
}
[
"a",
|"b",
"c"
]
↓ M-x json-par-goto-index 0 RET
[
|"a",
"b",
"c"
]
Pro tip: those commands except j, k, J, or K push a mark in the mark ring before moving, and b is bound to pop-to-mark-command
. So pressing b goes back to the previous position.
Press q to disable JSON Par mode only for next command. Press Q to disable JSON Par mode until explicitly enabled again.
Just one key to insert values:
Key | Description |
---|---|
t | Insert true |
f | Insert false |
n | Insert null |
[ | Insert [] |
{ | Insert {} |
" | Insert "" |
, | Insert , |
: | Insert : |
+, -, 0-9 | Insert number |
Commas and line breaks are inserted appropriately:
[
[
1, 2, 3
]|
]
↓ [
[
[
1, 2, 3
],
[
|
]
]
[
[ 1, 2, 3 ]|
]
↓ [
[
[ 1, 2, 3 ],
[|]
]
↓ 1
[
[ 1, 2, 3 ],
[ 1| ]
]
When the region is active, [, {, and " wrap the region. With C-u prefix, " unwrap the string.
When the region is active, d or <backspace> deletes the region.
When the region is not active, d + movement key marks members or values:
[
1|,
2,
3,
4
]
↓ d2j (“mark the following two members”)
[
1|,
2,
3*,
4
]
↓ d
[
1|,
4
]
Key | Description |
---|---|
dd | Mark the current member (key-value pair). |
d. | Mark the current value or key. |
dj | Mark the member following the point. |
dk | Mark the member preceding the point. |
dh | Mark the containing object/array (the point move before the parent). |
dl | Mark the containing object/array (the point move after the parent). |
da | Mark the key of the current key-value pair. |
de or dv | Mark the value of the current key-value pair. |
dA | Mark all members of the containing object/array (the point move before the first member). |
dE | Mark all members of the containing object/array (the point move after the last member). |
di | Mark all contents of the object/array/string before/after the point. |
Pro tip: you can delete without marking by setting json-par-action-when-deleting-value-or-member to delete
.
<backspace> and C-d delete or mark things while keeping structures:
[ 1, 2, 3 ]|
↓ <backspace>
[ *1, 2, 3| ]
[]|
↓ <backspace>
*[]|
[| 1, 2, 3 ]
↓ <backspace>
[ |1, 2, 3* ]
[|]
↓ <backspace>
|[]*
"Emacs"|
↓ <backspace>
"*Emacs|"
"|Emacs"
↓ <backspace>
"|Emacs*"
[ 1,| 2 ]
↓ <backspace>
[ *1,| 2 ]
{
"name":| "Emacs",
"website": "https://www.gnu.org/sotware/emacs/"
}
↓ <backspace>
{
*"name": "Emacs",
|"website": "https://www.gnu.org/sotware/emacs/"
}
delete-outer
: delete whole object/array.delete-inner
: delete contents of the object/array if not empty. Delete whole object/array otherwise.mark-outer
: mark whole object/array.mark-or-delete-outer
: mark whole object/array. If it is already marked, delete it.mark-inner
: mark contents of the object/array if not empty. Mark whole object/array otherwise.enter
: move the point into the object/array.delete-outer
: delete whole object/array.delete-inner
: delete contents of the object/array if not empty. Delete whole object/array otherwise.mark-outer
: mark whole object/array.mark-inner
: mark contents of the object/array if not empty. Mark whole object/array otherwise.mark-or-delete-inner
: mark contents of the object/array if empty. Mark whole object/array otherwise. If already marked, delete it.exit
: move the point out of the object/array.none
: do nothing.delete
: delete whole member (key-value pair) beyond the comma unconditionally.mark-or-delete
: delete only if the whole member beyond the comma is marked.mark
: mark whole member beyond the comma unconditionally.skip
: move the point to the opposite site.delete
: delete whole member (key-value pair) unconditionally.mark-or-delete
: delete only if the whole member is marked. Otherwise, mark the whole member.mark
: mark whole member unconditionally.skip
: move the point to the opposite site.v (json-par-delete-object-values
) deletes all values in the current object/array.
{
"group": "group1",
"key": "foo",
"value": |[ 1, 2, 3 ]
}
↓ V
{
"group": ,
"key": ,
"value": |
}
Examples:
|[
[
1,
2
],
[
3,
4
]
]
↓ O (‘json-par-oneline’) ↑ M (‘json-par-multiline’)
|[ [ 1, 2 ], [ 3, 4 ] ]
↓ O
|[[1,2],[3,4]]
{
"lyrics": |"Twinkle, twinkle, little star,
How I wonder what you are!
Up above the world so high,
Like a diamond in the sky."
}
↓ O (‘json-par-oneline’) ↑ M (‘json-par-multiline’)
{
"lyrics": |"Twinkle, twinkle, little star,\nHow I wonder what you are!\nUp above the world so high,\nLike a diamond in the sky."
}
With prefix arguments, you can limit depth of affected members:
|[
[
1,
2
],
[
3,
4
]
]
↓ C-1 O (convert members with levels more than one to oneline)
|[
[ 1, 2 ],
[ 3, 4 ]
]
↑ C-1 M (insert line breaks after commas with levels less than or equal to one)
|[ [ 1, 2 ], [ 3, 4 ] ]
When a line break is inserted just inside brackets, line breaks are also inserted after every members. When a line break just inside brackets is deleted, convert the object/array to the oneline:
[| [ 1, 2 ], [ 3, 4 ] ]
↓ RET ↑ <backspace>
[
|[ 1, 2 ],
[ 3, 4 ]
]
Action when breaking a line at just inside brackets.
break-inside-brackets
: break the lines at just inside brackets.
Example (‘|’ is the point):
[ |1, 2, 3 ] ↓ RET [ |1, 2, 3 ]
break-each-member
: break lines after each members.
Example (‘|’ is the point):
[ |1, 2, 3 ] ↓ RET [ |1, 2, 3 ]
The default value is break-each-member
.
Action when breaking a line after the first member.
just-break
: just break the line.
Example (‘|’ is the point):
[ 1, |2, 3 ] ↓ RET [ 1, |2, 3 ]
break-each-member
: break lines after each members.
Example (‘|’ is the point):
[ 1, |2, 3 ] ↓ RET [ 1, |2, 3 ]
The default value is just-break
.
Action when joining non-empty lines.
just-delete
: just delete the line break.
Example (‘|’ is the point):
[ 1, | 2, 3 ] ↓ <backspace> [ 1,| 2, 3 ]
delete-line-breaks-between-members
: delete all line breaks between members (but not before/after members) only if the each members is on its own line.
Example (‘|’ is the point):
[ 1, | 2, 3 ] ↓ <backspace> [ 1,| 2, 3 ]
[ 1, | 2, 3, 4 ] ↓ <backspace> [ 1,| 2, 3, 4 ]
delete-line-breaks-inside-brackets
: delete all line breaks inside the current array/object, only if the each members is on its own line.
Example (‘|’ is the point):
[ 1, | 2, 3 ] ↓ <backspace> [ 1,| 2, 3 ]
[ 1, | 2, 3, 4 ] ↓ <backspace> [ 1,| 2, 3, 4 ]
The default value is just-delete
.
Examples:
{
"properties": {
"tags": |{
"type": "array",
"items": {
"type": "string"
}
}
}
}
↓ cj (‘json-par-clone-member-forward’: clone the current member after it)
{
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"|tags*": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
[
{
"group": |"group1",
"key": "foo",
"value": [ 1, 2, 3 ]
}
]
↓ CJ (‘json-par-clone-parent-forward-without-value’: clone the parent member after it without values)
[
{
"group": "group1",
"key": "foo",
"value": [ 1, 2, 3 ]
},
{
"group": |,
"key": ,
"value":
}
]
Key | Description |
---|---|
cj, cc | Clone the current member after it. |
ck | Clone the current member before it. |
cJ | Clone the parent member after it. |
cK | Clone the parent member before it. |
Cj, CC, cvj, cvc | Clone the current member after it without value. |
Ck, cvk | Clone the current member before it without value. |
CJ, cvJ | Clone the parent member after it without value. |
CK, cvK | Clone the parent member before it without value. |
Advanced: pressing h or i after c selects an ancestor to clone.
? (json-par-insert-guessed
) is a dabbrev-expand
for JSON values or keys; insert a guessed value or key based on the context:
{
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string"
},
"email": |
}
}
↓ ?
{
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string"
},
"email": {
"type": "string"
}|
}
}
↓ ?
{
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string"
},
"email": {
"type": "string",
"minLength": 1
}|
}
}
In the previous example, the command searches for the key "email"
first in the current buffer and other JSON buffers. Then, it searches for the key "properties"
and picks its grandchildren. json-par-guess-max-ancestors controls how many ancestors to search.
If the point is inside an object but not after a key, it completes a key:
{
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string"
},
"email": {
"type": "string"|
}
}
}
↓ ?
{
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string"
},
"email": {
"type": "string",
"minLength": |
}
}
}
When guessing a key, it uses the ancestor keys ("email"
then "properties"
) and the sibling keys ("type"
).
{
"key": |"key1",
"value": "value1"
}
↓ s (‘json-par-transpose-member-forward’) ↑ w (‘json-par-transpose-member-backward’)
{
"value": "value1",
"key": |"key1"
}
{
"items" {
"oneOf": [
|{ "$ref": "#/definitions/Foo" },
{ "$ref": "#/definitions/Bar" }
]
}
}
↓ r (‘json-par-raise-member’)
{
"items" {
|{ "$ref": "#/definitions/Foo" }
}
}
Pressing m (json-par-mark-more
) or C-M-SPC repeatedly expands the region. With C-u prefix, undo an expansion.
Similarly, N (json-par-narrow
) narrows to the current value or key, and expand the region if repeated.
S (json-par-split
) splits a string, object, or array at the point. F (json-par-join
) join two strings or arrays/objects.
Setting custom variables shows ancestors out of the window:
Ancestors are displayed with the following faces:
You can also prepend a char before ancestors or current member: