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:
gSto split a single-line construct into multiple linesgJto 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..endvs{}), 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
gSandgJkeys 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