@@ -10,6 +10,12 @@ import { getEmmetHelper, getNode, getInnerRange, getMappingForIncludedLanguages,
1010const trimRegex = / [ \u00a0 ] * [ \d | # | \- | \* | \u2022 ] + \. ? / ;
1111const hexColorRegex = / ^ # \d + $ / ;
1212
13+ const inlineElements = [ 'a' , 'abbr' , 'acronym' , 'applet' , 'b' , 'basefont' , 'bdo' ,
14+ 'big' , 'br' , 'button' , 'cite' , 'code' , 'del' , 'dfn' , 'em' , 'font' , 'i' ,
15+ 'iframe' , 'img' , 'input' , 'ins' , 'kbd' , 'label' , 'map' , 'object' , 'q' ,
16+ 's' , 'samp' , 'select' , 'small' , 'span' , 'strike' , 'strong' , 'sub' , 'sup' ,
17+ 'textarea' , 'tt' , 'u' , 'var' ] ;
18+
1319interface ExpandAbbreviationInput {
1420 syntax : string ;
1521 abbreviation : string ;
@@ -62,7 +68,8 @@ export function wrapWithAbbreviation(args: any) {
6268 const preceedingWhiteSpace = matches ? matches [ 1 ] . length : 0 ;
6369
6470 rangeToReplace = new vscode . Range ( rangeToReplace . start . line , rangeToReplace . start . character + preceedingWhiteSpace , rangeToReplace . end . line , rangeToReplace . end . character ) ;
65- expandAbbrList . push ( { syntax, abbreviation, rangeToReplace, textToWrap : [ '\n\t$TM_SELECTED_TEXT\n' ] , filter } ) ;
71+ let textToWrap = rangeToReplace . isSingleLine ? [ '$TM_SELECTED_TEXT' ] : [ '\n\t$TM_SELECTED_TEXT\n' ] ;
72+ expandAbbrList . push ( { syntax, abbreviation, rangeToReplace, textToWrap, filter } ) ;
6673 } ) ;
6774
6875 return expandAbbreviationInRange ( editor , expandAbbrList , true ) ;
@@ -435,17 +442,29 @@ function expandAbbr(input: ExpandAbbreviationInput): string | undefined {
435442
436443 try {
437444 // Expand the abbreviation
438- let expandedText = helper . expandAbbreviation ( input . abbreviation , expandOptions ) ;
445+ let expandedText ;
439446
440447 if ( input . textToWrap ) {
448+ let parsedAbbr = helper . parseAbbreviation ( input . abbreviation , expandOptions ) ;
449+ if ( input . rangeToReplace . isSingleLine && input . textToWrap . length === 1 ) {
450+
451+ // Fetch rightmost element in the parsed abbreviation (i.e the element that will contain the wrapped text).
452+ let wrappingNode = parsedAbbr ;
453+ while ( wrappingNode && wrappingNode . children && wrappingNode . children . length > 0 ) {
454+ wrappingNode = wrappingNode . children [ wrappingNode . children . length - 1 ] ;
455+ }
456+
457+ // If wrapping with a block element, insert newline in the text to wrap.
458+ if ( wrappingNode && inlineElements . indexOf ( wrappingNode . name ) === - 1 ) {
459+ wrappingNode . value = '\n\t' + wrappingNode . value + '\n' ;
460+ }
461+ }
462+ expandedText = helper . expandAbbreviation ( parsedAbbr , expandOptions ) ;
441463 // All $anyword would have been escaped by the emmet helper.
442464 // Remove the escaping backslash from $TM_SELECTED_TEXT so that VS Code Snippet controller can treat it as a variable
443465 expandedText = expandedText . replace ( '\\$TM_SELECTED_TEXT' , '$TM_SELECTED_TEXT' ) ;
444-
445- // If the expanded text is single line then we dont need the \t and \n we added to $TM_SELECTED_TEXT earlier
446- if ( input . textToWrap . length === 1 && expandedText . indexOf ( '\n' ) === - 1 ) {
447- expandedText = expandedText . replace ( / \s * \$ T M _ S E L E C T E D _ T E X T \s * / , '$TM_SELECTED_TEXT' ) ;
448- }
466+ } else {
467+ expandedText = helper . expandAbbreviation ( input . abbreviation , expandOptions ) ;
449468 }
450469
451470 return expandedText ;
0 commit comments