Remove new lines inside a div using vim - 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>

Related

How can I paste to next line and enter insert mode on current line?

I'm brand new to vim. A common pattern I am dealing with looks like this
myFunction :: some code
myFunction = some more code
how could I create a command where after executing I look like this
myFunction
myFunction
and am in insert mode with my cursor on the end of the first 'myFunction' ?
If you are copying the first line to the down then maybe try yy for yanking the whole (first) line, P for pasting the line before the cursor and A to go in insert mode at the end of first line.
And you can use :map to do whole thing at one. Like :map 'l yyPA
I have found an almost perfect solution "using ultisnips plugin", the only thing missing is the cursor position. I am considering an already typed text:
You must select the target lines (use vip in normal mode) and use your defined trigger on ultisnips
snippet trigger "Description" w
`!p
import re
snip.rv = re.sub("(^\w+).*", r"\1", snip.v.text, flags=re.MULTILINE)
`
endsnippet

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)

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

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.

Append to top and bottom of selected text in vim

So I have the following text (==== delimiters denotes selected text):
This is some text
I'm not interested in.
This is indented text
not important.
=====================
This text portion is
selected.
=====================
Also not important
indented text
Other text i'm not
interested in.
Now I want to create a vim function so that when called, it appends at the top and at the bottom some default text. For example I would like to end with:
This is some text
I'm not interested in.
This is indented text
not important.
THIS TEXT WAS APPENDED
AFTER FUNCTION CALL
This text portion is
selected.
THIS OTHER TEXT WAS
APPENDED AFTER THE SAME
FUNCTION CALL
Also not important
indented text
Other text i'm not
interested in.
Please note that indentation should be preserved (thanks benjifisher)
How can I do this?
This is a little sloppy, but it works:
function! Frame() range
'<put!=\"THIS OTHER TEXT WAS\nAPPENDED AFTER\nFUNCTION CALL\"
'>put=\"THIS OTHER TEXT WAS\nAPPENDED AFTER THE SAME\nFUNCTION CALL\"
endfun
Select your lines in Visual mode, and type
:'<,'>call Frame()
(The range '<,'> is inserted automatically.) There are some advantages to using :execute with a:firstline and a:lastlineas in :help function-range-example, instead of the Visual marks '< and '>, but that gets a little complicated. You could also prefix each command with :silent if you do not care to be told that 3 lines have been added (twice).
Here is a version that copies the indentation from the first and last selected lines, as requested in the updated question. This version uses :call append() instead of :put, which makes it more convenient to use a:firstline and a:lastline; possibly, this will be useful if you ever want to call the function with a range other than the Visual one.
" Add lines at the bottom before adding at the top, since the line numbers
" will change when you add lines.
function! Frame() range
" Define a list of lines and prepend the desired indentation.
let botlines = ['THIS OTHER TEXT WAS', 'APPENDED AFTER THE SAME', 'FUNCTION CALL']
let botspaces = matchstr(getline(a:lastline), '\s*')
let lines = []
for line in botlines
call add(lines, botspaces . line)
endfor
" Now add those lines at the bottom.
call append(a:lastline, lines)
" Now do the same thing at the top.
let toplines = ['THIS OTHER TEXT WAS', 'APPENDED AFTER', 'FUNCTION CALL']
let topspaces = matchstr(getline(a:firstline), '\s*')
let lines = []
for line in toplines
call add(lines, topspaces . line)
endfor
call append(a:firstline - 1, lines)
endfun

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