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 fe93389

Browse files
authored
Merge pull request #1168 from chris-reeves/additional-shfmt-options
Additional shfmt options
2 parents 04a2cb3 + 3a5ac07 commit fe93389

File tree

9 files changed

+239
-10
lines changed

9 files changed

+239
-10
lines changed

‎README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ To be implemented:
2525

2626
### Dependencies
2727

28-
As a dependency, we recommend that you first install shellcheck [shellcheck][shellcheck] to enable linting: https://github.com/koalaman/shellcheck#installing . If shellcheck is installed, bash-language-server will automatically call it to provide linting and code analysis each time the file is updated (with debounce time of 500ms).
28+
As a dependency, we recommend that you first install [shellcheck][shellcheck] to enable linting:
29+
https://github.com/koalaman/shellcheck#installing . If `shellcheck` is installed,
30+
bash-language-server will automatically call it to provide linting and code analysis each time the
31+
file is updated (with debounce time of 500ms).
2932

3033
If you want your shell scripts to be formatted consistently, you can install [shfmt][shfmt]. If
3134
`shfmt` is installed then your documents will be formatted whenever you take the 'format document'
@@ -185,6 +188,13 @@ Using the built-in `eglot` lsp mode:
185188
(bash-ts-mode . eglot-ensure))
186189
```
187190

191+
## `shfmt` integration
192+
193+
The indentation used by `shfmt` is whatever has been configured for the current editor session, so
194+
there is no `shfmt`-specific configuration variable for this. If your editor is configured for
195+
two-space indents then that's what it will use. If you're using tabs for indentation then `shfmt`
196+
will use that.
197+
188198
## Logging
189199

190200
The minimum logging level for the server can be adjusted using the `BASH_IDE_LOG_LEVEL` environment variable

‎server/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Bash Language Server
22

3+
## 5.3.4
4+
5+
- Add additonal shfmt formatting config options https://github.com/bash-lsp/bash-language-server/pull/1168
6+
37
## 5.3.3
48

59
- Revert "Add --help fallback for documentation" https://github.com/bash-lsp/bash-language-server/pull/1052

‎server/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"description": "A language server for Bash",
44
"author": "Mads Hartmann",
55
"license": "MIT",
6-
"version": "5.3.3",
6+
"version": "5.3.4",
77
"main": "./out/server.js",
88
"typings": "./out/server.d.ts",
99
"bin": {

‎server/src/__tests__/config.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ describe('ConfigSchema', () => {
1717
"binaryNextLine": false,
1818
"caseIndent": false,
1919
"funcNextLine": false,
20+
"keepPadding": false,
2021
"path": "shfmt",
22+
"simplifyCode": false,
2123
"spaceRedirects": false,
2224
},
2325
}
@@ -36,7 +38,9 @@ describe('ConfigSchema', () => {
3638
binaryNextLine: true,
3739
caseIndent: true,
3840
funcNextLine: true,
41+
keepPadding: true,
3942
path: 'myshfmt',
43+
simplifyCode: true,
4044
spaceRedirects: true,
4145
},
4246
}),
@@ -59,7 +63,9 @@ describe('ConfigSchema', () => {
5963
"binaryNextLine": true,
6064
"caseIndent": true,
6165
"funcNextLine": true,
66+
"keepPadding": true,
6267
"path": "myshfmt",
68+
"simplifyCode": true,
6369
"spaceRedirects": true,
6470
},
6571
}
@@ -92,7 +98,9 @@ describe('getConfigFromEnvironmentVariables', () => {
9298
"binaryNextLine": false,
9399
"caseIndent": false,
94100
"funcNextLine": false,
101+
"keepPadding": false,
95102
"path": "shfmt",
103+
"simplifyCode": false,
96104
"spaceRedirects": false,
97105
},
98106
}
@@ -119,7 +127,9 @@ describe('getConfigFromEnvironmentVariables', () => {
119127
"binaryNextLine": false,
120128
"caseIndent": false,
121129
"funcNextLine": false,
130+
"keepPadding": false,
122131
"path": "",
132+
"simplifyCode": false,
123133
"spaceRedirects": false,
124134
},
125135
}
@@ -155,7 +165,9 @@ describe('getConfigFromEnvironmentVariables', () => {
155165
"binaryNextLine": false,
156166
"caseIndent": true,
157167
"funcNextLine": false,
168+
"keepPadding": false,
158169
"path": "/path/to/shfmt",
170+
"simplifyCode": false,
159171
"spaceRedirects": false,
160172
},
161173
}

‎server/src/config.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ export const ConfigSchema = z.object({
5555
// Place function opening braces on a separate line.
5656
funcNextLine: z.boolean().default(false),
5757

58+
// (Deprecated) Keep column alignment padding.
59+
keepPadding: z.boolean().default(false),
60+
61+
// Simplify code before formatting.
62+
simplifyCode: z.boolean().default(false),
63+
5864
// Follow redirection operators with a space.
5965
spaceRedirects: z.boolean().default(false),
6066
})
@@ -81,6 +87,8 @@ export function getConfigFromEnvironmentVariables(): {
8187
binaryNextLine: toBoolean(process.env.SHFMT_BINARY_NEXT_LINE),
8288
caseIndent: toBoolean(process.env.SHFMT_CASE_INDENT),
8389
funcNextLine: toBoolean(process.env.SHFMT_FUNC_NEXT_LINE),
90+
keepPadding: toBoolean(process.env.SHFMT_KEEP_PADDING),
91+
simplifyCode: toBoolean(process.env.SHFMT_SIMPLIFY_CODE),
8492
spaceRedirects: toBoolean(process.env.SHFMT_SPACE_REDIRECTS),
8593
},
8694
}

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

Lines changed: 175 additions & 3 deletions
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:exitedwithstatus1:.*\/testing\/fixtures\/parse-problems.sh:10:1:>mustbefollowedbyaword/,
6262
)
6363
})
6464

@@ -83,6 +83,12 @@ describe('formatter', () => {
8383
;;
8484
esac
8585
86+
echo one two three
87+
echo four five six
88+
echo seven eight nine
89+
90+
[[ "$simplify" == "simplify" ]]
91+
8692
echo space redirects >/dev/null
8793
8894
function next() {
@@ -128,6 +134,12 @@ describe('formatter', () => {
128134
;;
129135
esac
130136
137+
echo one two three
138+
echo four five six
139+
echo seven eight nine
140+
141+
[[ "$simplify" == "simplify" ]]
142+
131143
echo space redirects >/dev/null
132144
133145
function next() {
@@ -173,6 +185,12 @@ describe('formatter', () => {
173185
;;
174186
esac
175187
188+
echo one two three
189+
echo four five six
190+
echo seven eight nine
191+
192+
[[ "$simplify" == "simplify" ]]
193+
176194
echo space redirects >/dev/null
177195
178196
function next() {
@@ -219,6 +237,12 @@ describe('formatter', () => {
219237
;;
220238
esac
221239
240+
echo one two three
241+
echo four five six
242+
echo seven eight nine
243+
244+
[[ "$simplify" == "simplify" ]]
245+
222246
echo space redirects >/dev/null
223247
224248
function next() {
@@ -265,6 +289,12 @@ describe('formatter', () => {
265289
;;
266290
esac
267291
292+
echo one two three
293+
echo four five six
294+
echo seven eight nine
295+
296+
[[ "$simplify" == "simplify" ]]
297+
268298
echo space redirects >/dev/null
269299
270300
function next() {
@@ -311,6 +341,12 @@ describe('formatter', () => {
311341
;;
312342
esac
313343
344+
echo one two three
345+
echo four five six
346+
echo seven eight nine
347+
348+
[[ "$simplify" == "simplify" ]]
349+
314350
echo space redirects >/dev/null
315351
316352
function next()
@@ -333,6 +369,110 @@ describe('formatter', () => {
333369
`)
334370
})
335371

