splitjoin.vim turns a one-liner into a block and back again
Switch between single-line and multiline forms of code
At a glance
- What is it?
- A Vim plugin with two key bindings, gS and gJ, that transform between the single-line and multiline forms of a statement across many languages. The language coverage is the interesting part, not the bindings themselves.
- Who is it for?
- Adopt it if you write Ruby, Go, JavaScript or CSS inside Vim and keep rewriting the same block by hand, since gS and gJ support many languages from a single pair of mappings. Leave it out if your work is in a language absent from that list.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 22 days ago.
- What is it written in?
- Mainly Vim Script, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Two mappings and one transformation
The plugin reduces to two commands. gS splits a one-liner into multiple lines, and gJ joins a block back into a single-line statement when the cursor sits on the first line of the block. The README states both defaults can be customized, so nothing here is baked into a mapping you cannot move.
The motivating case is Ruby, where puts "foo" if bar? is idiomatic and short. Adding a second statement to the body means rewriting the whole construct by hand into the three-line if block. The HTML case generalizes it: `<div id="foo">bar</div>` becomes a three-line element with the content indented on its own line, and gJ reverses it. The author's own framing is that this is a task that came up too often in the workflow, not a general-purpose formatter.
Filetype rules are the bulk of the code
The repository layout explains where the work is. A top-level ftplugin/ directory holds the per-filetype behaviour, autoload/ holds the shared implementation, plugin/ holds the entry points that define the mappings, and doc/ holds splitjoin.txt. Everything else is developer tooling: a Gemfile, a Rakefile, a Guardfile, and an .rspec file. That split means adding a language means writing an ftplugin file, not modifying the core.
The language list is the real feature and it is long: C, CSS, Clojure, Coffeescript, Elixir, Elm, Eruby, Go, HAML, Hare, HTML and HTML-like markup, Handlebars, JSON, Java, Javascript, Lua, PHP, Perl, Python, R, Ruby, Rust, SCSS and Less, Shell, Tex, Vimscript and YAML. Several entries are grouped in ways that matter. SCSS and Less sit together, suggesting a shared rule. HAML and Handlebars are both indentation-sensitive templating languages. Javascript is called out as working within JSX, TSX and Vue.js templates, which is a broader claim than plain .js support.
Installing without a plugin manager
The README calls a plugin manager the easiest route and names vim-plug and Vundle, but it does not reproduce their configuration, so there is nothing to copy here for either. It does spell out the manual path, which is the useful part for anyone not running a manager. Cloning into a pack directory of type start/ makes Vim load the plugin at startup.
git clone https://github.com/AndrewRadev/splitjoin.vim ~/.vim/pack/_/start/splitjoinIf you would rather control loading yourself, the same directory under opt/ works, and one line in your .vimrc pulls it in on demand.
packadd splitjoinThere is a third route for people who keep no git on the machine: the README points at the releases tab and says to unzip the files into the relevant directory. Note that the clone command above points at the repository while the README's help link points at a master branch path in doc/splitjoin.txt, even though the repository's default branch is main. That mismatch is a small inconsistency in the documentation, harmless for installation but worth knowing if you write raw GitHub URLs.
The cursor position decides whether gJ does anything
gJ is not a general join command, and the README is precise about the precondition: with the cursor on the first line of a block. Anywhere else in the block the binding has no defined target. That is a deliberate narrowing of what a join operator could mean in a language where you might want to collapse three unrelated lines.
It also means the two mappings are not symmetric in their triggers. gS operates on whatever one-liner the cursor sits in, which is a well-defined neighbourhood. gJ needs the block to have an identifiable beginning, and the plugin has to find it from the cursor. In an indentation-sensitive language such as Python or YAML, where the first line of a block is determined by column rather than by a keyword, the ftplugin rules have to carry that logic, and those rules are where the differences between languages live.
What the plugin does not claim
The README is short and does not make several claims that a reader might reasonably expect. It does not document how gS interacts with your indentation settings, so what happens under an autoindent or smartindent configuration is unstated. It does not say whether trailing comments move with the code during a split, which is the classic failure case for this kind of transformation. It does not describe a way to undo other than Vim's own undo.
It also does not mention Vim's built-in J command anywhere, and gives no guidance on remapping around it. If you have customized J yourself, the README does not tell you whether that collides with gJ's semantics. These are absences rather than flaws, and the full help file at :help splitjoin is where the README sends you for anything beyond the summary, including examples for every supported language.
Where this is the wrong tool
The clearest mismatch is a language outside that list. If your file type is not in the supported list, the README describes no rules for it or any fallback behaviour. There is no generic form described, so the plugin is not a way to add arbitrary formatting to an arbitrary buffer.
The second case is a codebase with an enforced formatter. A plugin that rewrites the shape of a statement is fighting for authority with whatever runs on save. The README does not discuss cooperating with a formatter, and does not mention any format-on-save hook. If your language has an opinionated formatter, decide which one owns the block layout before installing both. The third case is bulk structural change. gS and gJ are cursor-local, single-block operations; nothing in the README describes a command-line or buffer-wide mode.
An alternative approach: doing the edit inside the language's own tooling
One alternative is to stay in the multiline form and stop writing the single-line form at all.
The difference in approach is where the authority sits. splitjoin.vim keeps both forms available and makes the switch a two-key action, which suits editing where you flip between compact and expanded constantly. A formatter or linter decides the form once and enforces it on every save, which suits teams. If you are the only one touching the file, the plugin's manual control is the cheaper option; if four people touch it, the enforcement argument usually wins.
Maintenance and licence
The repository is not archived and the last push was on 2026-10-01. That is recent activity, but the releases are old: v1.2.0 is dated 2023-06-25 and v1.1.0 dates from 2022-04-03, so the two most recent tags sit well behind the commit history. That is the usual shape for a Vim plugin, where fixes land on main and tagging happens rarely, but it does mean an upgrade path depends on the plugin manager you use rather than on a sequence of releases.
The licence is MIT. For a plugin loaded into your editor configuration, that removes the licensing question almost entirely, and there is no copyleft obligation that would reach your own .vimrc.
One contribution condition is unusual enough to note. CONTRIBUTING.md is the reference, and the README states that pull requests are welcome as long as they did not involve LLM usage. That is an unusual restriction for an open source project, and anyone planning to send a patch generated with an assistant needs to read CONTRIBUTING.md before writing it.
Editorial conclusion
Adopt it if you write Ruby, Go, JavaScript or CSS inside Vim and keep rewriting the same block by hand, since gS and gJ support many languages from a single pair of mappings. Leave it out if your work is in a language absent from that list. Before installing, open doc/splitjoin.txt and confirm that your filetype appears there, since the per-language examples live in the help file rather than the README.
Frequently asked questions
What is the default keybinding to split a line in splitjoin.vim?
gS splits a one-liner into multiple lines, and gJ with the cursor on the first line of a block joins it back into a single-line statement. The README states both defaults can be customized.
How do I install splitjoin.vim without a plugin manager?
Clone it under a pack directory of type start/, for example ~/.vim/pack/_/start/splitjoin, and Vim loads it at startup. Under opt/ instead, you load it yourself with packadd splitjoin. The releases tab also offers a zip download.
Which languages does splitjoin.vim support?
The README lists many languages, including C, CSS, Clojure, Coffeescript, Elixir, Elm, Eruby, Go, HAML, Hare, HTML, Handlebars, JSON, Java, Javascript, Lua, PHP, Perl, Python, R, Ruby, Rust, SCSS and Less, Shell, Tex, Vimscript and YAML. Javascript support is stated to extend into JSX, TSX and Vue.js templates.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/andrewradev-splitjoin-vim)Was this useful?