Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 0c7dd3c

Browse files
Add support for reading shfmt config options from .editorconfig
If we have any `shfmt`-specific options in `.editorconfig`, use the config in `.editorconfig` and ignore the language server config (this is similar to `shfmt`'s approach of using either `.editorconfig` or command line flags, but not both). Indentation always comes via the editor - if someone is using `.editorconfig` then the expectation is that they will have configured their editor's indentation in this way too.
1 parent e038a25 commit 0c7dd3c

File tree

3 files changed

+104
-21
lines changed

3 files changed

+104
-21
lines changed

‎pnpm-lock.yaml

Lines changed: 30 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎server/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"node": ">=16"
1818
},
1919
"dependencies": {
20+
"editorconfig": "2.0.0",
2021
"fast-glob": "3.3.2",
2122
"fuzzy-search": "3.2.1",
2223
"node-fetch": "2.7.0",

‎server/src/shfmt/index.ts

Lines changed: 73 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { spawn } from 'child_process'
2+
import * as editorconfig from 'editorconfig'
23
import * as LSP from 'vscode-languageserver/node'
3-
import { TextDocument, TextEdit } from 'vscode-languageserver-textdocument'
4+
import { DocumentUri,TextDocument, TextEdit } from 'vscode-languageserver-textdocument'
45

56
import { logger } from '../util/logger'
67

@@ -58,26 +59,82 @@ export class Formatter {
5859
]
5960
}
6061

62+
private async getShfmtArguments(
63+
documentUri: DocumentUri,
64+
formatOptions?: LSP.FormattingOptions | null,
65+
lspShfmtConfig?: Record<string, string | boolean> | null,
66+
): Promise<string[]> {
67+
const args: string[] = []
68+
69+
// this is the config that we'll use to build args - default to language server config
70+
let activeShfmtConfig = { ...lspShfmtConfig }
71+
72+
// do we have a document stored on the local filesystem?
73+
const filepathMatch = documentUri.match(/^file:\/\/(.*)$/)
74+
if (filepathMatch) {
75+
const filepath = filepathMatch[1]
76+
args.push(`--filename=${filepathMatch[1]}`)
77+
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+
) {
105+
logger.debug(
106+
'Shfmt: detected shfmt properties in .editorconfig - ignoring language server shfmt config',
107+
)
108+
activeShfmtConfig = { ...editorconfigShfmtConfig }
109+
} else {
110+
logger.debug(
111+
'Shfmt: no shfmt properties found in .editorconfig - using language server shfmt config',
112+
)
113+
}
114+
}
115+
116+
// indentation always comes via the editor - if someone is using .editorconfig then the
117+
// expectation is that they will have configured their editor's indentation in this way too
118+
const indentation: number = formatOptions?.insertSpaces ? formatOptions.tabSize : 0
119+
args.push(`-i=${indentation}`) // --indent
120+
121+
if (activeShfmtConfig?.binaryNextLine) args.push('-bn') // --binary-next-line
122+
if (activeShfmtConfig?.caseIndent) args.push('-ci') // --case-indent
123+
if (activeShfmtConfig?.funcNextLine) args.push('-fn') // --func-next-line
124+
if (activeShfmtConfig?.keepPadding) args.push('-kp') // --keep-padding
125+
if (activeShfmtConfig?.simplifyCode) args.push('-s') // --simplify
126+
if (activeShfmtConfig?.spaceRedirects) args.push('-sr') // --space-redirects
127+
if (activeShfmtConfig?.languageDialect) args.push(`-ln=${activeShfmtConfig.languageDialect}`) // --language-dialect
128+
129+
return args
130+
}
131+
61132
private async runShfmt(
62133
document: TextDocument,
63134
formatOptions?: LSP.FormattingOptions | null,
64135
shfmtConfig?: Record<string, string | boolean> | null,
65136
): Promise<string> {
66-
const indentation: number = formatOptions?.insertSpaces ? formatOptions.tabSize : 0
67-
const args: string[] = [`-i=${indentation}`] // --indent
68-
if (shfmtConfig?.binaryNextLine) args.push('-bn') // --binary-next-line
69-
if (shfmtConfig?.caseIndent) args.push('-ci') // --case-indent
70-
if (shfmtConfig?.funcNextLine) args.push('-fn') // --func-next-line
71-
if (shfmtConfig?.keepPadding) args.push('-kp') // --keep-padding
72-
if (shfmtConfig?.simplifyCode) args.push('-s') // --simplify
73-
if (shfmtConfig?.spaceRedirects) args.push('-sr') // --space-redirects
74-
if (shfmtConfig?.languageDialect) args.push(`-ln=${shfmtConfig.languageDialect}`) // --language-dialect
75-
76-
// If we can determine a local filename, pass that to shfmt to aid language dialect detection
77-
const filePathMatch = document.uri.match(/^file:\/\/(.*)$/)
78-
if (filePathMatch) {
79-
args.push(`--filename=${filePathMatch[1]}`)
80-
}
137+
const args = await this.getShfmtArguments(document.uri, formatOptions, shfmtConfig)
81138

82139
logger.debug(`Shfmt: running "${this.executablePath} ${args.join(' ')}"`)
83140

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /