vim how to paste multiple lines insert into another multiple lines? - vim

For example, copy multiple lines A:
'fjalkfjljfllfs'
'dasldkjlasdjla'
'jlfajldjaflajl'
they are random string with same length.
I have multiple lines text B and want to insert A into B's same position (not begin or end):
'xxxx fjalkfjljfllfs xxxxx'
'xxxx dasldkjlasdjla xxxxx'
'xxxx jlfajldjaflajl xxxxx'
in vim, is there a way to do this?

If you mark you lines A via blockwise visual mode (ctrl + V) and copy them with y you can just put them back with p.

Related

Autohotkey : Clipboard Convert Tabs to Spaces

I have a snippet of code I copied into my clipboard. Pasting it out looks like this. Where[tab] is an actual tab indent
[tab]<header id="masthead" class="site-header">
[tab][tab]<h1>
[tab][tab][tab]<h2>
[tab][tab][tab][tab]<h3>
[tab][tab][tab][tab][tab]<h4>;
I want to press an autohotkey to automatically normalize the code snippet. So if there's a [tab] on every line, remove it.
Then convert each [tab] into 2 spaces [**]
<header id="masthead" class="site-header">
**<h1>
****<h2>
******<h3>
********<h4>;
So the general workflow is:
Copy code to clipboard
Press an autohotkey
Paste the newly formatted contents
Pseudocode for autohotkey would look like this
Dig through every clipboard content line by line
If every item shares an equal number of [tab] spaces, remove them entirely
Line by line, convert [tab] to [**] 2 spaces
; convert each tab into 2 spaces:
clipboard =
(
<header id="masthead" class="site-header">
<h1>
<h2>
<h3>
<h4>;
)
clipboard := StrReplace(clipboard, A_Tab, A_Space A_Space)
https://autohotkey.com/docs/commands/StringReplace.htm
okay problem solved I have everything I want now. I took the other source code snippet here on autohotkey forum
F9::
clipboard := StrReplace(clipboard, A_Tab, A_Space A_Space)
position := RegExMatch(clipboard, "\S")
test := RegExReplace(clipboard, "m)^[ ]{" . position - 1 . "}")
clipboard := test
As a reference, need to highlight the full line on code snippet like so
So all I have to do now is:
Copy the full code
Press F9
Paste into my notetaking app (dynalist.io with codesnippet support)

How can I delete/yank paste in vim and have it indent correctly? (not talking about :paste)

Please note this is NOT related to :paste / :nopaste and the clipboard. I'm talking about copying and pasting entirely within vim (d, y, p).
It is common to copy and paste a block of code from an outer block into an inner block. Unfortunately, the indentation still is at the level of the outer block and I have to indent it afterwards.
What I want to do is to go from:
function foo() {
}
var bar;
var bazz;
to
function foo() {
var bar;
var bazz;
}
In vim what I normally do is:
1) go to the line
2) switch to visual mode
3) highlight the rows
4) dd to delete the lines
5) move the cursor up
6) P to paste
7) enter visual mode
8) highlight the rows
9) >> to indent the lines
I want it to automatically indent to the correct location. It would be a much smoother workflow if I didn't need to re-highlight the rows and then indent them manually. In other words, eliminate steps 7-9.
Anybody know of a way to do this?
You can easily make this a keymap that does auto indenting as part of pasting.
For example,
nnoremap gp p`[v`]=
Breakdown:
p to paste text
`[v`] to selecte Pasted text
= to autoindent selected text
I came across this plugin.
https://github.com/sickill/vim-pasta
Looks like it does the same thing as ronakg mentioned above with some additional functionality.

Remove new lines inside a div using vim

