Surround tags in vim - vim

I often want to surround a div tag with another div tag.
https://github.com/tpope/vim-surround is a real help there.
|<div>
...
</div>
if the cursor is at | and I typeysat<div> I get
<div><div>
...
</div><div>
instead I want
<div>
<div>
...
</div>
</div>
how can I force the div to be on a new line?

:help at says:
When used in Visual mode it is made characterwise.
The low-level mechanism used by Surround for its ys custom operator consumes the given motion as a visual selection, the type of which is then used by the plugin to decide what to do. In this case, Surround gets a characterwise motion which makes it operate in a characterwise fashion.
In order to achieve your goal, you will need to force a linewise motion by adding a V between the operator (ys) and the motion (at):
ysVat<div><CR>
^
See :help forced-motion:
*o_V*
V When used after an operator, before the motion command: Force
the operator to work linewise, also when the motion is
characterwise.

Related

Change HTML attribute in neovim

I found myself struggling with quickly changing attributes inside HTML tags.
For example, I have the following code
<div className="expense-date">
<div className="expense-date__###year">{year}</div>
<div>{month}</div>
<div>{day}</div>
</div>
My cursor is where the ### is, and I want to delete the whole attribute: className="expense-date__###year".
Is there any text object I can use to quickly delete it? Currently I use T ct> (or T ct if there's another attribute), but that's obviously not good enough and won't work if there's a space inside the attribute's value.
There is no built-in "attribute" text object but you can approximate one with something generic like this:
va"oB
where:
va" selects the value,
o moves the cursor to the other side of the selection,
B extends the selection to the beginning of the attribute.
This can be turned into quick and dirty pseudo-text objects:
xnoremap ix a"oB
onoremap ix :<C-u>normal vix<CR>
xnoremap ax a"oBh
onoremap ax :<C-u>normal vax<CR>
a visual mode mapping that covers the desired text,
an operator-pending mode mapping that uses the visual mode one,
to use like this:
yix
dax
vix
cax
…
See this plugin for a much smarter implementation.
Note that nothing in this answer is guaranteed to work in Neovim.
To my knowledge, there is no simple way to do this; unless you perform a deep syntax analysis, there will always be some caveats.
You can however improve your technique, for example with F"F=bF d2f".
F" goes to the beginning of the string;
F= goes to the previous = sign, skipping eventual spaces between;
b goes to attribute name (eventualy in the middle of it e.g. for data-my-attr), skipping eventual spaces;
F goes to the 1st space before the attribute name;
d2f" (or c2f") performs the job.
Of course, you can use it as a macro with q and # in order to simplify its use.
Here's another option:
vi> ........ visual select inner <>
o ............ jump to the other side
w ............ jump to the next word

Vim can multi-paste like vscode?

I'm a really big fan of VSCode, But I wanna migrate to vim...
vim has a alternative way, like vscode?
I know multi cursor plugin, But I don't know multi copy and multi paste with orderly.
There's plug-in mg979/vim-visual-multi, that implements something akin to multiple cursors in Vim.
Without plug-ins, Vim has a feature of Visual Block selection, but that is column based, so when you use it to perform this operation (in the same sequence you used), you end up with this instead:
<div>Multi-copy</div>
<div>Paste </div>
<div>Orderly </div>
(You can later use something else, like a :s, to remove the spaces before the </div>.)
Another option would be to use a Vim macro, to yank the contents of a single line, position the cursor inside one of the <div> blocks and put it there, then position the cursor at the next line, so that the next macro execution will act on the second line, then keep repeating the macro until done.
In Vim, it's actually more natural to do the opposite of what you've done, instead of putting the contents inside the <div>s, putting the <div>s around the contents is much easier. You can use Visual Block insert and append, even Visual Block put will work for the left tag (they have all the same length), there are also common plug-ins (such as vim-surround) to surround a selection in a specific HTML tag, and plug-ins (such as emmet.vim) to quickly generate a structure with a set of HTML tags.
Actually you have at least two options on neovim for doing that:
1 - Using (nvim) inccommand like:
:%s/<div>\zs/whetever you want/g
the \zs ensures your changes will start after this position
2 - Using visual block selection
Start visual block selection -> Ctrl-v
use j or k to expand your selection
now press I and type what you want, after that
just press Esc.

VIM Yanking Outter/Inner Tag without moving cursor

