vimtricks.wiki Concise Vim tricks, one at a time.

How do I split a single-line code statement into multiple lines or join them back in Vim?

Answer

gS / gJ

Explanation

The splitjoin.vim plugin by Andrew Radev provides two commands — gS to split and gJ to join — that intelligently convert code constructs between their single-line and multi-line forms. Unlike Vim's built-in J which blindly joins lines by removing newlines, splitjoin understands the syntax of your programming language and restructures the code accordingly.

How it works

Place your cursor on a code construct and press:

  • gS to split a single-line construct into multiple lines
  • gJ to join a multi-line construct into a single line

Example: Ruby hash

With the cursor on this single-line hash, pressing gS:

opts = { name: "Alice", age: 30, role: "admin" }

Transforms it to:

opts = {
  name: "Alice",
  age: 30,
  role: "admin"
}

Pressing gJ on the multi-line version joins it back to a single line.

Supported language constructs

Splitjoin supports dozens of constructs across many languages:

  • Ruby: hashes, arrays, if/unless one-liners, blocks (do..end vs {}), ternaries
  • JavaScript/TypeScript: object literals, arrow functions, import statements, ternaries
  • Python: dictionaries, lists, function arguments, comprehensions
  • HTML/JSX: tag attributes, self-closing tags
  • CSS: property declarations
  • Go: struct literals, if-err blocks
  • Lua, Rust, Elixir, PHP, Java, and many more

Example: JavaScript ternary

Pressing gS on a ternary expression:

const msg = isAdmin ? "Welcome back" : "Access denied";

Converts it to an if/else:

let msg;
if (isAdmin) {
  msg = "Welcome back";
} else {
  msg = "Access denied";
}

Example: HTML tag attributes

Pressing gS on a tag with multiple attributes:

<input type="text" name="email" class="form-control" required>

Splits the attributes onto separate lines:

<input
  type="text"
  name="email"
  class="form-control"
  required>

Tips

  • Splitjoin is filetype-aware — the same gS and gJ keys do the right thing in every language
  • Pair with vim-repeat so you can undo a split and redo it with .
  • The plugin handles trailing commas, semicolons, and bracket placement according to each language's conventions
  • Configure custom split/join rules for unsupported constructs using the plugin's callback system
  • Works especially well for reformatting function arguments, import lists, and data structure literals during code review cleanup

Next

How do I edit multiple lines at once using multiple cursors in Vim?