Skip to content

Commit

Permalink
Merge pull request #3105 from xconverge/allow-surround-to-retain-attr…
Browse files Browse the repository at this point in the history
…ibutes

fixes #1938 Allow to retain attributes when using surround
  • Loading branch information
xconverge authored Oct 6, 2018
2 parents 94d9c3a + 98d166d commit 9eb8597
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 5 deletions.
28 changes: 23 additions & 5 deletions src/actions/plugins/surround.ts
Original file line number Diff line number Diff line change
Expand Up @@ -436,16 +436,27 @@ export class CommandSurroundAddToReplacement extends BaseCommand {
vimState: VimState,
position: Position
): Promise<boolean> {
const { target, replacement, operator } = vimState.surround!;
const { target, operator } = vimState.surround!;
let replacement = vimState.surround!.replacement;

// Flag of whether or not html attributes should be retained
let retainAttributes = false;

if (operator === 'change' || operator === 'yank') {
if (!replacement) {
return false;
}

// This is an incomplete tag. Wait for the user to finish it.
if (replacement[0] === '<' && replacement[replacement.length - 1] !== '>') {
return false;
// This is currently an incomplete tag. Check if we should finish it.
if (replacement[0] === '<') {
// If enter is used, retain the html attributes if possible and consider this tag done
// if neither > or <enter> were pressed, this is not a complete tag so return false
if (replacement[replacement.length - 1] === '\n') {
replacement = replacement.slice(0, replacement.length - 1);
retainAttributes = true;
} else if (replacement[replacement.length - 1] !== '>') {
return false;
}
}
}

Expand Down Expand Up @@ -563,7 +574,14 @@ export class CommandSurroundAddToReplacement extends BaseCommand {
startReplaceRange = new Range(start, start.getRight());
endReplaceRange = new Range(innerTagContent.stop, innerTagContent.stop.getRight());

startDeleteRange = new Range(start.getRight(), innerTagContent.start);
if (retainAttributes) {
// Don't remove the attributes, just the tag name (one WORD)
const tagNameEnd = start.getCurrentBigWordEnd().getRight();
startDeleteRange = new Range(start.getRight(), tagNameEnd);
} else {
startDeleteRange = new Range(start.getRight(), innerTagContent.start);
}

endDeleteRange = new Range(innerTagContent.stop.getRight(), stop);
}

Expand Down
14 changes: 14 additions & 0 deletions test/plugins/surround.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,18 @@ suite('surround plugin', () => {
keysPressed: 'cs{[',
end: ['func() [ ', ' |foo()', ' ]'],
});

newTest({
title: 'change surround with tags that contain an attribute and preserve them',
start: ['<h2 test class="foo">b|ar</h2>'],
keysPressed: 'cstth3' + '\n',
end: ['<h3 test class="foo">b|ar</h3>'],
});

newTest({
title: 'change surround with tags that contain an attribute and remove them',
start: ['<h2 test class="foo">b|ar</h2>'],
keysPressed: 'cstth3>',
end: ['<h3>b|ar</h3>'],
});
});

0 comments on commit 9eb8597

Please sign in to comment.