What's the best shortcut or plugin to comment out HTML/XML elements?
And also need to uncomment.
You can use a combination of matching XML tags, as can be seen in this question and Perl's search and replace.
For instance, given this snippet:
<TypeDef name="a">
<ArrayType high="14" low="0">
<UndefType type="node">
</UndefType>
</ArrayType>
</TypeDef>
Put the cursor on either the opening or closing TypeDef and type the following sequence:
vat:s/^\(.*\)$/<!-- \1 -->/
v - puts you into visual mode
at - selects the whole XML tag
:s/^\(.*\)$/<!-- \1 -->/ - surrounds each line with '<!-- ... -->', the comment delimiters for XML
Alternatively, you can just delete it like this:
dat
d - delete according to the following movements
at - as before
To delete id use then use vat:s/-->// to delete comments
I use the tComment plugin. You can find a detailed video tutorial here on how to install and use it.
The plugin is very useful as it allows you to toggle comments from both the command and input interface, and you can do so using both visual mode and motions (like gcw, or gc3w)
If you use emmet-vim, you can select the whole contents of the tag you would like to comment out by pressing v a t and then press Ctrl y /
To comment: vato<ESC>i<!-- <ESC>vatA --><ESC>
Position the cursor anywhere inside the HTML block. Not inside a nested one unless you want to comment that one.
Go to the opening tag: vato
Exit visual mode: Esc
Insert: i<!--
Exit insert mode: Esc
Go to closing tag: vat
Append: A -->
Exit insert mode: Esc
Note: You may use I to insert directly from visual mode, and it'll work with multi-line blocks, but for single line elements it'll mess up the indentation.
To uncomment: vat<ESC>4xvato<Esc>5X
Position the cursor anywhere inside the HTML block, ending comment delimiter excluded.
Go to the closing tag: vat
Exit visual mode: Esc
Delete 4 chars: 4x
Go to the opening tag vato
Delete preceding 5 chars: 5X
Using .vimrc or init.vim to create shorcuts
You may add these lines to your .vimrc (or init.vim in neovim) to remap shortcuts:
" Comment HTML element
nnoremap <silent> <leader>h :set lazyredraw<cr>mhvato<ESC>i<!-- <ESC>vatA --><ESC>`h:set nolazyredraw<cr>
" Uncomment HTML element
nnoremap <silent> <leader>H :set lazyredraw<cr>mhvat<ESC>4xvato<ESC>5X`h:set nolazyredraw<cr>
Warning:
You will need to undo if you try to uncomment a non-commented area for it will delete some characters. You could avoid this by replacing 4x with d2f- and 5X with dF!, but then you'd have issues with this kind of workaround and anything else in the same line that contains -...- or !.
If there are already comments in between the tags of the element to comment out, you will need to uncomment those first.
Notes:
Change <leader>h and <leader>H to what you'd like to use.
:set lazyredraw is to hide intermediate steps by not redrawing the screen and :set nolazyredraw to avoid possible visual glitches afterwards.
mh is to save current cursor position and `h is to jump back to that line and column. You may replace h with any other lower case letter.
Tip: Use :source $MYVIMRC to apply changes done to .vimrc (or init.vim) without having to restart vim.
Related
How can I find and delete all occurrences of an html tag using Visual Studio Code.
As an example, I am trying to parse a page that is riddled with SVG tags. I don't want the tags, nor the contents of those tags in the file.
If you are opening the "Find and Replace" popup in VS-Code (Windows: CTRL + H, Mac ⌥ + ⌘ + F), then inside the "Search" input field there are three icons on the right side.
Press the right one .* in order to activate regular expressions.
After it's activated you can search for SVG tags like so:
<\s*svg[^>]*>(.*?)<\s*\/\s*svg>
Leave the replace input empty and press enter in order to replace it with "nothing" and therefore removing the HTML-Tag and it's inner text.
But be careful, this will really delete everything between those matched tags.
So for example if you are looking for <a> tags, even this String will be completely removed: Some <span>special</span> formatted link
You can find an example with it here: https://regex101.com/r/ewEttF/1
You can use Regex Search and Emmet.
Use regex search to find the start tags: <svg[^>]*>
While the focus is still in the find dialog: Alt+Enter
this will select all matching cases and put focus on the editor
Move cursors after the opening tag: RightArrow
Use Emmet: Balance outward to select content of tag
Use Emmet: Balance outward to select content and tag start and tag end
Delete selected stuff with: Delete
End Multi Cursor with: Esc
Every time I type an opening html tag (like <div>) then press the Enter key, the cursor automatically inserts an indention on the next line. However I don't want it to be indented since I still have to write the closing tag (actually I press the enter twice and write the closing tag in the third line so I can have an empty line in between). Now I have to press the back button to align the cursor with the opening tag.
I am aware of Sublime Text 2's autocomplete like when you type '<' and Ctrl + Space, a list
of available elements would appear. And when you select one item from the list, the editor would
provide you of both the opening and the closing tag. However, I'm not used to that kind of typing.
So is there a way to turn off this annoying feature of Sublime Text 2
You can disable auto-indentation by setting auto_indent to false.
In order to do this for the HTML syntax only, go to Preferences/Settings – More/Syntax Specific – User and insert the following contents:
{
"auto_indent": false
}
This will make the cursor to jump back at column 0 after hitting return.
To make it stay at the column of the opening tag, re-enable auto_indent and tweak the indentation settings in Packages/HTML/Miscellaneous.tmPreferences. If you aren’t into regular expressions, try to get rid of this file completely.
You can also just type the closing </div> tag and sublime text will automatically un-indent it for you.
Is there some plugin to fold HTML tags in Vim?
Or there is another way to setup a shortcut to fold or unfold html tags?
I would like to fold/unfold html tags just like I do with indentation folding.
I have found zfat (or, equally, zfit) works well for folding with HTML documents. za will toggle (open or close) an existing fold. zR opens all the folds in the current document, zM effectively re-enables all existing folds marked in the document.
If you find yourself using folds extensively, you could make some handy keybindings for yourself in your .vimrc.
If you indent your HTML the following should work:
set foldmethod=indent
The problem with this, I find, is there are too many folds. To get around this I use zO and zc to open and close nested folds, respectively.
See help fold-indent for more information:
The folds are automatically defined by the indent of the lines.
The foldlevel is computed from the indent of the line, divided by the
'shiftwidth' (rounded down). A sequence of lines with the same or higher fold
level form a fold, with the lines with a higher level forming a nested fold.
The nesting of folds is limited with 'foldnestmax'.
Some lines are ignored and get the fold level of the line above or below it,
whichever is lower. These are empty or white lines and lines starting
with a character in 'foldignore'. White space is skipped before checking for
characters in 'foldignore'. For C use "#" to ignore preprocessor lines.
When you want to ignore lines in another way, use the 'expr' method. The
indent() function can be used in 'foldexpr' to get the indent of a line.
Folding html with foldmethod syntax, which is simpler.
This answer is based on HTML syntax folding in vim. author is #Ingo Karcat.
set your fold method to be syntax with the following:
vim command line :set foldmethod=syntax
or put the setting in ~/.vim/after/ftplugin/html.vim
setlocal foldmethod=syntax
Also note so far, the default syntax script only folds a multi-line
tag itself, not the text between the opening and closing tag.
So, this gets folded:
<div
class="foo"
id="bar"
>
And this doesn't
<div>
<b>text between here</b>
</div>
To get folded between tags, you need extend the syntax script, via
the following, best place into ~/.vim/after/syntax/html.vim
The syntax folding is performed between all but void html elements
(those which don't have a closing sibling, like <br>)
syntax region htmlFold start="<\z(\<\(area\|base\|br\|col\|command\|embed\|hr\|img\|input\|keygen\|link\|meta\|para\|source\|track\|wbr\>\)\#![a-z-]\+\>\)\%(\_s*\_[^/]\?>\|\_s\_[^>]*\_[^>/]>\)" end="</\z1\_s*>" fold transparent keepend extend containedin=htmlHead,htmlH\d
Install js-beautify command(JavaScript version)
npm -g install js-beautify
wget --no-check-certificate https://www.google.com.hk/ -O google.index.html
js-beautify -f google.index.html -o google.index.bt.html
http://www.google.com.hk orignal html:
js-beautify and vim fold:
Add on to answer by James Lai.
Initially my foldmethod=syntax so zfat won't work.
Solution is to set the foldemethod to manual
:setlocal foldmethod=manual
to check which foldmethod in use,
:setlocal foldmethod?
Firstly set foldmethod=syntax and try zfit to fold start tag and zo to unfold tags, It works well on my vim.
I know
di<
will delete in an HTML tag itself.
Is there an easy way to delete text in between two tags?
<span>How can I delete this text?</span>
Thanks!
dit will delete the text between matching XML tags. (it is for "inner tag block".)
See :h it and :h tag-blocks.
cit
ci"
Two of the best productivity enabler commands of vim.
I save a lot of time and effort with just those two.
try dt< while the cursor is on the first character to delete. In your example the 'H'.
dit - delete inner tag, remains in command mode
cit - change inner tag, changes to edit mode
di" - delete inside ""
di' - delete inside ''
di( - delete inside ()
di) - delete inside ()
di[ - delete inside []
di] - delete inside []
di{ -delete inside {}
di} - delete inside {}
di< - delete inside <>
di> - etc
swap first letter d for c, if you want to be in edit mode after typing the command
(cursor on first character to delete)
v/<[enter]d
This solution starts on the first character, then enters visual mode ("v"). It then searches for the next start bracket ("/<"), and then press enter to exit the search.
At this point, your visual selection will cover the text to delete. press d ("d") to delete it.
If I had to do this for a bunch of tags, I'd record the command and combine it with some other searches to make it repeatable. The key sequence might look like this:
[cursor on start of file]
qa/>[enter]lv/<[enter]dnq
then press:
20#a
to do this for 20 tags
This applies to wherever your cursor is:
HTML
dit - for deleting tag content while still in command mode
cit - for deleting tag content, insert mode (Preferred Way)
STRING
dit - for deleting string content which still in command mode
ci"/ci' - for deleting string content, insert mode (Preferred Way)
If you're aiming to do the inverse of deleting text between flags, I suggest installing Vim-Surround and running dst which deletes the surround tag
It's been a while since I've had to do any HTML-like code in Vim, but recently I came across this again. Say I'm writing some simple HTML:
<html><head><title>This is a title</title></head></html>
How do I write those closing tags for title, head and html down quickly? I feel like I'm missing some really simple way here that does not involve me going through writing them all down one by one.
Of course I can use CtrlP to autocomplete the individual tag names but what gets me on my laptop keyboard is actually getting the brackets and slash right.
I find using the xmledit plugin pretty useful. it adds two pieces of functionality:
When you open a tag (e.g. type <p>), it expands the tag as soon as you type the closing > into <p></p> and places the cursor inside the tag in insert mode.
If you then immediately type another > (e.g. you type <p>>), it expands that into
<p>
</p>
and places the cursor inside the tag, indented once, in insert mode.
The xml vim plugin adds code folding and nested tag matching to these features.
Of course, you don't have to worry about closing tags at all if you write your HTML content in Markdown and use %! to filter your Vim buffer through the Markdown processor of your choice :)
I like minimal things,
imap ,/ </<C-X><C-O>
I find it more convinient to make vim write both opening and closing tag for me, instead of just the closing one. You can use excellent ragtag plugin by Tim Pope. Usage looks like this (let | mark cursor position)
you type:
span|
press CTRL+x SPACE
and you get
<span>|</span>
You can also use CTRL+x ENTER instead of CTRL+x SPACE, and you get
<span>
|
</span>
Ragtag can do more than just it (eg. insert <%= stuff around this %> or DOCTYPE). You probably want to check out other plugins by author of ragtag, especially surround.
Check this out..
closetag.vim
Functions and mappings to close open HTML/XML tags
https://www.vim.org/scripts/script.php?script_id=13
I use something similar.
If you're doing anything elaborate, sparkup is very good.
An example from their site:
ul > li.item-$*3 expands to:
<ul>
<li class="item-1"></li>
<li class="item-2"></li>
<li class="item-3"></li>
</ul>
with a <C-e>.
To do the example given in the question,
html > head > title{This is a title}
yields
<html>
<head>
<title>This is a title</title>
</head>
</html>
There is also a zencoding vim plugin: https://github.com/mattn/zencoding-vim
tutorial: https://github.com/mattn/zencoding-vim/blob/master/TUTORIAL
Update: this now called Emmet: http://emmet.io/
An excerpt from the tutorial:
1. Expand Abbreviation
Type abbreviation as 'div>p#foo$*3>a' and type '<c-y>,'.
---------------------
<div>
<p id="foo1">
</p>
<p id="foo2">
</p>
<p id="foo3">
</p>
</div>
---------------------
2. Wrap with Abbreviation
Write as below.
---------------------
test1
test2
test3
---------------------
Then do visual select(line wize) and type '<c-y>,'.
If you request 'Tag:', then type 'ul>li*'.
---------------------
<ul>
<li>test1</li>
<li>test2</li>
<li>test3</li>
</ul>
---------------------
...
12. Make anchor from URL
Move cursor to URL
---------------------
http://www.google.com/
---------------------
Type '<c-y>a'
---------------------
Google
---------------------
Mapping
I like to have my block tags (as opposed to inline) closed immediately and with as simple a shortcut as possible (I like to avoid special keys like CTRL where possible, though I do use closetag.vim to close my inline tags.) I like to use this shortcut when starting blocks of tags (thanks to #kimilhee; this is a take-off of his answer):
inoremap ><Tab> ><Esc>F<lyt>o</<C-r>"><Esc>O<Space>
Sample usage
Type—
<p>[Tab]
Result—
<p>
|
</p>
where | indicates cursor position.
Explanation
inoremap means create the mapping in insert mode
><Tab> means a closing angle brackets and a tab character; this is what is matched
><Esc> means end the first tag and escape from insert into normal mode
F< means find the last opening angle bracket
l means move the cursor right one (don't copy the opening angle bracket)
yt> means yank from cursor position to up until before the next closing angle bracket (i.e. copy tags contents)
o</ means start new line in insert mode and add an opening angle bracket and slash
<C-r>" means paste in insert mode from the default register (")
><Esc> means close the closing tag and escape from insert mode
O<Space> means start a new line in insert mode above the cursor and insert a space
Check out vim-closetag
It's a really simple script (also available as a vundle plugin) that closes (X)HTML tags for you. From it's README:
If this is the current content:
<table|
Now you press >, the content will be:
<table>|</table>
And now if you press > again, the content will be:
<table>
|
</table>
Note: | is the cursor here
Here is yet another simple solution based on easily foundable Web writing:
Auto closing an HTML tag
:iabbrev </ </<C-X><C-O>
Turning completion on
autocmd FileType xml set omnifunc=xmlcomplete#CompleteTags
allml (now Ragtag ) and Omni-completion ( <C-X><C-O> )
doesn't work in a file like .py or .java.
if you want to close tag automatically in those file,
you can map like this.
imap <C-j> <ESC>F<lyt>$a</^R">
( ^R is Contrl+R : you can type like this Control+v and then Control+r )
(| is cursor position )
now if you type..
<p>abcde|
and type ^j
then it close the tag like this..
<p>abcde</p>|
Building off of the excellent answer by #KeithPinson (sorry, not enough reputation points to comment on your answer yet), this alternative will prevent the autocomplete from copying anything extra that might be inside the html tag (e.g. classes, ids, etc...) but should not be copied to the closing tag.
UPDATE I have updated my response to work with filename.html.erb files.
I noticed my original response didn't work in files commonly used in Rails views, like some_file.html.erb when I was using embedded ruby (e.g. <p>Year: <%= #year %><p>). The code below will work with .html.erb files.
inoremap ><Tab> ><Esc>?<[a-z]<CR>lyiwo</<C-r>"><Esc>O
Sample usage
Type:
<div class="foo">[Tab]
Result:
<div class="foo">
|
<div>
where | indicates cursor position
And as an example of adding the closing tag inline instead of block style:
inoremap ><Tab> ><Esc>?<[a-z]<CR>lyiwh/[^%]><CR>la</<C-r>"><Esc>F<i
Sample usage
Type:
<div class="foo">[Tab]
Result:
<div class="foo">|<div>
where | indicates cursor position
It's true that both of the above examples rely on >[Tab] to signal a closing tag (meaning you would have to choose either inline or block style). Personally, I use the block-style with >[Tab] and the inline-style with >>.