1
1
package com.koxudaxi.ruff
2
2
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
7
3
import com.intellij.formatting.FormattingContext
8
4
import com.intellij.formatting.service.AsyncDocumentFormattingService
9
5
import com.intellij.formatting.service.AsyncFormattingRequest
10
6
import com.intellij.formatting.service.FormattingService
11
- import com.intellij.openapi.project.Project
7
+ import com.intellij.openapi.progress.ProcessCanceledException
12
8
import com.intellij.psi.PsiFile
13
- import java.nio.charset.StandardCharsets
14
9
import java.util.*
15
10
16
11
17
- abstract class RuffAsyncFormatterBase : AsyncDocumentFormattingService () {
18
- abstract fun isEnabled (project : Project ): Boolean
19
- abstract fun getArgs (project : Project ): List <String >
12
+ class RuffAsyncFormatter : AsyncDocumentFormattingService () {
20
13
private val FEATURES : MutableSet <FormattingService .Feature > = EnumSet .noneOf(
21
14
FormattingService .Feature ::class .java
22
15
)
@@ -26,54 +19,66 @@ abstract class RuffAsyncFormatterBase : AsyncDocumentFormattingService() {
26
19
}
27
20
28
21
override fun canFormat (file : PsiFile ): Boolean {
29
- return isEnabled (file.project) && file.isApplicableTo
22
+ return RuffConfigService .getInstance (file.project).runRuffOnReformatCode && file.isApplicableTo
30
23
}
31
-
32
24
override fun createFormattingTask (request : AsyncFormattingRequest ): FormattingTask ? {
33
25
val formattingContext: FormattingContext = request.context
34
26
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)
59
33
}
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)
60
57
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
+ }
64
65
}
66
+ }
67
+ override fun cancel (): Boolean {
68
+ return true
69
+ }
65
70
66
- override fun isRunUnderProgress (): Boolean {
67
- return true
68
- }
71
+ override fun isRunUnderProgress (): Boolean {
72
+ return true
69
73
}
70
- } catch (e: ExecutionException ) {
71
- e.message?.let { request.onError(" Ruff Error" , it) }
72
- return null
73
74
}
74
75
}
75
76
76
77
override fun getNotificationGroupId (): String {
77
78
return " Ruff"
78
79
}
80
+
81
+ override fun getName (): String {
82
+ return " Ruff Formatter"
83
+ }
79
84
}
0 commit comments