Skip to content

Commit d69efae

Browse files
authored
Fix indentation after string literals containing escaped characters (#6440)
* Update indent regex * Prettier formatting * Add regex tests * Undo prettier changes * Forgot some * One more * Simplify & fix tests * More descriptive comment * Move language config to another file * Remove unneeded tslint disable rule
1 parent 0eb059b commit d69efae

File tree

4 files changed

+61
-26
lines changed

4 files changed

+61
-26
lines changed

news/2 Fixes/4241.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix indentation after string literals containing escaped characters.

src/client/extension.ts

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import {
2525
Disposable,
2626
ExtensionContext,
2727
extensions,
28-
IndentAction,
2928
languages,
3029
Memento,
3130
OutputChannel,
@@ -41,7 +40,7 @@ import { registerTypes as appRegisterTypes } from './application/serviceRegistry
4140
import { IApplicationDiagnostics } from './application/types';
4241
import { DebugService } from './common/application/debugService';
4342
import { IApplicationShell, ICommandManager, IWorkspaceService } from './common/application/types';
44-
import { Commands, isTestExecution, PYTHON, PYTHON_LANGUAGE, STANDARD_OUTPUT_CHANNEL } from './common/constants';
43+
import { Commands, isTestExecution, PYTHON, STANDARD_OUTPUT_CHANNEL } from './common/constants';
4544
import { registerTypes as registerDotNetTypes } from './common/dotnet/serviceRegistry';
4645
import { registerTypes as installerRegisterTypes } from './common/installer/serviceRegistry';
4746
import { traceError } from './common/logger';
@@ -86,6 +85,7 @@ import { registerTypes as interpretersRegisterTypes } from './interpreter/servic
8685
import { ServiceContainer } from './ioc/container';
8786
import { ServiceManager } from './ioc/serviceManager';
8887
import { IServiceContainer, IServiceManager } from './ioc/types';
88+
import { setLanguageConfiguration } from './language/languageConfiguration';
8989
import { LinterCommands } from './linters/linterCommands';
9090
import { registerTypes as lintersRegisterTypes } from './linters/serviceRegistry';
9191
import { ILintingEngine } from './linters/types';
@@ -173,30 +173,7 @@ async function activateUnsafe(context: ExtensionContext): Promise<IExtensionApi>
173173
const linterProvider = new LinterProvider(context, serviceManager);
174174
context.subscriptions.push(linterProvider);
175175

176-
// Enable indentAction
177-
// tslint:disable-next-line:no-non-null-assertion
178-
languages.setLanguageConfiguration(PYTHON_LANGUAGE, {
179-
onEnterRules: [
180-
{
181-
beforeText: /^\s*(?:def|class|for|if|elif|else|while|try|with|finally|except|async)\b.*:\s*/,
182-
action: { indentAction: IndentAction.Indent }
183-
},
184-
{
185-
beforeText: /^(?!\s+\\)[^#\n]+\\\s*/,
186-
action: { indentAction: IndentAction.Indent }
187-
},
188-
{
189-
beforeText: /^\s*#.*/,
190-
afterText: /.+$/,
191-
action: { indentAction: IndentAction.None, appendText: '# ' }
192-
},
193-
{
194-
beforeText: /^\s+(continue|break|return)\b.*/,
195-
afterText: /\s+$/,
196-
action: { indentAction: IndentAction.Outdent }
197-
}
198-
]
199-
});
176+
setLanguageConfiguration();
200177

201178
if (pythonSettings && pythonSettings.formatting && pythonSettings.formatting.provider !== 'internalConsole') {
202179
const formatProvider = new PythonFormattingEditProvider(context, serviceContainer);
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
'use strict';
4+
5+
import { IndentAction, languages } from 'vscode';
6+
import { PYTHON_LANGUAGE } from '../common/constants';
7+
8+
export const MULTILINE_SEPARATOR_INDENT_REGEX = /^(?!\s+\\)[^#\n]+\\$/;
9+
10+
export function setLanguageConfiguration() {
11+
// Enable indentAction
12+
languages.setLanguageConfiguration(PYTHON_LANGUAGE, {
13+
onEnterRules: [
14+
{
15+
beforeText: /^\s*(?:def|class|for|if|elif|else|while|try|with|finally|except|async)\b.*:\s*/,
16+
action: { indentAction: IndentAction.Indent }
17+
},
18+
{
19+
beforeText: MULTILINE_SEPARATOR_INDENT_REGEX,
20+
action: { indentAction: IndentAction.Indent }
21+
},
22+
{
23+
beforeText: /^\s*#.*/,
24+
afterText: /.+$/,
25+
action: { indentAction: IndentAction.None, appendText: '# ' }
26+
},
27+
{
28+
beforeText: /^\s+(continue|break|return)\b.*/,
29+
afterText: /\s+$/,
30+
action: { indentAction: IndentAction.Outdent }
31+
}
32+
]
33+
});
34+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
'use strict';
5+
6+
import { expect } from 'chai';
7+
8+
import { MULTILINE_SEPARATOR_INDENT_REGEX } from '../../client/language/languageConfiguration';
9+
10+
suite('Language configuration regexes', () => {
11+
test('Multiline separator indent regex should not pick up strings with no multiline separator', async () => {
12+
const result = MULTILINE_SEPARATOR_INDENT_REGEX.test('a = "test"');
13+
expect (result).to.be.equal(false, 'Multiline separator indent regex for regular strings should not have matches');
14+
});
15+
test('Multiline separator indent regex should not pick up strings with escaped characters', async () => {
16+
const result = MULTILINE_SEPARATOR_INDENT_REGEX.test('a = \'hello \\n\'');
17+
expect (result).to.be.equal(false, 'Multiline separator indent regex for strings with escaped characters should not have matches');
18+
});
19+
test('Multiline separator indent regex should pick up strings ending with a multiline separator', async () => {
20+
const result = MULTILINE_SEPARATOR_INDENT_REGEX.test('a = \'multiline \\');
21+
expect (result).to.be.equal(true, 'Multiline separator indent regex for strings with newline separator should have matches');
22+
});
23+
});

0 commit comments

Comments
 (0)