From da6dc0f471df4cecf567fb02c55ffdc896478463 Mon Sep 17 00:00:00 2001 From: Henry Chu Date: Fri, 26 Jan 2024 21:52:15 +0800 Subject: [PATCH 1/2] Add formatting options --- .../kotlin/org/javacs/kt/Configuration.kt | 15 ++++++- .../javacs/kt/KotlinTextDocumentService.kt | 7 ++-- .../org/javacs/kt/KotlinWorkspaceService.kt | 16 ++++++++ .../org/javacs/kt/formatting/Formatter.kt | 41 +++++++++++++------ .../javacs/kt/formatting/KtFmtFormatter.kt | 28 +++++++++++++ 5 files changed, 91 insertions(+), 16 deletions(-) create mode 100644 server/src/main/kotlin/org/javacs/kt/formatting/KtFmtFormatter.kt diff --git a/server/src/main/kotlin/org/javacs/kt/Configuration.kt b/server/src/main/kotlin/org/javacs/kt/Configuration.kt index ad3db4bb7..4439b61e8 100644 --- a/server/src/main/kotlin/org/javacs/kt/Configuration.kt +++ b/server/src/main/kotlin/org/javacs/kt/Configuration.kt @@ -57,6 +57,18 @@ data class InlayHintsConfiguration( var chainedHints: Boolean = false ) +data class KtFmtConfiguration( + var style: String = "google", + var indent: Int = 4, + var maxWidth: Int = 100, + var continuationIndent: Int = 8, + var removeUnusedImports: Boolean = true, +) + +data class FormattingConfiguration( + var formatter: String = "ktfmt", + var ktFmt: KtFmtConfiguration = KtFmtConfiguration() +) fun getStoragePath(params: InitializeParams): Path? { params.initializationOptions?.let { initializationOptions -> @@ -94,5 +106,6 @@ public data class Configuration( val scripts: ScriptsConfiguration = ScriptsConfiguration(), val indexing: IndexingConfiguration = IndexingConfiguration(), val externalSources: ExternalSourcesConfiguration = ExternalSourcesConfiguration(), - val inlayHints: InlayHintsConfiguration = InlayHintsConfiguration() + val inlayHints: InlayHintsConfiguration = InlayHintsConfiguration(), + val formatting: FormattingConfiguration = FormattingConfiguration(), ) diff --git a/server/src/main/kotlin/org/javacs/kt/KotlinTextDocumentService.kt b/server/src/main/kotlin/org/javacs/kt/KotlinTextDocumentService.kt index cbacca589..2ec1e5227 100644 --- a/server/src/main/kotlin/org/javacs/kt/KotlinTextDocumentService.kt +++ b/server/src/main/kotlin/org/javacs/kt/KotlinTextDocumentService.kt @@ -8,7 +8,7 @@ import org.javacs.kt.codeaction.codeActions import org.javacs.kt.completion.completions import org.javacs.kt.definition.goToDefinition import org.javacs.kt.diagnostic.convertDiagnostic -import org.javacs.kt.formatting.formatKotlinCode +import org.javacs.kt.formatting.FormattingService import org.javacs.kt.hover.hoverAt import org.javacs.kt.position.offset import org.javacs.kt.position.extractRange @@ -45,6 +45,7 @@ class KotlinTextDocumentService( ) : TextDocumentService, Closeable { private lateinit var client: LanguageClient private val async = AsyncExecutor() + private val formattingService = FormattingService(config.formatting) var debounceLint = Debouncer(Duration.ofMillis(config.diagnostics.debounceTime)) val lintTodo = mutableSetOf() @@ -139,7 +140,7 @@ class KotlinTextDocumentService( val code = extractRange(params.textDocument.content, params.range) listOf(TextEdit( params.range, - formatKotlinCode(code, params.options) + formattingService.formatKotlinCode(code, params.options) )) } @@ -215,7 +216,7 @@ class KotlinTextDocumentService( LOG.info("Formatting {}", describeURI(params.textDocument.uri)) listOf(TextEdit( Range(Position(0, 0), position(code, code.length)), - formatKotlinCode(code, params.options) + formattingService.formatKotlinCode(code, params.options) )) } diff --git a/server/src/main/kotlin/org/javacs/kt/KotlinWorkspaceService.kt b/server/src/main/kotlin/org/javacs/kt/KotlinWorkspaceService.kt index 6b89473e4..4e6a28e47 100644 --- a/server/src/main/kotlin/org/javacs/kt/KotlinWorkspaceService.kt +++ b/server/src/main/kotlin/org/javacs/kt/KotlinWorkspaceService.kt @@ -103,6 +103,22 @@ class KotlinWorkspaceService( } } + // Update options for formatting + get("formatting")?.asJsonObject?.apply { + val formatting = config.formatting + get("formatter")?.asString?.let { + formatting.formatter = it + } + get("ktfmt")?.asJsonObject?.apply { + val ktfmt = formatting.ktFmt + get("style")?.asString?.let { ktfmt.style = it } + get("indent")?.asInt?.let { ktfmt.indent = it } + get("maxWidth")?.asInt?.let { ktfmt.maxWidth = it } + get("continuationIndent")?.asInt?.let { ktfmt.continuationIndent = it } + get("removeUnusedImports")?.asBoolean?.let { ktfmt.removeUnusedImports = it } + } + } + // Update options for inlay hints get("inlayHints")?.asJsonObject?.apply { val inlayHints = config.inlayHints diff --git a/server/src/main/kotlin/org/javacs/kt/formatting/Formatter.kt b/server/src/main/kotlin/org/javacs/kt/formatting/Formatter.kt index d0a5a5362..464b51d8b 100644 --- a/server/src/main/kotlin/org/javacs/kt/formatting/Formatter.kt +++ b/server/src/main/kotlin/org/javacs/kt/formatting/Formatter.kt @@ -1,14 +1,31 @@ package org.javacs.kt.formatting -import com.facebook.ktfmt.format.Formatter -import com.facebook.ktfmt.format.FormattingOptions as KtfmtOptions -import org.eclipse.lsp4j.FormattingOptions - -fun formatKotlinCode( - code: String, - options: FormattingOptions = FormattingOptions(4, true) -): String = Formatter.format(KtfmtOptions( - style = KtfmtOptions.Style.GOOGLE, - blockIndent = options.tabSize, - continuationIndent = 2 * options.tabSize -), code) +import org.javacs.kt.Configuration +import org.javacs.kt.FormattingConfiguration +import org.eclipse.lsp4j.FormattingOptions as LspFromattingOptions + +private const val DEFAULT_INDENT = 4 + +class FormattingService(private val config: FormattingConfiguration) { + + private val formatter: Formatter get() = when (config.formatter) { + "ktfmt" -> KtFmtFormatter(config.ktFmt) + "none" -> NopFormatter + else -> KtFmtFormatter(config.ktFmt) + } + + fun formatKotlinCode( + code: String, + options: LspFromattingOptions = LspFromattingOptions(DEFAULT_INDENT, true) + ): String = this.formatter.format(code, options) +} + + +interface Formatter { + fun format(code: String, options: LspFromattingOptions): String +} + +object NopFormatter : Formatter { + override fun format(code: String, options: LspFromattingOptions): String = code +} + diff --git a/server/src/main/kotlin/org/javacs/kt/formatting/KtFmtFormatter.kt b/server/src/main/kotlin/org/javacs/kt/formatting/KtFmtFormatter.kt new file mode 100644 index 000000000..ad1ffe574 --- /dev/null +++ b/server/src/main/kotlin/org/javacs/kt/formatting/KtFmtFormatter.kt @@ -0,0 +1,28 @@ +package org.javacs.kt.formatting + +import org.javacs.kt.KtFmtConfiguration +import com.facebook.ktfmt.format.Formatter as KtFmt +import com.facebook.ktfmt.format.FormattingOptions as KtfmtOptions +import org.eclipse.lsp4j.FormattingOptions as LspFormattingOptions + +class KtFmtFormatter(private val config: KtFmtConfiguration) : Formatter { + override fun format( + code: String, + options: LspFormattingOptions, + ): String { + val style = when (config.style) { + "google" -> KtfmtOptions.Style.GOOGLE + "facebook" -> KtfmtOptions.Style.FACEBOOK + "dropbox" -> KtfmtOptions.Style.DROPBOX + else -> KtfmtOptions.Style.GOOGLE + } + return KtFmt.format(KtfmtOptions( + style = style, + maxWidth = config.maxWidth, + blockIndent = options.tabSize.takeUnless { it == 0 } ?: config.indent, + continuationIndent = config.continuationIndent, + removeUnusedImports = config.removeUnusedImports, + ), code) + } +} + From 3aca373e289fd0a1bc84df6f6686b3c70c546b37 Mon Sep 17 00:00:00 2001 From: Henry Chu Date: Tue, 20 Feb 2024 09:45:30 +0800 Subject: [PATCH 2/2] refactorings to formatting --- .../kotlin/org/javacs/kt/Configuration.kt | 4 ++-- .../org/javacs/kt/KotlinWorkspaceService.kt | 2 +- .../org/javacs/kt/formatting/Formatter.kt | 23 ------------------- .../javacs/kt/formatting/FormattingService.kt | 21 +++++++++++++++++ .../{KtFmtFormatter.kt => KtfmtFormatter.kt} | 8 +++---- .../org/javacs/kt/formatting/NopFormatter.kt | 8 +++++++ 6 files changed, 36 insertions(+), 30 deletions(-) create mode 100644 server/src/main/kotlin/org/javacs/kt/formatting/FormattingService.kt rename server/src/main/kotlin/org/javacs/kt/formatting/{KtFmtFormatter.kt => KtfmtFormatter.kt} (80%) create mode 100644 server/src/main/kotlin/org/javacs/kt/formatting/NopFormatter.kt diff --git a/server/src/main/kotlin/org/javacs/kt/Configuration.kt b/server/src/main/kotlin/org/javacs/kt/Configuration.kt index 4439b61e8..13774c38e 100644 --- a/server/src/main/kotlin/org/javacs/kt/Configuration.kt +++ b/server/src/main/kotlin/org/javacs/kt/Configuration.kt @@ -57,7 +57,7 @@ data class InlayHintsConfiguration( var chainedHints: Boolean = false ) -data class KtFmtConfiguration( +data class KtfmtConfiguration( var style: String = "google", var indent: Int = 4, var maxWidth: Int = 100, @@ -67,7 +67,7 @@ data class KtFmtConfiguration( data class FormattingConfiguration( var formatter: String = "ktfmt", - var ktFmt: KtFmtConfiguration = KtFmtConfiguration() + var ktfmt: KtfmtConfiguration = KtfmtConfiguration() ) fun getStoragePath(params: InitializeParams): Path? { diff --git a/server/src/main/kotlin/org/javacs/kt/KotlinWorkspaceService.kt b/server/src/main/kotlin/org/javacs/kt/KotlinWorkspaceService.kt index 4e6a28e47..82ec771bd 100644 --- a/server/src/main/kotlin/org/javacs/kt/KotlinWorkspaceService.kt +++ b/server/src/main/kotlin/org/javacs/kt/KotlinWorkspaceService.kt @@ -110,7 +110,7 @@ class KotlinWorkspaceService( formatting.formatter = it } get("ktfmt")?.asJsonObject?.apply { - val ktfmt = formatting.ktFmt + val ktfmt = formatting.ktfmt get("style")?.asString?.let { ktfmt.style = it } get("indent")?.asInt?.let { ktfmt.indent = it } get("maxWidth")?.asInt?.let { ktfmt.maxWidth = it } diff --git a/server/src/main/kotlin/org/javacs/kt/formatting/Formatter.kt b/server/src/main/kotlin/org/javacs/kt/formatting/Formatter.kt index 464b51d8b..901942e0e 100644 --- a/server/src/main/kotlin/org/javacs/kt/formatting/Formatter.kt +++ b/server/src/main/kotlin/org/javacs/kt/formatting/Formatter.kt @@ -1,31 +1,8 @@ package org.javacs.kt.formatting -import org.javacs.kt.Configuration -import org.javacs.kt.FormattingConfiguration import org.eclipse.lsp4j.FormattingOptions as LspFromattingOptions -private const val DEFAULT_INDENT = 4 - -class FormattingService(private val config: FormattingConfiguration) { - - private val formatter: Formatter get() = when (config.formatter) { - "ktfmt" -> KtFmtFormatter(config.ktFmt) - "none" -> NopFormatter - else -> KtFmtFormatter(config.ktFmt) - } - - fun formatKotlinCode( - code: String, - options: LspFromattingOptions = LspFromattingOptions(DEFAULT_INDENT, true) - ): String = this.formatter.format(code, options) -} - - interface Formatter { fun format(code: String, options: LspFromattingOptions): String } -object NopFormatter : Formatter { - override fun format(code: String, options: LspFromattingOptions): String = code -} - diff --git a/server/src/main/kotlin/org/javacs/kt/formatting/FormattingService.kt b/server/src/main/kotlin/org/javacs/kt/formatting/FormattingService.kt new file mode 100644 index 000000000..97cc16bc9 --- /dev/null +++ b/server/src/main/kotlin/org/javacs/kt/formatting/FormattingService.kt @@ -0,0 +1,21 @@ +package org.javacs.kt.formatting + +import org.javacs.kt.Configuration +import org.javacs.kt.FormattingConfiguration +import org.eclipse.lsp4j.FormattingOptions as LspFromattingOptions + +private const val DEFAULT_INDENT = 4 + +class FormattingService(private val config: FormattingConfiguration) { + + private val formatter: Formatter get() = when (config.formatter) { + "ktfmt" -> KtfmtFormatter(config.ktfmt) + "none" -> NopFormatter + else -> KtfmtFormatter(config.ktfmt) + } + + fun formatKotlinCode( + code: String, + options: LspFromattingOptions = LspFromattingOptions(DEFAULT_INDENT, true) + ): String = this.formatter.format(code, options) +} diff --git a/server/src/main/kotlin/org/javacs/kt/formatting/KtFmtFormatter.kt b/server/src/main/kotlin/org/javacs/kt/formatting/KtfmtFormatter.kt similarity index 80% rename from server/src/main/kotlin/org/javacs/kt/formatting/KtFmtFormatter.kt rename to server/src/main/kotlin/org/javacs/kt/formatting/KtfmtFormatter.kt index ad1ffe574..5b4012fcb 100644 --- a/server/src/main/kotlin/org/javacs/kt/formatting/KtFmtFormatter.kt +++ b/server/src/main/kotlin/org/javacs/kt/formatting/KtfmtFormatter.kt @@ -1,11 +1,11 @@ package org.javacs.kt.formatting -import org.javacs.kt.KtFmtConfiguration -import com.facebook.ktfmt.format.Formatter as KtFmt +import org.javacs.kt.KtfmtConfiguration +import com.facebook.ktfmt.format.Formatter as Ktfmt import com.facebook.ktfmt.format.FormattingOptions as KtfmtOptions import org.eclipse.lsp4j.FormattingOptions as LspFormattingOptions -class KtFmtFormatter(private val config: KtFmtConfiguration) : Formatter { +class KtfmtFormatter(private val config: KtfmtConfiguration) : Formatter { override fun format( code: String, options: LspFormattingOptions, @@ -16,7 +16,7 @@ class KtFmtFormatter(private val config: KtFmtConfiguration) : Formatter { "dropbox" -> KtfmtOptions.Style.DROPBOX else -> KtfmtOptions.Style.GOOGLE } - return KtFmt.format(KtfmtOptions( + return Ktfmt.format(KtfmtOptions( style = style, maxWidth = config.maxWidth, blockIndent = options.tabSize.takeUnless { it == 0 } ?: config.indent, diff --git a/server/src/main/kotlin/org/javacs/kt/formatting/NopFormatter.kt b/server/src/main/kotlin/org/javacs/kt/formatting/NopFormatter.kt new file mode 100644 index 000000000..bd72856b5 --- /dev/null +++ b/server/src/main/kotlin/org/javacs/kt/formatting/NopFormatter.kt @@ -0,0 +1,8 @@ +package org.javacs.kt.formatting + +import org.eclipse.lsp4j.FormattingOptions as LspFormattingOptions + +object NopFormatter : Formatter { + override fun format(code: String, options: LspFormattingOptions): String = code +} +