73

The standard J command for joining lines replaces the newline character(s) with a space. It's useful when editing 'literature' but can be troublesome if I, say, edit a hex dump by hand if I forget to remove the superfluous space.

Is there a quick & easy method to join two lines without producing a space between them?

88

The gJ combination does this; from :help gJ:

Join [count] lines, with a minimum of two lines. Don't insert or remove any spaces.

You could rebind it to J, if you wanted to save a keystroke:

:nnoremap J gJ

Note that this doesn't remove any spaces, so if either the current line ends with a space or next line starts with one or more spaces, they will be left as is.

So:

Hello
    world

Becomes:

Hello    world

We could use Jx in this case, then it will be Helloworld, but that won't work in all cases; from the help:

Join the highlighted lines, with a minimum of two lines. Remove the indent and insert up to two spaces

[...]

These commands, except "gJ", insert one space in place of the unless there is trailing white space or the next line starts with a ')'.

So in some cases more than one space or no space is inserted. As far as I can see, there is no easy way to change this behaviour; I created a function to modify gJ to always join without spaces:

" Like gJ, but always remove spaces
fun! JoinSpaceless()
    execute 'normal gJ'

    " Character under cursor is whitespace?
    if matchstr(getline('.'), '\%' . col('.') . 'c.') =~ '\s'
        " When remove it!
        execute 'normal dw'
    endif
endfun

" Map it to a key
nnoremap <Leader>J :call JoinSpaceless()<CR>

See also: :help J, :help 'joinspaces'

  • Is it possible to use some "Preserve" function to keep the cursor position when using this function or how do I get this result? – SergioAraujo Dec 15 '17 at 12:19
8

Another trick you may try is to use replace. Sometimes this might be useful.

%s/$\n//g

Scenario: Delete the last character and join with the next line:

%s/=$\n\(.\)/\1/g

For example,

xxxx=
123

becomes:

xxxx123
3

Create a macro and reuse it:

qaJxq

Now replay the macro, a by using @a wherever you want to join two lines with no space.

@@ will repeat the previous macro. So you can just hold @ to join multiple lines.

  • 1
    Why type @a when you can type Jx? Same number of key presses and SHIFT presses! – Shahbaz Jan 19 '17 at 1:37
  • 2
    @Shahbaz Maybe because of the last line: "you can just hold @" – muru Jan 19 '17 at 3:13
  • 1
    @muru, that's true! – Shahbaz Jan 19 '17 at 15:23
  • 4
    It also makes it a repeatable command, so you can use 3@a to join 3 lines, whereas doing 3Jx would join 3 lines with spaces and then delete the space between the second and third lines, leaving spaces between the other lines. – Haegin Feb 27 '17 at 18:05
1

To always join with a single space :

nmap J gJi <ESC>ciW <ESC>

To join with no space at all (removes trailing+leading space) :

nmap <C-J> gJi <ESC>diW
  • 1
    Welcome to this site! Your mappings look a bit over-engineered to me, it would be helpful if you could add a bit more explanations about how they work. – statox Apr 9 at 15:31
1

Select the lines you'd like to merge, enter an Ex command by typing a colon : in normal mode. Then type this command:

s/$\n\s*//gc

The entire command should look likewise:

:'<,'>s/$\n\s*//gc

This is actually a tweaked version of the @insidepower's command that replaces space-indentations as well as newline characters.

Explanation:

  • '<,'> means that we modify only the lines selected in visual mode.

  • /$\n\s* is a regex pattern. We're looking for a match that ends $ with a new line character \n and has non-determined number of whitespaces * thereafter.

  • s/pattern//gc is a substitute command to find each pattern and replace it with an empty character on confirmation.

To figure out more about flags and metacharacters for regular expressions in Vim take a look at this chapter of Vim Reference.

  • 2
    Hi ubique, welcome to Vi and Vim! You've got a pretty well-written answer there; kudos for that. My one nitpick is that vim regular expressions =/= python regular expressions, and sometimes that is confusing for users. Maybe link to the help document for Vim regex instead? – D. Ben Knoble Oct 8 at 2:07
  • 2
    Second nit: the answer you reference was written by @insidepower and edited by Peter. – D. Ben Knoble Oct 8 at 2:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.