vim, create new line after or before selected line - vim

In vim I can jump to line number, for example, 14 like this : "14gg"; Then I can use "o" or "O" to create a new line after or before this line.
Is there a way to create a new line before or after 14th without jumping to it? Something like "14O" or "14o" (these commands don't work)

You can create a mapping in your .vimrc file for this, to map a single character to what you want to achieve. (Create a .vimrc in your home directory if you dont have one already i.e /home/user)
For example, put following lines in your .vimrc file
map e ggo
map E ggO
Now whenever you will do something like 14e, it will go to line 14 and insert a new line below and take you in insert mode. Likewise, E for inserting line above
Please note that this may override whatever functionality key e and E might have in vim.
I strongly recommend simply using 14ggo in a go to achieve what you want

Your question is a duplicate of this superuser question: https://superuser.com/questions/147715/vim-insert-empty-line-above-current-line-not-open-i-e-without-entering-inser
append() is the standard answer to your question:
:call append(14, '')
The cursor will not get moved, nor the position marks.

You can do:
14Go<Esc>
14GO<Esc>
or:
:14norm o
:14norm O
or:
:14put=
:14put!=
You'll need to jump back to where you come from anyway.

Related

Vim copy line and comment out old line

I'm trying to achieve the same thing asked here, but in Vim.
Duplicate line and comment out old one
Basically I want to yank line, comment out the old one, paste new one, and keep cursor at the beginning of new line and end in insert mode.
For example:
def func (param)
will change to:
//def func (param)
def func (param)
I recorded a macro for it, put it into .vimrc and I'm using it via #y
" copy-and-comment-line macro
" yank line, comment out original line, move cursor at the begining
" of copied line and end in insert mode
let #y='yypkui//kdklkl'
(I'm not sure it will work for you as it contains unprintable ~# characters which code block won't display)
Macro works, but is there a built-in command in vim that I can achieve same thing with?
This mapping should do it for you:
nnoremap YOURKEY YI//<esc>p
The cursor will be on the pasted line.
replace YOURKEY by a key (or keys) you like
Note that this answer works only for your example, //style comment. If you want it to be generic solution, you have to build a function, in this function check the filetype, and decide which comment style should be used. There is no good built-in solution so far, but you can check the NERDCommenter or vim-commentary plugins to see how they achieve this, or you can install one of them (or a similar plugin) and call it's function in your mapping.

VIM Select Entire Line

How do you select a single line in VIM, when your cursor as at some random point along that line?
I know you can do (v, $) to get to the end of the line, or (v, ^) to get to the start, but when you do (v,$,^) it logically doesn't select the whole line, it selects from cursor, until end, then switches it to cursor until beginning... So this approach fails of course.
Capital V selects the current line in one key stroke; two, if you include the "shift" in shift+v.
V would be direct answer. However, I rarely need to do this because "selecting the current line" is generally part of a larger task. Example of such tasks includes copying the line and deleting the line. There's generally a better way to accomplish the task as a whole. The following are some of the tasks I can think of:
copy the line: yy
delete the line: dd
indent the line: >> or <<
select the current paragraph: vap or vip
delete from the current line to the end of the file 0dG
highlight the current line to see where my cursor is: use :set cursorline in .vimrc file
One case in which I do use V is to select multiple lines that are not a paragraph or some other text object. In this case, there's a tip that might be useful for you: once in the selection mode, you can use o to jump the cursor between the start and the end of the selection.
While this might be more keystrokes.
If you are already in visual mode you can use o to go to the other end of the visual selection.
So you can type
v0o$
To select the whole line. Take a look at :h visual-change
However from the comments it seems you just want to copy the whole line.
Which would just be yy
Just change your order of operations. You almost have it.
^,v,$
Or as suggested by #Kent: because ^ goes to the first non-empty char, if the line has leading spaces:
0,v,$
I know this thread is super old, but I just had the same question. This thread came up first, but I found a different answer than any found here. Use 'V' to select whole lines. That easy. One character to select the whole current line.

How to visually select lines based on a search pattern in vim?

I've got some method calls all over the place in a large file, I'd like to match these lines, select and then yank them as one so I can put them all in a single place.
I can find all the lines I want with :g/>set but how do I visually select each line?
You can't have multiple visual selections in Vim.
But you can clear a register and append all the matching lines to it:
:let #a = ''
:g/>set/y A
then create an empty buffer (or navigate to an existing one):
:vnew
and paste from register a:
"ap
But you probably want something like TagList or TagBar.
edit
:[something]y a
means "yank into register a".
:[something]y A
means "append to register a".
What I usually do is :
Remove all the lines without the pattern :v/pattern/d
Select the whole new file with ggyG
Paste somewhere the result with p
Use undo a few times with u to get the file back to its initial state
This is a bit cumbersome, I would welcome a simpler solution.

How to replace the whole line with the text in the buffer in VIM?

Here is the text I'm working on:
line1: website = "a.com";
...
line3: website = "b.com";
...
line5: website = "c.com";
Suppose I want to change all website to "stackoverflow.com", I can do:
- change "a.com" to "stackoverflow.com"
- yank the whole line (Y)
- go to line3, hit p, k, dd to paste from buffer and delete the old "b.com" line.
Now the problem is that since dd puts the "b.com" into the buffer, to replace line5 I'll have to yank the whole line again.
Is there any simple way so that I can replace line3 and line5 with the already yanked line quickly?
UPDATE:
Thanks for the answers, now there are several ways doing it: delete to black hole, yank from named buffer, etc. I found this being my favorite method ( I use key R instead r as sometime I need to replace a single character):
In Vim is there a way to delete without putting text in the register?
I put some links to similar SO questions below:
How to Delete (desired text), delete (undesired text), and paste (desired text) in Vim
In Vim is there a way to delete without putting text in the register?
First things first
You can go one better by not needing to explicitly delete the line:
yank the whole line into register x: "xY
go to the next line to replace
visually select the whole line: V
paste over the selection from register x: "xp
Now the deleted line is in register ", as always, but the yanked line is still in register x, so you can repeat steps 2 through 4 without having to yank over and over.
Repeated things repeated
Unfortunately you cannot use . to repeat steps 3+4. So if you have to do this for a lot of lines, insert a few more steps to record a macro:
yank the whole line into a register x: "xY
go to the next line to replace
record a macro into the w register: qw
visually select the whole line: V
paste over the selection from register x: "xp
stop recording: q
go to the next line to replace
replay the macro recorded into w: #w
go to the next line to replace
and now finally, you can replay same-as-last-time: ##
Then you can simply repeat steps 9 and 10 for the next 50 lines you need to replace.
Last (repeated) things last
In fact, if you find the next line by searching, then you should use that search to go to the first line as well. Because then the n that you use to go to the next line can be included as part of the macro – basically you just swap steps 6 and 7.
Then you don’t have to manually go to the next line to replace at all, because the macro will send you there as the last thing it does. You can just keep hitting ##, along with any occasional ns whenever you happen to want to skip a particular match.
References
help "
help registers
help complex-repeat
You can use named buffers for this instead of the default unnamed buffer: "lY then "lp to yank resp. paste from register l, then let the dd use the default buffer.
This is not an answer to your question as put but it is an answer to your real question, I think.
Technique 1: Are you aware of :s? If you are just wanting to replace all matches, you could do something like this:
:%s/^website = "\zs.*\ze\.com";$/stackoverflow/
As you haven't specified precise format of it all and whether or not you are wanting to replace all or only some, I can't say whether this is what you want or not.
Technique 1b: Even if you only want to replace some, there's a useful and not terribly widely known flag for :s: c, "confirm". (See :help :s_flags and more specifically :help :s_c.) Then you can decide with each one whether you want to replace it or not.
:%s/^website = "\zs.*\ze\.com";$/stackoverflow/c
Technique 2: You could also search, replace and then repeat. /^website = "\zs.*\ze\.com";$, then cwstackoverflowEsc to replace the word with "stackoverflow". Then n to go to the next match and if you want to replace it with "stackoverflow", use ..
Rereading this question I think this is closer to what you're after:
In Vim is there a way to delete without putting text in the register?
E.g. instead of using dd use "_dd
The "0 register always contain your last yanked text. Then you can do:
change "a.com" to "stackoverflow.com"
yank the whole line (Y)
go to line3, hit "0p, k, dd to paste from buffer and delete the old "b.com" line.
go to line5, hit "0p, k, dd to paste from buffer and delete the old "c.com" line.
ci" - change inside the ""
ctrl-r 0 - put default register
jj - move down two lines
. - repeat last command
jj
.

Vim: insert text from a file at current cursor position

To insert text from a file in the current Vim buffer I use :r filename to insert the text below the cursor or :0r filename to insert in the first line.
How do you insert the contents of a file where [Cursor] is located?
Actual line with some coding [Cursor] // TODO for later version
Line below actual line ...
This inserts the contents of the file whose path is at the cursor position:
:r <cfile>
Insert a line break, read the file, and then take out the line break...
I propose Ctrl-R Ctrl-O = join(readfile('filename','b'), "\n")
Other solution:
Possibly open the other file in another window, use :%yh (h is a register name) and in your original file, in normal mode use "hp or "hP or in insert mode, Ctrl-R Ctrl-O h
To expand on the accepted answer with actual code, since I tried the suggestion and it worked nicely;
Here is an example of it working to insert a little php snippet:
`nnoremap <leader>php a<CR><ESC>:.-1read $SNIPPETS/php<CR>I<BS><ESC>j0i<BS><ESC>l`
In general the syntax is
`nnoremap [KEY SEQUENCE] a<CR><ESC>:.-1read [FILE PATH]<CR>I<BS><ESC>j0i<BS><ESC>l`
Just to break it down:
nnoremap : I'm about to define a new key mapping for normal mode
<leader>php : I would like to trigger the command sequence when this key combination is pressed. In my case <leader> is , so I type ,php to trigger the command.
Now for the command, bit by bit:
a<CR><ESC> : go into insert mode (after the cursor), insert a line break, go back into normal mode.
:.-1read <file><CR> : this enters the desired file on the line above the current line.
I<BS><ESC> : jump to the start of the line, delete line break, return to normal mode.
j0i<BS><ESC>l : Go down one line (to the remainder of the line that you were initially on), jump to the start, enter insert mode, delete the line break, return to normal mode.
l : position the cursor to the right of the pasted file (this just made the command work more like how you expect it to).
note
You have a choice of whether to paste before or after the cursor. I have chosen in this example to paste after the cursor because that is how the p command usually works to paste yanked text. Alternately, to paste before the cursor you should change the a at the start of the command to an i. You could use one of these exclusively, or you could bind them both to different but related key sequences. For example:
`nnoremap <leader>php i<CR><ESC>:.-1read $SNIPPETS/php<CR>I<BS><ESC>j0i<BS><ESC>l`
Could paste text before the cursor,
and :
`nnoremap <leader><leader>php a<CR><ESC>:.-1read $SNIPPETS/php<CR>I<BS><ESC>j0i<BS><ESC>l`
could paste text after the cursor. Or vice versa. I have made 'before the cursor' easier to trigger because I use it more often when pasting in-line.
other note
This solution is mainly useful if you're reading from a file that you expect to use often enough that it's worthwhile setting up a key mapping for it (ie reading a snippet from a file). This doesn't really help if you just want to read in a random files whenever since you won't have the key mapping ready.
Since it is very formulaic, I'm sure it would be possible to define a function that would take the file name as an argument and do the same thing though. I've never written a function in vimscript though so if someone who knows more feels like editing this answer to contain that solution - I urge them to do so!
" put this in your ~/.vimrc
" in insert mode press ,n
"
imap ,n <c-r>=expand("%:p")<cr>
Read more in wikia.

Resources