Skip to content

Commit 6e419da

Browse files
committed
Add config option to ignore .editorconfig when running shfmt
1 parent 9c7f723 commit 6e419da

File tree

5 files changed

+80
-31
lines changed

5 files changed

+80
-31
lines changed

server/src/__tests__/config.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ describe('ConfigSchema', () => {
1717
"binaryNextLine": false,
1818
"caseIndent": false,
1919
"funcNextLine": false,
20+
"ignoreEditorconfig": false,
2021
"keepPadding": false,
2122
"languageDialect": "auto",
2223
"path": "shfmt",
@@ -39,6 +40,7 @@ describe('ConfigSchema', () => {
3940
binaryNextLine: true,
4041
caseIndent: true,
4142
funcNextLine: true,
43+
ignoreEditorconfig: true,
4244
keepPadding: true,
4345
languageDialect: 'posix',
4446
path: 'myshfmt',
@@ -65,6 +67,7 @@ describe('ConfigSchema', () => {
6567
"binaryNextLine": true,
6668
"caseIndent": true,
6769
"funcNextLine": true,
70+
"ignoreEditorconfig": true,
6871
"keepPadding": true,
6972
"languageDialect": "posix",
7073
"path": "myshfmt",
@@ -101,6 +104,7 @@ describe('getConfigFromEnvironmentVariables', () => {
101104
"binaryNextLine": false,
102105
"caseIndent": false,
103106
"funcNextLine": false,
107+
"ignoreEditorconfig": false,
104108
"keepPadding": false,
105109
"languageDialect": "auto",
106110
"path": "shfmt",
@@ -131,6 +135,7 @@ describe('getConfigFromEnvironmentVariables', () => {
131135
"binaryNextLine": false,
132136
"caseIndent": false,
133137
"funcNextLine": false,
138+
"ignoreEditorconfig": false,
134139
"keepPadding": false,
135140
"languageDialect": "auto",
136141
"path": "",
@@ -170,6 +175,7 @@ describe('getConfigFromEnvironmentVariables', () => {
170175
"binaryNextLine": false,
171176
"caseIndent": true,
172177
"funcNextLine": false,
178+
"ignoreEditorconfig": false,
173179
"keepPadding": false,
174180
"languageDialect": "auto",
175181
"path": "/path/to/shfmt",

server/src/config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ export const ConfigSchema = z.object({
4646
// Controls the executable used for Shfmt formatting. An empty string will disable formatting
4747
path: z.string().trim().default('shfmt'),
4848

49+
// Ignore shfmt config options in .editorconfig (always use language server config)
50+
ignoreEditorconfig: z.boolean().default(false),
51+
4952
// Language dialect to use when parsing (bash/posix/mksh/bats).
5053
languageDialect: z.enum(['auto', 'bash', 'posix', 'mksh', 'bats']).default('auto'),
5154

@@ -87,6 +90,7 @@ export function getConfigFromEnvironmentVariables(): {
8790
shellcheckPath: process.env.SHELLCHECK_PATH,
8891
shfmt: {
8992
path: process.env.SHFMT_PATH,
93+
ignoreEditorconfig: toBoolean(process.env.SHFMT_IGNORE_EDITORCONFIG),
9094
languageDialect: process.env.SHFMT_LANGUAGE_DIALECT,
9195
binaryNextLine: toBoolean(process.env.SHFMT_BINARY_NEXT_LINE),
9296
caseIndent: toBoolean(process.env.SHFMT_CASE_INDENT),

server/src/shfmt/__tests__/index.test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,5 +760,32 @@ describe('formatter', () => {
760760
expect(shfmtArgs).toContain(`--filename=${filepath}`)
761761
})
762762
})
763+
764+
describe('when an .editorconfig exists but ignoreEditorconfig is set', () => {
765+
let shfmtArgs: string[]
766+
const filepath = `${FIXTURE_FOLDER}/shfmt-editorconfig/shfmt-properties/foo.sh`
767+
768+
beforeAll(async () => {
769+
// @ts-expect-error Testing a private method
770+
shfmtArgs = await formatter.getShfmtArguments(
771+
`file://${filepath}`,
772+
formatOptions,
773+
{ ...lspShfmtConfig, ignoreEditorconfig: true },
774+
)
775+
})
776+
777+
it('should use language server config', () => {
778+
expect(shfmtArgs).toEqual(expect.arrayContaining(lspShfmtArgs))
779+
expect(shfmtArgs.length).toEqual(5) // indentation + filename
780+
})
781+
782+
it('should use indentation config from the editor', () => {
783+
expect(shfmtArgs).toContain('-i=2')
784+
})
785+
786+
it('should include the filename argument', () => {
787+
expect(shfmtArgs).toContain(`--filename=${filepath}`)
788+
})
789+
})
763790
})
764791
})

server/src/shfmt/index.ts

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -75,40 +75,46 @@ export class Formatter {
7575
const filepath = filepathMatch[1]
7676
args.push(`--filename=${filepathMatch[1]}`)
7777

78-
const editorconfigProperties = await editorconfig.parse(filepath)
79-
logger.debug(
80-
`Shfmt: found .editorconfig properties: ${JSON.stringify(
81-
editorconfigProperties,
82-
)}`,
83-
)
84-
85-
const editorconfigShfmtConfig: Record<string, any> = {}
86-
editorconfigShfmtConfig.binaryNextLine = editorconfigProperties.binary_next_line
87-
editorconfigShfmtConfig.caseIndent = editorconfigProperties.switch_case_indent
88-
editorconfigShfmtConfig.funcNextLine = editorconfigProperties.function_next_line
89-
editorconfigShfmtConfig.keepPadding = editorconfigProperties.keep_padding
90-
// --simplify is not supported via .editorconfig
91-
editorconfigShfmtConfig.spaceRedirects = editorconfigProperties.space_redirects
92-
editorconfigShfmtConfig.languageDialect = editorconfigProperties.shell_variant
93-
94-
// if we have any shfmt-specific options in .editorconfig, use the config in .editorconfig and
95-
// ignore the language server config (this is similar to shfmt's approach of using either
96-
// .editorconfig or command line flags, but not both)
97-
if (
98-
editorconfigShfmtConfig.binaryNextLine !== undefined ||
99-
editorconfigShfmtConfig.caseIndent !== undefined ||
100-
editorconfigShfmtConfig.funcNextLine !== undefined ||
101-
editorconfigShfmtConfig.keepPadding !== undefined ||
102-
editorconfigShfmtConfig.spaceRedirects !== undefined ||
103-
editorconfigShfmtConfig.languageDialect !== undefined
104-
) {
78+
if (!lspShfmtConfig?.ignoreEditorconfig) {
79+
const editorconfigProperties = await editorconfig.parse(filepath)
10580
logger.debug(
106-
'Shfmt: detected shfmt properties in .editorconfig - ignoring language server shfmt config',
81+
`Shfmt: found .editorconfig properties: ${JSON.stringify(
82+
editorconfigProperties,
83+
)}`,
10784
)
108-
activeShfmtConfig = { ...editorconfigShfmtConfig }
85+
86+
const editorconfigShfmtConfig: Record<string, any> = {}
87+
editorconfigShfmtConfig.binaryNextLine = editorconfigProperties.binary_next_line
88+
editorconfigShfmtConfig.caseIndent = editorconfigProperties.switch_case_indent
89+
editorconfigShfmtConfig.funcNextLine = editorconfigProperties.function_next_line
90+
editorconfigShfmtConfig.keepPadding = editorconfigProperties.keep_padding
91+
// --simplify is not supported via .editorconfig
92+
editorconfigShfmtConfig.spaceRedirects = editorconfigProperties.space_redirects
93+
editorconfigShfmtConfig.languageDialect = editorconfigProperties.shell_variant
94+
95+
// if we have any shfmt-specific options in .editorconfig, use the config in .editorconfig and
96+
// ignore the language server config (this is similar to shfmt's approach of using either
97+
// .editorconfig or command line flags, but not both)
98+
if (
99+
editorconfigShfmtConfig.binaryNextLine !== undefined ||
100+
editorconfigShfmtConfig.caseIndent !== undefined ||
101+
editorconfigShfmtConfig.funcNextLine !== undefined ||
102+
editorconfigShfmtConfig.keepPadding !== undefined ||
103+
editorconfigShfmtConfig.spaceRedirects !== undefined ||
104+
editorconfigShfmtConfig.languageDialect !== undefined
105+
) {
106+
logger.debug(
107+
'Shfmt: detected shfmt properties in .editorconfig - ignoring language server shfmt config',
108+
)
109+
activeShfmtConfig = { ...editorconfigShfmtConfig }
110+
} else {
111+
logger.debug(
112+
'Shfmt: no shfmt properties found in .editorconfig - using language server shfmt config',
113+
)
114+
}
109115
} else {
110116
logger.debug(
111-
'Shfmt: no shfmt properties found in .editorconfig - using language server shfmt config',
117+
'Shfmt: configured to ignore .editorconfig - using language server shfmt config',
112118
)
113119
}
114120
}
@@ -124,7 +130,8 @@ export class Formatter {
124130
if (activeShfmtConfig?.keepPadding) args.push('-kp') // --keep-padding
125131
if (activeShfmtConfig?.simplifyCode) args.push('-s') // --simplify
126132
if (activeShfmtConfig?.spaceRedirects) args.push('-sr') // --space-redirects
127-
if (activeShfmtConfig?.languageDialect) args.push(`-ln=${activeShfmtConfig.languageDialect}`) // --language-dialect
133+
if (activeShfmtConfig?.languageDialect)
134+
args.push(`-ln=${activeShfmtConfig.languageDialect}`) // --language-dialect
128135

129136
return args
130137
}

vscode-client/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@
8383
"default": "shfmt",
8484
"description": "Controls the executable used for Shfmt formatting. An empty string will disable formatting."
8585
},
86+
"bashIde.shfmt.ignoreEditorconfig": {
87+
"type": "boolean",
88+
"default": false,
89+
"description": "Ignore shfmt config options in .editorconfig (always use language server config)"
90+
},
8691
"bashIde.shfmt.languageDialect": {
8792
"type": "string",
8893
"default": "auto",

0 commit comments

Comments
 (0)