1
1
// Copyright (c) Microsoft Corporation. All rights reserved.
2
2
// Licensed under the MIT License.
3
3
4
+ import { ConfigurationTarget , extensions , WorkspaceConfiguration } from 'vscode' ;
4
5
import { LanguageClientOptions } from 'vscode-languageclient' ;
6
+ import * as semver from 'semver' ;
5
7
import { IWorkspaceService } from '../../common/application/types' ;
8
+ import { PYLANCE_EXTENSION_ID } from '../../common/constants' ;
9
+ import { IExperimentService } from '../../common/types' ;
6
10
7
11
import { LanguageServerAnalysisOptionsBase } from '../common/analysisOptions' ;
8
12
import { ILanguageServerOutputChannel } from '../types' ;
9
13
import { LspNotebooksExperiment } from './lspNotebooksExperiment' ;
10
14
15
+ const EDITOR_CONFIG_SECTION = 'editor' ;
16
+ const FORMAT_ON_TYPE_CONFIG_SETTING = 'formatOnType' ;
17
+
11
18
export class NodeLanguageServerAnalysisOptions extends LanguageServerAnalysisOptionsBase {
12
19
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
13
20
constructor (
14
21
lsOutputChannel : ILanguageServerOutputChannel ,
15
22
workspace : IWorkspaceService ,
23
+ private readonly experimentService : IExperimentService ,
16
24
private readonly lspNotebooksExperiment : LspNotebooksExperiment ,
17
25
) {
18
26
super ( lsOutputChannel , workspace ) ;
@@ -25,6 +33,53 @@ export class NodeLanguageServerAnalysisOptions extends LanguageServerAnalysisOpt
25
33
trustedWorkspaceSupport : true ,
26
34
lspNotebooksSupport : this . lspNotebooksExperiment . isInNotebooksExperiment ( ) ,
27
35
lspInteractiveWindowSupport : this . lspNotebooksExperiment . isInNotebooksExperimentWithInteractiveWindowSupport ( ) ,
36
+ autoIndentSupport : await this . isAutoIndentEnabled ( ) ,
28
37
} as unknown ) as LanguageClientOptions ;
29
38
}
39
+
40
+ private async isAutoIndentEnabled ( ) {
41
+ const editorConfig = this . getPythonSpecificEditorSection ( ) ;
42
+ let formatOnTypeEffectiveValue = editorConfig . get ( FORMAT_ON_TYPE_CONFIG_SETTING ) ;
43
+ const formatOnTypeInspect = editorConfig . inspect ( FORMAT_ON_TYPE_CONFIG_SETTING ) ;
44
+ const formatOnTypeSetForPython = formatOnTypeInspect ?. globalLanguageValue !== undefined ;
45
+
46
+ const inExperiment = await this . isInAutoIndentExperiment ( ) ;
47
+
48
+ if ( inExperiment !== formatOnTypeSetForPython ) {
49
+ if ( inExperiment ) {
50
+ await NodeLanguageServerAnalysisOptions . setPythonSpecificFormatOnType ( editorConfig , true ) ;
51
+ } else if ( formatOnTypeInspect ?. globalLanguageValue !== false ) {
52
+ await NodeLanguageServerAnalysisOptions . setPythonSpecificFormatOnType ( editorConfig , undefined ) ;
53
+ }
54
+
55
+ formatOnTypeEffectiveValue = this . getPythonSpecificEditorSection ( ) . get ( FORMAT_ON_TYPE_CONFIG_SETTING ) ;
56
+ }
57
+
58
+ return inExperiment && formatOnTypeEffectiveValue ;
59
+ }
60
+
61
+ private async isInAutoIndentExperiment ( ) : Promise < boolean > {
62
+ if ( await this . experimentService . inExperiment ( 'pylanceAutoIndent' ) ) {
63
+ return true ;
64
+ }
65
+
66
+ const pylanceVersion = extensions . getExtension ( PYLANCE_EXTENSION_ID ) ?. packageJSON . version ;
67
+ return pylanceVersion && semver . prerelease ( pylanceVersion ) ?. includes ( 'dev' ) ;
68
+ }
69
+
70
+ private getPythonSpecificEditorSection ( ) {
71
+ return this . workspace . getConfiguration ( EDITOR_CONFIG_SECTION , undefined , /* languageSpecific */ true ) ;
72
+ }
73
+
74
+ private static async setPythonSpecificFormatOnType (
75
+ editorConfig : WorkspaceConfiguration ,
76
+ value : boolean | undefined ,
77
+ ) {
78
+ await editorConfig . update (
79
+ FORMAT_ON_TYPE_CONFIG_SETTING ,
80
+ value ,
81
+ ConfigurationTarget . Global ,
82
+ /* overrideInLanguage */ true ,
83
+ ) ;
84
+ }
30
85
}
0 commit comments