-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Client-side on-type formatting support #745
Changes from 16 commits
192de8e
503ba8d
16788ba
7912c4b
1570e22
8141e65
18a7d8b
8169857
e376359
7ff8a26
908b2a3
bec2ea6
d74ebfe
d6ce58f
638d54a
920db1a
7fdfbc5
4fed3f3
51a3acf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -458,6 +458,67 @@ Here is an example with the [Java Language Server](https://github.com/eclipse-jd | |
|
||
 | ||
|
||
If desired — for example, for those who want to control when formatting is performed — server-side/LSP-based | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While updating the on-type formatting docs for this feature, I added details on how to disable server-side on-type formatting if desired. |
||
on-type formatting can be disabled via client configuration as follows: | ||
|
||
```json | ||
{ | ||
"format": { | ||
"onTypeFormatting": { | ||
"serverSide": { | ||
"enabled": false | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
|
||
#### Client-side On-Type Formatting | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And I documented client-side on-type formatting extensively including the TypeScript server configuration example and a demo. |
||
|
||
Not all language servers support the `textDocument/onTypeFormatting` feature. To provide an improved editor experience | ||
for users of those that do not, LSP4IJ includes support for _client-side on-type formatting_. Client-side on-type | ||
formatting can be enabled via client configuration with the following settings: | ||
|
||
* `format.onTypeFormatting.clientSide.formatOnCloseBrace` - When set to `true`, formatting is automatically applied when a close brace character is typed. Defaults to `false`. | ||
* `format.onTypeFormatting.clientSide.formatOnCloseBraceCharacters` - Specifies the exact characters that should treated as a close brace character for purposes of client-side on-type formatting. Defaults to the close brace characters for the language, typically `}`, `]`, and `)`. | ||
* `format.onTypeFormatting.clientSide.formatOnCloseBraceScope` - Specifies the scope that should be formatted when a close brace is typed. Valid values are `CODE_BLOCK` and `FILE`. Defaults to `CODE_BLOCK`. `FILE` is most useful for language servers that do not support range formatting or yield incorrect results for range formatting. | ||
* `format.onTypeFormatting.clientSide.formatOnStatementTerminator` - When set to `true`, formatting is automatically applied when a statement terminator character is typed. Defaults to `false`. | ||
* `format.onTypeFormatting.clientSide.formatOnStatementTerminatorCharacters` - Specifies the exact characters that should treated as a statement terminator character for purposes of client-side on-type formatting. Defaults to empty and must be specified if `formatOnStatementTerminator` is enabled. | ||
* `format.onTypeFormatting.clientSide.formatOnStatementTerminatorScope` - Specifies the scope that should be formatted when a statement terminator is typed. Valid values are `STATEMENT`, `CODE_BLOCK` and `FILE`. Defaults to `STATEMENT`. The other values are most useful for language servers that do not support range formatting or yield incorrect results for range formatting. | ||
* `format.onTypeFormatting.clientSide.formatOnCompletionTrigger` - When set to `true`, formatting is automatically applied when a completion trigger character is typed. Defaults to `false`. | ||
* `format.onTypeFormatting.clientSide.formatOnCompletionTriggerCharacters` - Specifies the exact characters that should treated as a completion trigger character for purposes of client-side on-type formatting. Defaults to the completion trigger characters specified by the language server. | ||
* Note that there is no configurable scope for completion trigger-based formatting. Exactly the type completion trigger character is formatted. As above, support for this may vary by language server. | ||
|
||
For example, the [TypeScript Language Server](./user-defined-ls/typescript-language-server.md) does not support server-side on-type formatting, but client-side | ||
on-type formatting is included in its language server configuration template as: | ||
|
||
```json | ||
{ | ||
"format": { | ||
"onTypeFormatting": { | ||
"clientSide": { | ||
"formatOnCloseBrace": true, | ||
"formatOnStatementTerminator": true, | ||
"formatOnStatementTerminatorCharacters": ";", | ||
"formatOnCompletionTrigger": true | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
|
||
Here is an example for client-side on-type formatting with that configuration showing automatic indentation of a | ||
statement continuation when the completion trigger character `.` is typed and automatic formatting of an entire code | ||
block when the closing brace character `}` is typed for a surrounding conditional statement: | ||
|
||
 | ||
|
||
#### Server-side / Client-side On-Type Formatting Relationship | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also wanted to call out the relationship between server-side and client-side on-type formatting if the former is available in the language server and enabled and the latter is also enabled in config. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks so much for having taken time to write this doc, it is excellent! |
||
|
||
If server-side on-type formatting is supported by the language server and enabled _and_ client-side on-type formatting | ||
is enabled for specific trigger characters, _only client-side on-type formatting will be applied_ when those specific | ||
trigger characters are typed. | ||
|
||
### Show Message | ||
|
||
[window/showMessage](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#window_showMessage) supports Markdown messages and clickable links. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -135,7 +135,7 @@ public void setServerCapabilities(@Nullable ServerCapabilities serverCapabilitie | |
} | ||
} | ||
|
||
// Client configuration settings | ||
// Server-side on-type formatting | ||
|
||
/** | ||
* Whether or not server-side on-type formatting is enabled if <code>textDocument/onTypeFormatting</code> is | ||
|
@@ -148,4 +148,123 @@ public boolean isOnTypeFormattingEnabled(@NotNull PsiFile file) { | |
// Default to enabled | ||
return true; | ||
} | ||
|
||
// Client-side on-type formatting | ||
|
||
/** | ||
* Supported formatting scopes. | ||
*/ | ||
public enum FormattingScope { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Part of the config of this feature is the scope to which formatting should be applied when an enabled key has been typed. Because some language servers may not report very good code blocks (CSS doesn't seem to), for example, it may be desirable to enable this feature so that the entire file is formatted properly when certain keys are typed. The default are detailed below for each aspect of the feature. |
||
/** | ||
* The current statement if one can be identified. | ||
*/ | ||
STATEMENT, | ||
/** | ||
* The current code block if one can be identified. | ||
*/ | ||
CODE_BLOCK, | ||
/** | ||
* The current file. | ||
*/ | ||
FILE | ||
} | ||
|
||
/** | ||
* Whether or not to format on close brace using client-side on-type formatting. Defaults to false. | ||
* | ||
* @param file the file | ||
* @return true if the file should be formatted when close braces are typed; otherwise false | ||
*/ | ||
public boolean isFormatOnCloseBrace(@NotNull PsiFile file) { | ||
// Default to disabled | ||
return false; | ||
} | ||
|
||
/** | ||
* The specific close brace characters that should trigger client-side on-type formatting. | ||
* | ||
* @param file the file | ||
* @return the close brace characters that should trigger on-type formatting or null if the language's standard | ||
* close brace characters should be used | ||
*/ | ||
@Nullable | ||
public String getFormatOnCloseBraceCharacters(@NotNull PsiFile file) { | ||
// Default to the language's standard close brace characters | ||
return null; | ||
} | ||
|
||
/** | ||
* The scope that should be formatted using client-side on-type formatting when a close brace is typed. Allowed | ||
* values are {@link FormattingScope#CODE_BLOCK CODE_BLOCK} and {@link FormattingScope#FILE FILE}. Defaults to | ||
* {@link FormattingScope#CODE_BLOCK CODE_BLOCK}. | ||
* | ||
* @param file the file | ||
* @return the format scope | ||
*/ | ||
@NotNull | ||
public FormattingScope getFormatOnCloseBraceScope(@NotNull PsiFile file) { | ||
// Default to CODE_BLOCK | ||
return FormattingScope.CODE_BLOCK; | ||
} | ||
|
||
/** | ||
* Whether or not to format on statement terminator using client-side on-type formatting. Defaults to false. | ||
* | ||
* @param file the file | ||
* @return true if the file should be formatted when statement terminators are typed; otherwise false | ||
*/ | ||
public boolean isFormatOnStatementTerminator(@NotNull PsiFile file) { | ||
// Default to disabled | ||
return false; | ||
} | ||
|
||
/** | ||
* The specific statement terminator characters that should trigger client-side on-type formatting. | ||
* | ||
* @param file the file | ||
* @return the statement terminator characters that should trigger on-type formatting | ||
*/ | ||
@Nullable | ||
public String getFormatOnStatementTerminatorCharacters(@NotNull PsiFile file) { | ||
// Default to none | ||
return null; | ||
} | ||
|
||
/** | ||
* The scope that should be formatted using client-side on-type formatting when a statement terminator is typed. | ||
* Allowed values are {@link FormattingScope#STATEMENT STATEMENT}, {@link FormattingScope#CODE_BLOCK CODE_BLOCK}, | ||
* and {@link FormattingScope#FILE FILE}. Defaults to {@link FormattingScope#STATEMENT STATEMENT}. | ||
* | ||
* @param file the file | ||
* @return the format scope | ||
*/ | ||
@NotNull | ||
public FormattingScope getFormatOnStatementTerminatorScope(@NotNull PsiFile file) { | ||
// Default to STATEMENT | ||
return FormattingScope.STATEMENT; | ||
} | ||
|
||
/** | ||
* Whether or not to format using client-side on-type formatting on completion trigger. Defaults to false. | ||
* | ||
* @param file the file | ||
* @return true if the file should be formatted when completion triggers are typed; otherwise false | ||
*/ | ||
public boolean isFormatOnCompletionTrigger(@NotNull PsiFile file) { | ||
// Default to disabled | ||
return false; | ||
} | ||
|
||
/** | ||
* The specific completion trigger characters that should trigger client-side on-type formatting. | ||
* | ||
* @param file the file | ||
* @return the completion trigger characters that should trigger on-type formatting or null if the language's | ||
* standard completion trigger characters should be used | ||
*/ | ||
@Nullable | ||
public String getFormatOnCompletionTriggerCharacters(@NotNull PsiFile file) { | ||
// Default to the language's standard completion trigger characters | ||
return null; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are the new client configuration options for client-side on-type formatting.