Skip to content

Commit

Permalink
Fix gq to handle tab indentation (#4050)
Browse files Browse the repository at this point in the history
The `gq` command to "reflow" selected text in visual line mode didn't
properly handle tabs, replacing them with spaces.
Fixes #3929
  • Loading branch information
orn688 authored and J-Fields committed Sep 7, 2019
1 parent 91e20e0 commit cf076c6
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 24 deletions.
23 changes: 14 additions & 9 deletions src/actions/operator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -841,22 +841,27 @@ class ActionVisualReflowParagraph extends BaseOperator {
{ singleLine: true, start: '' },
];

public getIndentationLevel(s: string): number {
public getIndentation(s: string): string {
// Use the indentation of the first non-whitespace line, if any such line is
// selected.
for (const line of s.split('\n')) {
const result = line.match(/^\s+/g);
const indentLevel = result ? result[0].length : 0;
const indent = result ? result[0] : '';

if (indentLevel !== line.length) {
return indentLevel;
if (indent !== line) {
return indent;
}
}

return 0;
return '';
}

public reflowParagraph(s: string, indentLevel: number): string {
public reflowParagraph(s: string, indent: string): string {
let indentLevel = 0;
for (const char of indent) {
indentLevel += char === '\t' ? configuration.tabstop : 1;
}
const maximumLineLength = configuration.textwidth - indentLevel - 2;
const indent = Array(indentLevel + 1).join(' ');

// Chunk the lines by commenting style.

Expand Down Expand Up @@ -1033,9 +1038,9 @@ class ActionVisualReflowParagraph extends BaseOperator {
end = Position.LaterOf(start, end);

let textToReflow = TextEditor.getText(new vscode.Range(start, end));
let indentLevel = this.getIndentationLevel(textToReflow);
let indent = this.getIndentation(textToReflow);

textToReflow = this.reflowParagraph(textToReflow, indentLevel);
textToReflow = this.reflowParagraph(textToReflow, indent);

vimState.recordedState.transformations.push({
type: 'replaceText',
Expand Down
49 changes: 34 additions & 15 deletions test/mode/modeNormal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1330,22 +1330,41 @@ suite('Mode Normal', () => {
end: ['testtest', 'testtest', 'testtes|t'],
});

// These tests run poorly on Travis for w.e. reason
// newTest({
// title: "gq handles spaces after single line comments correctly",
// start: ['// We choose to write a vim extension, not because it is easy, but because it is hard|.'],
// keysPressed: 'Vgq',
// end: [ '// We choose to write a vim extension, not because it is easy, but because it is',
// '|// hard.'],
// });
newTest({
title: 'gq handles spaces after single line comments correctly',
start: [
'// We choose to write a vim extension, not because it is easy, but because it is hard|.',
],
keysPressed: 'Vgq',
end: [
'// We choose to write a vim extension, not because it is easy, but because it is',
'|// hard.',
],
});

// newTest({
// title: "gq handles spaces before single line comments correctly",
// start: [' // We choose to write a vim extension, not because it is easy, but because it is hard|.'],
// keysPressed: 'Vgq',
// end: [ ' // We choose to write a vim extension, not because it is easy, but because',
// '| // it is hard.']
// });
newTest({
title: 'gq handles spaces before single line comments correctly',
start: [
' // We choose to write a vim extension, not because it is easy, but because it is hard|.',
],
keysPressed: 'Vgq',
end: [
' // We choose to write a vim extension, not because it is easy, but because',
'| // it is hard.',
],
});

newTest({
title: 'gq handles tabs before single line comments correctly',
start: [
'\t\t// We choose to write a vim extension, not because it is easy, but because it is hard|.',
],
keysPressed: 'Vgq',
end: [
'\t\t// We choose to write a vim extension, not because it is easy, but',
'|\t\t// because it is hard.',
],
});

newTest({
title: 'Can handle space',
Expand Down

0 comments on commit cf076c6

Please sign in to comment.