I have some data like this
<div>
This
is
some text
</div>
and i want to end up with this
<div>
This is some text
</div>
I know I can search and replace for \n, but I want to limit that search for only the lines inside the <div> tag.
I have a very long HTML file with thousands of Divs, no class or ID.
How can I do this with Vim?
Move your cursor into the <div> block, try this:
vitojJ
To join all non-overlapped <div> blocks, try this:
:g/<div>/+1,/<\/div>/-1 join
Start recording a macro (in register d) with qd
Search for an opening DIV tag with /<div (then press return)
Use visual mode to select everything inside the DIV with vit
Change the visual selection so that it doesn't include the line with the opening tag with oj
Join the lines with J
Stop recording with q
Now you can play back the macro as many times as you need to with #d (or, for a fixed number of repetitions you can prefix it with a number, e.g. 20#d)
(This solution assumes that, as in your example, the open and close tags are always on their own lines. Also, if there is only one line of content in the DIV then the closing tag will end up on the same line as the content.)
You can do one of these:
Select the tree lines with V, and use J to put them in the same line.
Put the cursor on the second line and use 3J.
Put your cursor on the second line, and do J two times.
If you are on "This", VjjJ (select whole lines, down twice, join rows with ' ' as separator.)
--
If you want the end result to be <div>This is some text</div>: place cursor anywhere in tag and do vatJ (visual mode, select inclusive, select tag, join rows.)
:g/<div>/norm! jVjjJ
:................... command
g................... global
/<div> ............. search for <div>
norm! .............. in normal mode
j................... down one line 'j',
V .................. visual by line 'V'
jj ................. down more two lines
J .................. upper 'J' join lines
For variable number of lines try
:g/<div>/norm! jV/\/div^MkJ
:............. command
g ............ global
/<div> ....... search div
norm! ....... execute in normal mode
j ............ down one line
V ............ start visual mode
/\/div ....... search div close
^M ........... type <ctrl-v> in linux or <ctrl-k> on windows, after that <enter>
k ............ up one line
J ............ joine all selected lines
On linux to insert <Enter> press <ctrl-v><enter>
On windows try <ctrl-k><enter>

Align to the right in visual block

I would like to know how to align to the right in a visual block without changing the text before and the block.
I used this code till before:
:<C-U>'<,'>s/\%V\(.\{-}\)\(\s\{-}\)\%(\%V\#!\|$\)/\2\1/
However I noted that it doesn't work when after the visual block is only spaces.
(There has to be text after the visual block in order to make above code work)
Is there no way to align text to the right in a visual block whatever is written after the block?
Example:
text before +align text text after
text before align text text after
text before align text text after
text before align text+ text after
What I want to do is select a block of text from + to + (see example above)
and align it to the right. Output must be:
text before align text text after
text before align text text after
text before align text text after
text before align text text after
Above code does the job but it does not work when there is not something written after align text in every line.
In order to solve the issue correctly handling all corner cases, I would use
the following function.
function! RightAlignVisual() range
let lim = [virtcol("'<"), virtcol("'>")]
let [l, r] = [min(lim), max(lim)]
exe "'<,'>" 's/\%'.l.'v.*\%<'.(r+1).'v./\=StrPadLeft(submatch(0),r-l+1)'
endfunction
function! StrPadLeft(s, w)
let s = substitute(a:s, '^\s\+\|\s\+$', '', 'g')
return repeat(' ', a:w - strwidth(s)) . s
endfunction
I use this. Put the cursor before the text which should be aligned to right. Run :Right
How does it work:
v0 Visualy select the text from current position to the beginning of the line
d Delete selected text and put into the buffer
:right Align the text on the right side of the cursor
0 Put cursor to the first column
gv Visualy select same area which we deleted before
p Replace selection with deleted text
command! Right execute "normal v0d\<CR>:right\<CR>0gvp"
:'<,'>s/\%V.*\%V/\=printf("%*s", col("'>")-col("'<"), substitute(submatch(0), '^\s*\|\s*$', '', 'g'))

vim: delete all blank space until next non-blank character

Say I have the following code:
<p>
Hello
</p>
And I want to make it
<p>Hello</p>
I would like to put the cursor in normal mode at the end of line 1, so on the ' > ' and have a command to delete all spaces until the next character. The closest I can think of is the motion
d/Hello
which deletes everything until Hello but the issue is that it deletes also the character under the cursor (the ' > ') so I end up with
<pHello
</p>
How would you do that?
One way when you won't need to repeat this action many times.
JxJx
Explanation:
J # Join current line with next one but substitute end of line with a space.
x # Remove the space.
Jx # Repeat same process for last line.
There's a tag text-object in vim:
put cursor within tag, press vat to select entire tag
press :, it becomes :'<,'>
type j, it becomes :'<,'>j
press Enter to join lines
:help v_at
at "a tag block", select [count] tag blocks, from the
[count]'th unmatched "<aaa>" backwards to the matching
"</aaa>", including the "<aaa>" and "</aaa>".
See |tag-blocks| about the details.
When used in Visual mode it is made characterwise.
When standing anywhere in the second line (the one that says Hello), press the following keys: ^d0vatgJ. Simply explained:
^ will go to the first non-whitespace character, H
d0 will delete to the beginning of the line
vat will select the entire tag
gJ will join all the lines without inserting spaces
If you start on the H, you can skip the ^ part.

Resources