Skip to content

Commit d482c45

Browse files
authored
Merge pull request #518 from koxudaxi/fix_ruff_formatter
Improve RuffAsyncFormatter
2 parents 8e69879 + 67045f6 commit d482c45

8 files changed

+57
-78
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Changelog
22

33
## [Unreleased]
4+
- Improve RuffAsyncFormatter [[#518](https://github.com/koxudaxi/ruff-pycharm-plugin/pull/518)]
45

56
## [0.0.40] - 2024-09-18
67

gradle.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ pluginGroup = com.koxudaxi.ruff
44
pluginName = Ruff
55
pluginRepositoryUrl = https://github.com/koxudaxi/ruff-pycharm-plugin
66
# SemVer format -> https://semver.org
7-
pluginVersion = 0.0.40
7+
pluginVersion = 0.0.41
88

99
# Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
1010
pluginSinceBuild = 242.20224.89

resources/META-INF/plugin.xml

+1-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
enabledByDefault="true" level="WARNING"
1717
implementationClass="com.koxudaxi.ruff.RuffInspection"/>
1818
<externalAnnotator language="Python" implementationClass="com.koxudaxi.ruff.RuffExternalAnnotator"/>
19-
<formattingService implementation="com.koxudaxi.ruff.RuffAsyncFixFormatter"/>
20-
<formattingService implementation="com.koxudaxi.ruff.RuffAsyncFormatFormatter" order="last"/>
19+
<formattingService implementation="com.koxudaxi.ruff.RuffAsyncFormatter"/>
2120
<platform.backend.documentation.targetProvider
2221
implementation="com.koxudaxi.ruff.RuffNoqaDocumentationTargetProvider"/>
2322
<actionOnSave id="BlackFormatterActionOnSave" implementation="com.koxudaxi.ruff.RuffActionOnSave" order="last"/>

src/com/koxudaxi/ruff/Ruff.kt

+4-4
Original file line numberDiff line numberDiff line change
@@ -268,9 +268,9 @@ fun isInspectionEnabled(project: Project): Boolean {
268268
return inspectionProfileManager.currentProfile.isToolEnabled(toolWrapper.displayKey)
269269
}
270270
fun runCommand(
271-
commandArgs: CommandArgs
271+
commandArgs: CommandArgs, stdin: ByteArray? = null
272272
): String? = runCommand(
273-
commandArgs.executable, commandArgs.project, commandArgs.stdin, *commandArgs.args.toTypedArray()
273+
commandArgs.executable, commandArgs.project, if (stdin is ByteArray) stdin else commandArgs.stdin, *commandArgs.args.toTypedArray()
274274
)
275275

276276
private fun getGeneralCommandLine(command: List<String>, projectPath: String?): GeneralCommandLine =
@@ -430,9 +430,9 @@ enum class NewArgument(val argument: String) {
430430
open class UnexpectedArgumentException(argument: String) : ExecutionException("Unexpected argument: $argument")
431431
class UnexpectedNewArgumentException(newArgument: NewArgument) : UnexpectedArgumentException(newArgument.argument)
432432

433-
fun runRuff(commandArgs: CommandArgs): String? {
433+
fun runRuff(commandArgs: CommandArgs, stdin: ByteArray? = null): String? {
434434
return try {
435-
runCommand(commandArgs)
435+
runCommand(commandArgs, stdin)
436436
} catch (_: RunCanceledByUserException) {
437437
null
438438
} catch (_: TOMLParseException) {

src/com/koxudaxi/ruff/RuffApplyService.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class RuffApplyService(val project: Project) {
3535
}
3636
}
3737
}
38-
38+
val actionName = "Formatting with Ruff"
3939
fun apply(document: Document, sourceFile: SourceFile, withFormat: Boolean) {
4040
val checkedFixed = runReadActionOnPooledThread(null) {
4141
val fixed = runRuff(sourceFile, project.FIX_ARGS)

src/com/koxudaxi/ruff/RuffAsyncFixFormatter.kt

-12
This file was deleted.

src/com/koxudaxi/ruff/RuffAsyncFormatFormatter.kt

-14
This file was deleted.
+49-44
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,15 @@
11
package com.koxudaxi.ruff
22

3-
import com.intellij.execution.ExecutionException
4-
import com.intellij.execution.process.CapturingProcessAdapter
5-
import com.intellij.execution.process.OSProcessHandler
6-
import com.intellij.execution.process.ProcessEvent
73
import com.intellij.formatting.FormattingContext
84
import com.intellij.formatting.service.AsyncDocumentFormattingService
95
import com.intellij.formatting.service.AsyncFormattingRequest
106
import com.intellij.formatting.service.FormattingService
11-
import com.intellij.openapi.project.Project
7+
import com.intellij.openapi.progress.ProcessCanceledException
128
import com.intellij.psi.PsiFile
13-
import java.nio.charset.StandardCharsets
149
import java.util.*
1510

1611

17-
abstract class RuffAsyncFormatterBase : AsyncDocumentFormattingService() {
18-
abstract fun isEnabled(project: Project): Boolean
19-
abstract fun getArgs(project: Project): List<String>
12+
class RuffAsyncFormatter : AsyncDocumentFormattingService() {
2013
private val FEATURES: MutableSet<FormattingService.Feature> = EnumSet.noneOf(
2114
FormattingService.Feature::class.java
2215
)
@@ -26,54 +19,66 @@ abstract class RuffAsyncFormatterBase : AsyncDocumentFormattingService() {
2619
}
2720

2821
override fun canFormat(file: PsiFile): Boolean {
29-
return isEnabled(file.project) && file.isApplicableTo
22+
return RuffConfigService.getInstance(file.project).runRuffOnReformatCode && file.isApplicableTo
3023
}
31-
3224
override fun createFormattingTask(request: AsyncFormattingRequest): FormattingTask? {
3325
val formattingContext: FormattingContext = request.context
3426
val ioFile = request.ioFile ?: return null
35-
val sourceFile = formattingContext.containingFile.sourceFile
36-
val commandArgs = generateCommandArgs(sourceFile, getArgs(formattingContext.project)) ?: return null
37-
try {
38-
val commandLine =
39-
getGeneralCommandLine(commandArgs.executable, commandArgs.project, *commandArgs.args.toTypedArray())
40-
?: return null
41-
val handler = OSProcessHandler(commandLine.withCharset(StandardCharsets.UTF_8))
42-
with(handler) {
43-
processInput.write(ioFile.readText().toByteArray())
44-
processInput.close()
45-
}
46-
return object : FormattingTask {
47-
override fun run() {
48-
handler.addProcessListener(object : CapturingProcessAdapter() {
49-
override fun processTerminated(event: ProcessEvent) {
50-
val exitCode = event.exitCode
51-
if (exitCode == 0) {
52-
request.onTextReady(output.stdout)
53-
} else {
54-
request.onError("Ruff Error", output.stderr)
55-
}
56-
}
57-
})
58-
handler.startNotify()
27+
return object : FormattingTask {
28+
private fun updateText(currentText: String, text: String?) {
29+
when {
30+
text == null -> request.onTextReady(null)
31+
currentText == text -> request.onTextReady(null)
32+
else -> request.onTextReady(text)
5933
}
34+
}
35+
override fun run() {
36+
runCatching {
37+
val sourceFile = formattingContext.containingFile.sourceFile
38+
val fixCommandArgs =
39+
generateCommandArgs(sourceFile, formattingContext.project.FIX_ARGS) ?: return@runCatching
40+
val currentText = ioFile.readText()
41+
val fixCommandStdout = runRuff(fixCommandArgs, currentText.toByteArray())
42+
if (fixCommandStdout == null) {
43+
request.onTextReady(null)
44+
return@runCatching
45+
}
46+
if (!RuffConfigService.getInstance(formattingContext.project).useRuffFormat) {
47+
updateText(currentText, fixCommandStdout)
48+
return@runCatching
49+
}
50+
val formatCommandArgs = generateCommandArgs(sourceFile, FORMAT_ARGS)
51+
if (formatCommandArgs == null) {
52+
updateText(currentText, fixCommandStdout)
53+
return@runCatching
54+
}
55+
val formatCommandStdout = runRuff(formatCommandArgs, fixCommandStdout.toByteArray())
56+
updateText(currentText, formatCommandStdout)
6057

61-
override fun cancel(): Boolean {
62-
handler.destroyProcess()
63-
return true
58+
}.onFailure { exception ->
59+
when (exception) {
60+
is ProcessCanceledException -> { /* ignore */ }
61+
else -> {
62+
request.onError("Ruff Error", exception.localizedMessage)
63+
}
64+
}
6465
}
66+
}
67+
override fun cancel(): Boolean {
68+
return true
69+
}
6570

66-
override fun isRunUnderProgress(): Boolean {
67-
return true
68-
}
71+
override fun isRunUnderProgress(): Boolean {
72+
return true
6973
}
70-
} catch (e: ExecutionException) {
71-
e.message?.let { request.onError("Ruff Error", it) }
72-
return null
7374
}
7475
}
7576

7677
override fun getNotificationGroupId(): String {
7778
return "Ruff"
7879
}
80+
81+
override fun getName(): String {
82+
return "Ruff Formatter"
83+
}
7984
}

0 commit comments

Comments
 (0)