I have the following HTML:
1 <div>
2 <p>This is a paragraph</p>
3 <p>This is the second paragraph</p>
4 </div>
If I do not have my cursor anywhere near the above item and try to yank
The entire div by: :1yat
The inner content of that div :1yit
The inner content of the first paragraph :2yit
None of the above commands work. Any idea how I can yank inner/outter div elements without moving the cursor (#extremelaziness)?
Thank you
Vim is commonly called "modal" editor, because it has modes. What it truly means is that all the commands and keyhits are different between different modes. That's the main point which must be learnt by anyone who uses Vim.
In your case yat and such belong to the Normal mode, while : switches into Command-line mode. While in the Command-line mode you can only execute its commands.
Of course, there is :normal which serves as a sort of "bridge" between Normal and Command-line, however it's primarily used in scripting as typing :1norm yat looks like anything but #extremelaziness.
So you have either to write some custom command yourself or to keep typing 2ggyat<C-O> and such.

Vim Surround: Create new tag but don't indent/new line

I would like to mimic Textmates CTRL+ALT+w, which creates a new pair of opening and closing HTML tags on the same line.
In VIM Surround I'm using CTRL+st in Edit mode for this, but it always indents and creates a new line after setting the tag, so that it looks like this (* = cursor position):
<p>
*
</p>
Is there a way to achieve this? :
<p>*</p>
I guess your problem is that the selected area is "line wise". For example, if you select a few lives with V and surround it with tags, the tags will be placed one line above and one bellow the selected lines.
You probably want to create a "character wise" selection, with v before surrounding it.
Anyway, please post the map you created, so we can help debugging this.
Update
After some clarification in the comments, I would tell you that the surround plugin is not the best option. As its name describes, it was created to deal with surrounded content. So you may need content to surround.
In your case, I recommend taking a look in HTML AutoCloseTag. This plugin closes the html tag once you type the >. It is certainly more appropriated, and uses less keystrokes than surround.
<p <--- Now when you type ">", if becomes:
<p>|</p> <--- Where "|" is the cursor.
Obviously, you will get this behavior to every tag. But that may be handy if you like it.
From normal mode, type vstp> to enter visual mode and output an opening and closing <p> tag on the same line at the current cursor position. Use a capital S to maintain the current indent level.
This doesn't place the cursor in between the tags as you describe, but neither does Textmate's CtrlW shortcut (I think you meant CTRL+Shift+w, not CTRL+ALT+w, as the latter just outputs a diamond sign.)
My answer is probably coming to late, but I'll try to help.
I had similar problem with Vimsurround plugin. Every time I select sentence (one line) using ctrl+V and try to surround it with something I get this:
{
var myVar
}
instead of this:
{ var myVar } // what I wanted
I found easy solution: From a normal mode I choose a line with vis command and then I type capital C (my vim surround mapping ) and choose brackets to surround.Then I get one line nicely surrounded.
The question title is technically mislabeled based on what the author was actually looking for, but since I was actually looking for the answer to the question asked in the title, I figure I should provide an answer to it as well.
To create a new tag surrounding an element without the automatic indentation Vim Surround uses when using a block wise selection (ie: VysS), you can instead do something like:
^ys$
This command will move your cursor to the first non-blank character of the line, issue the command that you want to utilize You Surround, and move to the end of the line. Then, simply start entering your tag.
The result is this:
<input type="email" name="email">
Could become something like this:
<li><input type="email" name="email"></li>
The command is repeatable as well with . and all the normal other Vim goodness.
Stumbled upon this question because I was wondering this as well - I believe the simplest way to do this is just:
yss<p>
(yss surrounds a line with something without indenting - see here: http://www.catonmat.net/blog/vim-plugins-surround-vim/)
You can accomplish this by selecting the relevant text object: :h text-objects
...and surrounding that instead of surrounding a Visual Line selection.
The most common example I found myself running into was when trying to surround one tag with another. In that situation, the it and at text objects are quite useful:
*v_at* *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.
*v_it* *it*
it "inner tag block", select [count] tag blocks, from the
[count]'th unmatched "<aaa>" backwards to the matching
"</aaa>", excluding the "<aaa>" and "</aaa>".
See |tag-blocks| about the details.
When used in Visual mode it is made characterwise.
For example, if you had your cursor in a paragraph and you wanted to surround it with a div on the same line, ysat<div> would accomplish that.

Vim: quickly returning to a part of the text

I have been trying to learn Vim and have been using it for 2 weeks now.
My question is how do I return the cursor immediately to the middle of the text I just typed:
I have a tendency to type:
<div>
</div>
and returning back to the content of the tag and writing its contents:
<div>
text
</div>
This also goes for functions:
function eat() {
}
before getting back to the middle of the and typing it's contents:
function eat(){
blah
}
An uppercase O, so Shift+o, inserts an empty line above the one you're currently on and puts you into insert mode where you can begin typing. It was kind of an epiphany for me when I first figured that out.
If you work a lot with html / xml tags, have a look at surround.vim
I agree with michaelmichael, O works in both of your examples above.
In general, in vi or vim, you can use "macro" to achieve this. This feature acts like a bookmark, despite its name.
ma will define a macro called 'a'.
`a will take you back to where the bookmark was defined. If you want the beginning of the line, use 'a
So, if you typed 'ma' at the appropriate spot, continued typing, then typed '`a', it would achieve the effect you're looking for.
Snipmate plugin - Completion codes
dynamics
see an example of plugin in action at the vimeo site

Resources