Given text like this:
This is line one.
This is line two.
I would like to change it to this:
This is line one. This is line two.
If my cursor is at the end of line one, how is this done with vim, regardless of what line two starts with? Also, are there different ways to do it with/without whitespace?
Put your cursor anywhere on line 1, then type J.
Related
I'd like to join every 3 lines of a file with a tab character as separator. How can this be done using Vim?
I'm aware of the macro mechanism, but I?m looking for something more elegant.
It turns out that this works:
:g/\n/,+1s//\t
The :global will match every line in the buffer (or in the range, if you pass it a range.)
The /\n/ is being used as a regex that will match every line, in this case, on the line break itself. We could have used something like /^/ (or perhaps /./ or /\S/ to match non-empty or non-blank lines), here we're using /\n/ since we want to use that pattern in the following :s, so we can omit it there to use the same pattern.
Then, for each line processed by :g, we use a range of that line up to line +1. That means two lines, in this case, current line and next one. Since we want to join three lines, we want to replace the line break on two lines, so from current line up to line +1. (You could generalize that to using + the number of lines in the blocks you want to join, minus two.)
Finally, we perform the substitution s//\t, which is equivalent to s/\n/\t/ (using an empty pattern will match the previously used on, in this case the one passed to :g.) This :substitute will replace the matched line breaks with a tab character, effectively joining lines where it matches. Since we're using ranges of two lines, it will only do so two lines at a time, effectively replacing two line breaks, which will join three lines.
This works because the way :global works when there are edits on the affected lines. It first "marks" the lines that should be acted on, but then if the line is no longer there, it will skip it. So while it will first mark every line, when the :s joins every second and third line to the first in a block, the marks on them will no longer be there, so the end result is that :g will not try to process this line again and will move on to the next "marked" line, which will then become the start of the next block.
I would go with two :help :normal commands…
Append a tab to every line:
:%normal A^i
with the literal ^i being obtained with <C-v><Tab>.
Join every group of three lines:
:%normal 3J
I would recommend using macro, doing the process manually once and bind it into one key, but if you want to use it regularly I would recommend you to add a mapped command in your .vimrc
I have relative line numbers turned on.
I can yank line 10 using :10y.
But how to I yank say the 5th line below the current line without jumping to said line, yanking and jumping back (i.e. 5jY5k).
If I had this file:
2 describe 'foobar' do
1 it 'should be cool' do
46 # do stuff
1 end
2 end
I am on line 46 and I want to yank relative line 1 or 2, either above or below.
You can use +n and -n for relative addresses:
:+2y " Two lines after the current line
:-2y " Two lines before the current line
And you can also combine this:
:-2,+2y " Two lines before the cursor and two lines after
Also see this answer for some more examples and :help [range] for the Vim documentation.
I like the Markdown style underlining, but I want it to line up with the above line.
So for example if I have this:
heading one
_
^ cursor here
I could (in normal mode) just type (something)i=<ESC><ESC>, and the result would be:
heading one
===========
^ cursor here
Does anyone know what I can use for (something)?
It doesn't really matter to me where my cursor is/ends up, so for example I could be on the last position of the heading one line and do some operation to achieve the same result. I'm picky, but not that picky.
If you use visual selections you can then use r to replace every character in said visual selection.
So if you start with your cursor on the "heading one" line type.
yypVr=
Would copy the line and then replace every character with an equal sign.
kyypv$r=j
go up one line
yank it
paste it below
visually select the line
replace every character with =
Turn it into a mapping if you ned it often:
nnoremap <key> kyypv$r=j
I'd suggest you do this on the line to underline itself and not on the line below, though:
nnoremap <key> yypv$r=
I find myself doing Nyy very often to yank the current line and N-1 lines below. So 3yy would yank the current line and 2 more lines (so all together 3).
I know how to yank N lines above the current line (yNk), but this does not include the current line. What I want is to yank the current line and N-1 lines above. How do I do this (ideally also with the yy command)?
Edit: Apparently yNk includes the current line as well. I must have missed it. Thx for the comments.
The following will yank the current line plus two above:
2yk
Obviously changing the 2 will alter the number of lines yanked above. No number is an implicit 1, so yk is equivalent to 1yk.
I have a substitute command that captures and displays submatch() values in the replacement string. But I have another line of information that I want to parse below this line. That line is always the first line after an empty line, though the number of lines TO that empty line varies. For example:
The first important line I want to capture is here
Stuff I don't want.
A few more lines of stuff I don't want...
Second line I want to capture.
This pattern repeats a hundred or so times in a document. I can substitute "The First Important Line" fine, but shouldn't that search pattern include a way to jump down to the first empty line and then pick up the next "Second line I want to capture." ?? I could then place the contents of that second line into submatch parenthesis and substitute them where needed (right?).
If so, I cannot discover the way to extend the first search pattern to capture the "Second line" Suggestions or correcting my approach would be greatly appreciated.
Someone has already dealt with a similar problem. Below I provide their solution and the detailed description.
/^\nF\d\_.\{-}\_^\n\zs.*/+
It means "Find a block of lines that start with F and a digit,
then scan forward to the next blank line and select the line after that."
Part of regex
Meaning
^\n
Matches the start of a line, followed by a newline - i.e a blank line
F\d
The next line starts with an F followed by a digit
\_.\{-}
\_. is like ., but also matches newline. \{-} matches the minimum number of the preceeding \_.. (If I were to use * instead of \{-}, it would match to near the end-of file.)
\_^\n
Matches a blank line. \_^ is like ^, but ^ only works at the start of a regular expression.
\zs
When the match is finished, set the start of match to this point. I use this because I don't want the preceding text to be highlighted.
.*
Matches the whole line.
The + after the regular expression tells Vim to put the cursor on the line after the selection.
I think I read about offsets, but I can't find the bit in the help that is relevant right now. As such, my other solution would be to record a macro to do what you want:
qa/[Your pattern]<CR>jddq
You could then execute this macro with #a and repeat with ##; or run it a lot of times (e.g., 999#a).