11import * as editorconfig from 'editorconfig'
2- import { TextDocument , TextEditorOptions , Uri , window , workspace } from 'vscode'
2+ import {
3+ TextDocument ,
4+ TextEditorOptions ,
5+ Uri ,
6+ window ,
7+ workspace ,
8+ commands ,
9+ } from 'vscode'
310
411/**
512 * Resolves `TextEditorOptions` for a `TextDocument`, combining the editor's
@@ -15,16 +22,15 @@ export async function resolveTextEditorOptions(
1522 onEmptyConfig ?: ( relativePath : string ) => void
1623 } = { } ,
1724) {
18- const editorconfigSettings = await resolveCoreConfig ( doc , {
19- onBeforeResolve,
20- } )
21- if ( editorconfigSettings ) {
22- return fromEditorConfig ( editorconfigSettings , pickWorkspaceDefaults ( doc ) )
25+ const coreConfig = await resolveCoreConfig ( doc , { onBeforeResolve } )
26+ if ( coreConfig ) {
27+ const defaults = pickWorkspaceDefaults ( doc )
28+ return fromEditorConfig ( coreConfig , defaults )
2329 }
2430 if ( onEmptyConfig ) {
25- const rp = resolveFile ( doc ) . relativePath
26- if ( rp ) {
27- onEmptyConfig ( rp )
31+ const { relativePath } = resolveFile ( doc )
32+ if ( relativePath ) {
33+ onEmptyConfig ( relativePath )
2834 }
2935 }
3036 return { }
@@ -72,14 +78,21 @@ export function pickWorkspaceDefaults(doc?: TextDocument): {
7278 * this property value will be `undefined`.
7379 */
7480 insertSpaces ?: boolean
81+ /**
82+ * The number of spaces used for indentation or `undefined` if
83+ * `editor.detectIndentation` is on.
84+ */
85+ indentSize ?: number | string
7586} {
87+ commands . executeCommand ( 'editor.action.detectIndentation' )
7688 const workspaceConfig = workspace . getConfiguration ( 'editor' , doc )
7789 const detectIndentation = workspaceConfig . get < boolean > ( 'detectIndentation' )
7890
7991 return detectIndentation
8092 ? { }
8193 : {
8294 tabSize : workspaceConfig . get < number > ( 'tabSize' ) ,
95+ indentSize : workspaceConfig . get < number | string > ( 'indentSize' ) ,
8396 insertSpaces : workspaceConfig . get < boolean > ( 'insertSpaces' ) ,
8497 }
8598}
@@ -95,9 +108,7 @@ export async function resolveCoreConfig(
95108 doc : TextDocument ,
96109 {
97110 onBeforeResolve,
98- } : {
99- onBeforeResolve ?: ( relativePath : string ) => void
100- } = { } ,
111+ } : { onBeforeResolve ?: ( relativePath : string ) => void } = { } ,
101112) : Promise < ResolvedCoreConfig > {
102113 const { fileName, relativePath } = resolveFile ( doc )
103114 if ( ! fileName ) {
@@ -107,9 +118,6 @@ export async function resolveCoreConfig(
107118 onBeforeResolve ?.( relativePath )
108119 }
109120 const config = await editorconfig . parse ( fileName )
110- if ( config . indent_size === 'tab' ) {
111- config . indent_size = config . tab_width
112- }
113121 return config as ResolvedCoreConfig
114122}
115123
@@ -144,28 +152,39 @@ export function fromEditorConfig(
144152 config : editorconfig . KnownProps = { } ,
145153 defaults : TextEditorOptions = pickWorkspaceDefaults ( ) ,
146154) : TextEditorOptions {
147- const resolved : TextEditorOptions = {
148- tabSize :
149- config . indent_style === 'tab'
150- ? ( config . tab_width ?? config . indent_size )
151- : ( config . indent_size ?? config . tab_width ) ,
155+ const resolved : TextEditorOptions = { }
156+
157+ if ( Number . isInteger ( config . indent_size ) ) {
158+ resolved . indentSize = config . indent_size
159+ } else if ( config . indent_size === 'tab' ) {
160+ resolved . indentSize = 'tabSize'
152161 }
153- if ( resolved . tabSize === 'tab' ) {
162+
163+ if ( Number . isInteger ( config . tab_width ) ) {
154164 resolved . tabSize = config . tab_width
165+ } else if ( Number . isInteger ( config . indent_size ) ) {
166+ resolved . tabSize = config . indent_size
155167 }
156- return {
157- ...( config . indent_style === 'tab' ||
158- config . indent_size === 'tab' ||
159- config . indent_style === 'space'
160- ? {
161- insertSpaces : config . indent_style === 'space' ,
162- }
163- : { } ) ,
164- tabSize :
165- resolved . tabSize && Number ( resolved . tabSize ) >= 0
166- ? resolved . tabSize
167- : defaults . tabSize ,
168+
169+ if ( config . indent_style === 'tab' ) {
170+ resolved . insertSpaces = false
171+ } else if ( config . indent_style === 'space' ) {
172+ resolved . insertSpaces = true
168173 }
174+
175+ const combined = { ...defaults , ...resolved }
176+
177+ // decouple tabSize from indentSize when possible
178+ if (
179+ ! Number . isInteger ( config . tab_width ) &&
180+ ! ( combined . insertSpaces && combined . indentSize === 'tabSize' ) &&
181+ ! ( config . indent_style === 'tab' && Number . isInteger ( config . indent_size ) ) &&
182+ Number . isInteger ( defaults . tabSize )
183+ ) {
184+ combined . tabSize = defaults . tabSize
185+ }
186+
187+ return combined
169188}
170189
171190/**
0 commit comments