• Skip to primary navigation
  • Skip to main content
Sal Ferrarello
  • About Sal Ferrarello
  • Speaking
  • Connect
    Mastodon GitHub Twitter (inactive)
You are here: Home / Dev Tips / Vim JSON Format

Vim JSON Format

Last updated on October 30, 2022 by Sal Ferrarello

Vim allows you to run all (or some) of your content through an external program. In this case, we want to use Python to format (i.e. pretty print) our JSON with python -m json.tool.

The Goal

Before

{"data":{"attributes":{"name":"sal"}}}

After

{
    "data": {
        "attributes": {
            "name": "sal"
        }
    }
}

Using Vim Filters

A Vim filter allows us to run a selection a text through an external filter (see :help filter).

JSON Format the Entire File

Running the following command will try to JSON pretty print format the entire file.

:%!python -m json.tool

Explanation

The command starts with : because it is entered in command-line mode (see :help Cmdline-mode).

The % indicates the range to operate on is the entire file (see :help :%).

The ! indicates this is a filter to apply to the selected text (see :help filter).

The python -m json.tool is the command line tool. We pass the selected text to the command line tool and replace the selected text with the output we receive.

Other Ranges

We can replace the range % (the entire file) with any other range (see :help range). e.g.

  • . the current line
  • 3,5 lines 3 to 5
  • '<,'> the current visual selection

JSON Format the Current Line

:.!python -m json.tool

JSON Format Lines 3 to 5

:3,5!python -m json.tool

JSON Format the Current Visual Selection

Highlight the desired lines using Visual Mode (v, see :help visual-mode) or Linewise Visual Mode (V, see :help linewise-visual).

:'<,'>!python -m json.tool

Neovim (lua) Custom Command

My problem with all of these solutions is that I don’t remember the commands and I have to look these up each time.

My ideal solution would be a custom Vim command (e.g. :JSONFormat), which would allow me to type :JSO<tab> and get the command autocompleted. Additionally, the command should operate on a given range (e.g. :%JSONFormat or :'<,'>JSONFormat) or the current line if no range is given.

vim.api.nvim_create_user_command(
  'JSONFormat',
  '<line1>,<line2>!python -m json.tool',
  {
    range = true,
  }
)

Vimscript Custom Command

command! -range JSONFormat <line1>,<line2>!python -m json.tool

This is the solution I came up with and added to my .vimrc (see PR 182 Add :JSONFormat to pretty print format JSON).

How it Works

The line in our .vimrc begins with command because it is a user defined command (see :help user-commands).

The exclamation mark ! allows this command to be redefined. If the ! is omitted and you try to reload your .vimrc, you’ll get an error because the command is already defined. By including the ! we prevent this error (see :help E182).

The -range attribute allows our user defined command to accept a range (by default user defined commands do not accept ranges). See :help command-range.

We are naming our command JSONFormat

When our command is executed it does the following <line1>,<line2>!python -m json.tool, where

  • <line1> is the starting line of the command range (see ‘:help <line1>`)
  • <line2> is the final line of the command range (see ‘:help <line2>`)
  • ! here indicates this is a filter to apply to the selected text (see :help filter)
  • The python -m json.tool is the command line tool. We pass the selected text to the command line tool and replace the selected text with the output we receive.
Sal Ferrarello
Sal Ferrarello (@salcode)
Sal is a PHP developer with a focus on the WordPress platform. He is a conference speaker with a background including Piano Player, Radio DJ, Magician/Juggler, Beach Photographer, and High School Math Teacher. Sal can be found professionally at WebDevStudios, where he works as a senior backend engineer.

Share this post:

Share on TwitterShare on FacebookShare on LinkedInShare on EmailShare on Reddit

Filed Under: Dev Tips, Solution Tagged With: lua, neovim, vim, vimscript

Reader Interactions

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Copyright © 2023 · Bootstrap4 Genesis on Genesis Framework · WordPress · Log in