Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vim delete/yank/copy a key/entry block from JSON or javascript object

Tags:

vim

I work with a lot of JSON. It's super common that I'll want to operate on an entire block of JSON--Selecting an entire block, deleting the block, moving it, etc. Is there any way to operate on the key and its value combined?

Mockup:

vim delete json key mockup

A motion like viB won't work in this case because it will select all the children in the same nest level (not what I want). I want the complete block and only that block for whatever the cursor is over.

like image 560
Jonathan Dumaine Avatar asked Oct 04 '22 12:10

Jonathan Dumaine


1 Answers

Using vim-textobj-user you can define a textobject to select whatever you want. Here is one to select a block matching your criteria that I just wrote:

call textobj#user#plugin('textobj-syntax-is-garbage', {
\   'regex_j': {
\     'select': 'aj',
\     '*pattern*': '^\s*"\?\w\+"\?\s*:\s*{\_[^}]*}.*\n\?',
\   })

This will not work for nested json blocks :( but it will work for your use case

The aj means you can execute vaj or daj or whatever your little heart desires.

Explanation:

^\s*"\?\w\+"\?\s*:\s*{

Match from the start of the line to a key (word characters) with optional double quotes

\_[^}]*

Match anything that's not a closing nipple bracket. \_ means match across multiple lines.

}.*\n\?

Match a closing nipple bracket, and an optional newline so that it will not leave a line break around after you delete the block.

This regex could definietly be improved. It's probably impossible to do correct nested block selection with a regex, but I think textobj-entire lets you specify a function to run as well.

like image 65
Andy Ray Avatar answered Oct 30 '22 02:10

Andy Ray