Skip to content

Commit 773a61c

Browse files
committed
Pass --filename to shfmt when available
This will aid in language dialect detection.
1 parent 2d81228 commit 773a61c

File tree

2 files changed

+28
-6
lines changed

2 files changed

+28
-6
lines changed

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ describe('formatter', () => {
5858
expect(async () => {
5959
await getFormattingResult({ document: FIXTURE_DOCUMENT.PARSE_PROBLEMS })
6060
}).rejects.toThrow(
61-
'Shfmt: exited with status 1: <standard input>:10:1: > must be followed by a word',
61+
/Shfmt: exited with status 1: .*\/testing\/fixtures\/parse-problems.sh:10:1: > must be followed by a word/,
6262
)
6363
})
6464

@@ -584,4 +584,22 @@ describe('formatter', () => {
584584
]
585585
`)
586586
})
587+
588+
it('should omit filename from the shfmt comment when it cannot be determined', async () => {
589+
// There's no easy way to see what filename has been passed to shfmt without inspecting the
590+
// contents of the logs. As a workaround, we set a non-file:// URI on a dodgy document to
591+
// trigger an exception and inspect the error message.
592+
const testDocument = TextDocument.create(
593+
'http://localhost/',
594+
'shellscript',
595+
0,
596+
FIXTURE_DOCUMENT.PARSE_PROBLEMS.getText(),
597+
)
598+
599+
expect(async () => {
600+
await getFormattingResult({ document: testDocument })
601+
}).rejects.toThrow(
602+
/Shfmt: exited with status 1: <standard input>:10:1: > must be followed by a word/,
603+
)
604+
})
587605
})

server/src/shfmt/index.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,7 @@ export class Formatter {
4141
formatOptions?: LSP.FormattingOptions | null,
4242
shfmtConfig?: Record<string, string | boolean> | null,
4343
): Promise<TextEdit[]> {
44-
const documentText = document.getText()
45-
46-
const result = await this.runShfmt(documentText, formatOptions, shfmtConfig)
44+
const result = await this.runShfmt(document, formatOptions, shfmtConfig)
4745

4846
if (!this._canFormat) {
4947
return []
@@ -61,7 +59,7 @@ export class Formatter {
6159
}
6260

6361
private async runShfmt(
64-
documentText: string,
62+
document: TextDocument,
6563
formatOptions?: LSP.FormattingOptions | null,
6664
shfmtConfig?: Record<string, string | boolean> | null,
6765
): Promise<string> {
@@ -74,6 +72,12 @@ export class Formatter {
7472
if (shfmtConfig?.simplifyCode) args.push('-s') // --simplify
7573
if (shfmtConfig?.spaceRedirects) args.push('-sr') // --space-redirects
7674

75+
// If we can determine a local filename, pass that to shfmt to aid language dialect detection
76+
const filePathMatch = document.uri.match(/^file:\/\/(.*)$/)
77+
if (filePathMatch) {
78+
args.push(`--filename=${filePathMatch[1]}`)
79+
}
80+
7781
logger.debug(`Shfmt: running "${this.executablePath} ${args.join(' ')}"`)
7882

7983
let out = ''
@@ -90,7 +94,7 @@ export class Formatter {
9094
// This is solved in Node >= 15.1 by the "on('spawn', ...)" event, but we need to
9195
// support earlier versions.
9296
})
93-
proc.stdin.end(documentText)
97+
proc.stdin.end(document.getText())
9498
})
9599

96100
let exit

0 commit comments

Comments
 (0)