372+
it('should format with padding kept as-is when keepPadding is true', async () => {
373+
const [result] = await getFormattingResult({
374+
document: FIXTURE_DOCUMENT.SHFMT,
375+
formatOptions: { tabSize: 2, insertSpaces: true },
376+
shfmtConfig: { keepPadding: true },
377+
})
378+
expect(result).toMatchInlineSnapshot(`
379+
[
380+
{
381+
"newText": "#!/bin/bash
382+
set -ueo pipefail
383+
384+
if [ -z "$arg" ]; then
385+
echo indent
386+
fi
387+
388+
echo binary &&
389+
echo next line
390+
391+
case "$arg" in
392+
a)
393+
echo case indent
394+
;;
395+
esac
396+
397+
echo one two three
398+
echo four five six
399+
echo seven eight nine
400+
401+
[[ "$simplify" == "simplify" ]]
402+
403+
echo space redirects >/dev/null
404+
405+
function next() {
406+
echo line
407+
}
408+
",
409+
"range": {
410+
"end": {
411+
"character": 2147483647,
412+
"line": 2147483647,
413+
},
414+
"start": {
415+
"character": 0,
416+
"line": 0,
417+
},
418+
},
419+
},
420+
]
421+
`)
422+
})
423+
424+
it('should format after simplifying the code when simplifyCode is true', async () => {
425+
const [result] = await getFormattingResult({
426+
document: FIXTURE_DOCUMENT.SHFMT,
427+
formatOptions: { tabSize: 2, insertSpaces: true },
428+
shfmtConfig: { simplifyCode: true },
429+
})
430+
expect(result).toMatchInlineSnapshot(`
431+
[
432+
{
433+
"newText": "#!/bin/bash
434+
set -ueo pipefail
435+
436+
if [ -z "$arg" ]; then
437+
echo indent
438+
fi
439+
440+
echo binary &&
441+
echo next line
442+
443+
case "$arg" in
444+
a)
445+
echo case indent
446+
;;
447+
esac
448+
449+
echo one two three
450+
echo four five six
451+
echo seven eight nine
452+
453+
[[ $simplify == "simplify" ]]
454+
455+
echo space redirects >/dev/null
456+
457+
function next() {
458+
echo line
459+
}
460+
",
461+
"range": {
462+
"end": {
463+
"character": 2147483647,
464+
"line": 2147483647,
465+
},
466+
"start": {
467+
"character": 0,
468+
"line": 0,
469+
},
470+
},
471+
},
472+
]
473+
`)
474+
})
475+
336476
it('should format with redirect operators followed by a space when spaceRedirects is true', async () => {
337477
const [result] = await getFormattingResult({
338478
document: FIXTURE_DOCUMENT.SHFMT,
@@ -358,6 +498,12 @@ describe('formatter', () => {
358498
;;
359499
esac
360500
501+
echo one two three
502+
echo four five six
503+
echo seven eight nine
504+
505+
[[ "$simplify" == "simplify" ]]
506+
361507
echo space redirects > /dev/null
362508
363509
function next() {
@@ -387,6 +533,8 @@ describe('formatter', () => {
387533
binaryNextLine: true,
388534
caseIndent: true,
389535
funcNextLine: true,
536+
keepPadding: true,
537+
simplifyCode: true,
390538
spaceRedirects: true,
391539
},
392540
})
@@ -401,18 +549,24 @@ describe('formatter', () => {
401549
fi
402550
403551
echo binary \\
404-
&& echo next line
552+
&& echo next line
405553
406554
case "$arg" in
407555
a)
408556
echo case indent
409557
;;
410558
esac
411559
560+
echo one two three
561+
echo four five six
562+
echo seven eight nine
563+
564+
[[ $simplify == "simplify" ]]
565+
412566
echo space redirects > /dev/null
413567
414568
function next()
415-
{
569+
{
416570
echo line
417571
}
418572
",
@@ -430,4 +584,22 @@ describe('formatter', () => {
430584
]
431585
`)
432586
})
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:exitedwithstatus1:<standardinput>:10:1:>mustbefollowedbyaword/,
603+
)
604+
})
433605
})

0 commit comments

Comments
(0)

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