microsoft/vscode

Missing Sublime Text command - wrap HTML tag

waderyan opened this issue · 16 comments

While building this extension to map Sublime Text default keyboard shortcuts to VS Code, I found that this feature is missing.

The feature is wrap HTML tag.

Default Sublime Text keybindings
Windows / Linux: alt+shift+w
Mac: ctrl+shift+w

wrap_html_tag

An extension exists to provide functionality that is close to but not quite on par. I think we should bring this into the core product.

Yes, this is a Sublime feature that I really miss. I've tried out some tag-wrapping and tag-closing extensions but they do not work well with multi-line selection. (For instance, if I have a bunch of words that I want to wrap with <li></li>)

The fun part of the implementation of this feature is you always need to switch to multi cursor mode.

Just for clarity. This is one extension that tried to implement this feature:
https://marketplace.visualstudio.com/items?itemName=bradgashler.htmltagwrap

  1. It uses multicursor mode, and you have to manually exit it. I always forget to do it, and don’t see my second cursor until I corrupt too much code with it.

  2. Automatically exiting multicursor on pressing space will improve things but still be far from perfect. When I press ↑ or ↓, it should also exit this tag-wrapping mode (i.e. a mode when I type simultaneously the opening and closing tags).

  3. Even if does exit the tag-wrapping mode on pressing space, it should remember to re-enter it on pressing backspace. So it should somehow maintain the understanding that I’m still between the less-than and greater-than signs and enable/disable multicursor as necessary.

  4. Even if all of the above is somehow implemented correctly with multicusor, we still sacrifice multicusor for this feature. And I want to be able multiple cursors to wrap many things into one type of tag.

Sublime Text works like magic here.

VS Code has Emmet's "Wrap with Abbreviation" command. It wokrs great for one tag. You can assign the preffered keyboard shortcut to it.

Unfortunately, if I want to wrap for example text with link in each list-item, it only wraps the first one. That feature works great in Atom and Sublime and I really miss it in VS Code.
wrap

There is also question on stackoverflow - https://stackoverflow.com/questions/43326394/vs-code-wrap-with-html-tag-for-multiple-selection-regions

Darn, I use this all. the. time. Maybe I will have to stick with Sublime a while longer.

@pageworthy they fixed that in recent version. You can do it now.

@Linxflasher I don't see anything in the docs that allows me to wrap each line. Is it a part of Emmet or something?

@pageworthy yeah, part of Emmet. Ctrl + Shift + P. Then Wrap with abbreviation.

I assume you're talking about New Emmet. I'm not seeing the correct behavior, though. I'm on VSCode 1.14.2

If I have the following lines:

test1
test2
test3
test4

If I do a multi-line cursor select on these 4 lines and then select "Emmet: Wrap with Abbreviation", I actually get this:

<tag>
<tag>
<tag>
<tag>
    test4
</tag>est3
</tag>est2
</tag>est1
</tag>
test2
test3
test4

If I use the old Emmet, then it only wraps test1 with <tag>.

On VSCode 1.16.1 (and maybe some previous versions), it's "Emmet: Wrap Individual Lines with Abbreviation." I think it was added recently.

jaegz commented

+1, Sublime with Emmet nailed Wrap with Abbreviation.

A simple Ctrl+Shift+G (on windows) in sublime. Rather in VS Code I find myself getting jumbled up in Ctrl+Shift+P+WRAP or Ctrl+Shift+P+WRAPI depending on which type of expansion I need and that also depends on how my selection was made (if I used multiple cursors or not).

The live preview aspect also helped a ton by eliminating guess&check redundancy. These features would be super beneficial to roll into VS Code!

I use the ctrl+shift+w shortcut a lot in Sublime and am really missing it in VS Code.

This feature, when implemented, should not require any text to be selected so that an empty tag is created and then the tab key can advance the cursor into the tag. It should work for html tags as well as tags from other syntax' like JSX, XML, etc

  1. ctrl+shift+w produces a default tag (maybe <p>?):

    <p></p>
    
  2. Then typing View produces:

    <View></View>
    
  3. Then typing attributes or props, such as name="Beau", produces:

    <View name="Beau"></View>
    
  4. Then hitting tab places cursor inside the tag:

    <View name="Beau">|</View>
    

See further clarification in my comment below

@beausmith what you described can be done easily with Emmet, which is built in to VSC. Just type div.foo and press tab, and emmet will convert that to <div class="foo"></div> and put your cursor within the tags. Saves a few keystrokes even! :-)

You can also create a customer custom keybinding to add the Emmet Wrap With Abbreviation or Wrap Individual Lines With Abbreviation. Adding custom keybindings is documented here:

https://code.visualstudio.com/docs/getstarted/keybindings

Add the following to your keybindings.json file (the one below is for Mac).

[
  {
    "key": "shift+cmd+w",
    "command": "editor.emmet.action.wrapIndividualLinesWithAbbreviation"
  }
]

With that in place you get some superhuman powers, all documented on the Emmet website:

https://docs.emmet.io/actions/wrap-with-abbreviation/

For example, start with this text in the editor:

this is line 1
this is line 2
this is line 3

Then select those three lines and hit Shift+Cmd+W, type p.text*, and hit Enter. You'll get this:

<p class="text">this is line 1</p>
<p class="text">this is line 2</p>
<p class="text">this is line 3</p>

And it shows a preview of the results as you type out the abbreviation.

Thanks @tythewebguy.

What you suggested works great for html tags, and I have tried it.

My request was for a different feature:

  • I do not want to have to select any content before using the keyboard shortcut.
  • I also want to use this for jsx tags such as <View> and ` which don't work with Emmet tab completion.

Though I still want the ability to use a keyboard shortcut to create blank tags, I did find a simi-solution using code snippets for tab completion of <View> and ` tags:

{
	"View": {
		"scope": "javascript,typescript",
		"prefix": "View",
		"body": [
			"<${1:View}$3>$2</${1:View}>$0"
		],
		"description": "JSX <View> tag"
	},
	"Text": {
		"scope": "javascript,typescript",
		"prefix": "Text",
		"body": [
			"<${1:Text}$3>$2</${1:Text}>$0"
		],
		"description": "JSX <Text> tag"
	}
}

The described behavior is how it is expected to work. If you disagree, please explain what is expected and what is not in more detail. See also our issue reporting guidelines.

Happy Coding!

This feature is available as "Emmet: Wrap with Abbreviation".