Skip to content

Commit

Permalink
Redo coroutines
Browse files Browse the repository at this point in the history
  • Loading branch information
InSyncWithFoo committed Sep 2, 2024
1 parent c92dda9 commit 5ba4212
Show file tree
Hide file tree
Showing 11 changed files with 75 additions and 81 deletions.
5 changes: 5 additions & 0 deletions src/main/kotlin/insyncwithfoo/ryecharm/Editing.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ internal fun PsiFile.edit(callback: (Document) -> Unit) {
}


internal fun PsiFile.paste(newText: String) {
this.edit { it.replaceContentWith(newText) }
}


internal fun Document.replaceString(range: TextRange, value: String) {
replaceString(range.startOffset, range.endOffset, value)
}
Expand Down
6 changes: 6 additions & 0 deletions src/main/kotlin/insyncwithfoo/ryecharm/Progresses.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package insyncwithfoo.ryecharm

import com.intellij.openapi.application.EDT
import com.intellij.openapi.command.writeCommandAction
import com.intellij.openapi.project.Project
import com.intellij.platform.ide.progress.ModalTaskOwner
import com.intellij.platform.ide.progress.TaskCancellation
Expand Down Expand Up @@ -59,6 +60,11 @@ internal suspend fun <T> Project.runInBackground(
withBackgroundProgress(this, title, cancellable, action)


@Suppress("UnstableApiUsage")
internal suspend fun <T> Project.runWriteCommandAction(title: String, action: () -> T) =
writeCommandAction(this, title, action)


internal enum class ProgressContext(private val context: CoroutineContext) {
IO(Dispatchers.IO),
UI(Dispatchers.EDT);
Expand Down
16 changes: 0 additions & 16 deletions src/main/kotlin/insyncwithfoo/ryecharm/ruff/Coroutines.kt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ internal class OptimizeImportsCommand(
get() {
val arguments = mutableListOf(
"--fix", "--exit-zero", "--quiet",
"--select", "I",
"--select", "I,F401",
)

if (stdinFilename != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package insyncwithfoo.ryecharm.ruff.formatting

import com.intellij.lang.ImportOptimizer
import com.intellij.openapi.command.writeCommandAction
import com.intellij.openapi.editor.Document
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.toNioPathOrNull
import com.intellij.psi.PsiFile
Expand All @@ -11,10 +11,21 @@ import insyncwithfoo.ryecharm.configurations.ruff.ruffConfigurations
import insyncwithfoo.ryecharm.isSupportedByRuff
import insyncwithfoo.ryecharm.message
import insyncwithfoo.ryecharm.notifyIfProcessIsUnsuccessfulOr
import insyncwithfoo.ryecharm.psiDocumentManager
import insyncwithfoo.ryecharm.paste
import insyncwithfoo.ryecharm.ruff.commands.ruff
import insyncwithfoo.ryecharm.ruff.runFormattingOperation
import insyncwithfoo.ryecharm.runInBackground
import insyncwithfoo.ryecharm.runWriteCommandAction
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch


@Service(Service.Level.PROJECT)
private class RuffImportOptimizerCoroutine(val scope: CoroutineScope)


private fun Project.runTask(action: suspend CoroutineScope.() -> Unit) {
service<RuffImportOptimizerCoroutine>().scope.launch(block = action)
}


internal class RuffImportOptimizer : ImportOptimizer {
Expand All @@ -30,29 +41,24 @@ internal class RuffImportOptimizer : ImportOptimizer {
val document = viewProvider.document ?: return null
val path = virtualFile?.toNioPathOrNull()

val command = ruff.optimizeImports(document.text, path)

return Runnable {
project.optimizeImportsAndLoadResult(command, document)
val command = ruff.optimizeImports(document.text, path)
project.runCommandAndLoadResult(command, this)
}
}

private fun Project.optimizeImportsAndLoadResult(command: Command, document: Document) = runFormattingOperation {
private fun Project.runCommandAndLoadResult(command: Command, file: PsiFile) = runTask {
val output = runInBackground(command)
val newText = output.stdout

notifyIfProcessIsUnsuccessfulOr(command, output) {
if (!newText.contentEquals(document.charsSequence)) {
writeNewTextBack(document, output.stdout)
}
writeNewTextBack(file, newText)
}
}

@Suppress("UnstableApiUsage", "DialogTitleCapitalization")
private fun Project.writeNewTextBack(document: Document, newText: String) = runFormattingOperation {
writeCommandAction(this@writeNewTextBack, message("progresses.command.ruff.optimizeImports")) {
document.replaceString(0, document.textLength, newText)
psiDocumentManager.commitDocument(document)
private fun Project.writeNewTextBack(file: PsiFile, newText: String) = runTask {
runWriteCommandAction(message("progresses.command.ruff.optimizeImports")) {
file.paste(newText)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,34 @@
package insyncwithfoo.ryecharm.ruff.formatting

import com.intellij.openapi.command.writeCommandAction
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.editor.Document
import com.intellij.openapi.fileEditor.FileDocumentManagerListener
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.toNioPathOrNull
import com.intellij.psi.PsiFile
import insyncwithfoo.ryecharm.Command
import insyncwithfoo.ryecharm.configurations.ruff.ruffConfigurations
import insyncwithfoo.ryecharm.isSupportedByRuff
import insyncwithfoo.ryecharm.message
import insyncwithfoo.ryecharm.notifyIfProcessIsUnsuccessfulOr
import insyncwithfoo.ryecharm.paste
import insyncwithfoo.ryecharm.psiDocumentManager
import insyncwithfoo.ryecharm.ruff.commands.ruff
import insyncwithfoo.ryecharm.ruff.runFormattingOperation
import insyncwithfoo.ryecharm.runInBackground
import insyncwithfoo.ryecharm.runWriteCommandAction
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch


@Service(Service.Level.PROJECT)
private class RuffOnSaveFormatterCoroutine(val scope: CoroutineScope)


private fun Project.runTask(action: suspend CoroutineScope.() -> Unit) {
service<RuffOnSaveFormatterCoroutine>().scope.launch(block = action)
}


// TODO: Use com.intellij.openapi.roots.ProjectFileIndex.isInProject
Expand All @@ -27,6 +41,7 @@ internal class RuffOnSaveFormatter(private val project: Project) : FileDocumentM
override fun beforeDocumentSaving(document: Document) {
val file = project.psiDocumentManager.getPsiFile(document) ?: return
val virtualFile = file.virtualFile
val path = virtualFile?.toNioPathOrNull()
val configurations = project.ruffConfigurations

when {
Expand All @@ -37,27 +52,23 @@ internal class RuffOnSaveFormatter(private val project: Project) : FileDocumentM
}

val ruff = project.ruff ?: return
val command = ruff.format(document.text, virtualFile?.toNioPathOrNull())
val command = ruff.format(document.text, path)

project.runRuffFormatAndLoadResult(command, document)
project.runCommandAndLoadResult(command, file)
}

private fun Project.runRuffFormatAndLoadResult(command: Command, document: Document) = runFormattingOperation {
private fun Project.runCommandAndLoadResult(command: Command, file: PsiFile) = runTask {
val output = runInBackground(command)
val newText = output.stdout

notifyIfProcessIsUnsuccessfulOr(command, output) {
if (!newText.contentEquals(document.charsSequence)) {
writeNewTextBack(document, output.stdout)
}
writeNewTextBack(file, newText)
}
}

@Suppress("UnstableApiUsage")
private fun Project.writeNewTextBack(document: Document, newText: String) = runFormattingOperation {
writeCommandAction(this@writeNewTextBack, message("progresses.command.ruff.format")) {
document.replaceString(0, document.textLength, newText)
psiDocumentManager.commitDocument(document)
private fun Project.writeNewTextBack(file: PsiFile, newText: String) = runTask {
runWriteCommandAction(message("progresses.command.ruff.format")) {
file.paste(newText)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ internal class ShowProjectInformation : AnAction(), DumbAware {
val project = event.project ?: return noProjectFound()
val rye = project.rye ?: return project.unableToRunCommand()

project.runRyeShowAndShowOutput(rye)
project.runCommandAndShowOutput(rye)
}

private fun Project.runRyeShowAndShowOutput(rye: Rye) = runAction {
private fun Project.runCommandAndShowOutput(rye: Rye) = runAction {
val command = rye.show()

runInBackground(command) { output ->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
package insyncwithfoo.ryecharm.rye.intentions

import com.intellij.execution.process.ProcessOutput
import com.intellij.openapi.editor.Document
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiFile
import insyncwithfoo.ryecharm.Command
import insyncwithfoo.ryecharm.ExternalIntentionAction
import insyncwithfoo.ryecharm.ProgressContext
import insyncwithfoo.ryecharm.WriteIntentionAction
import insyncwithfoo.ryecharm.fileDocumentManager
import insyncwithfoo.ryecharm.isPyprojectToml
Expand All @@ -18,7 +15,6 @@ import insyncwithfoo.ryecharm.notifyIfProcessIsUnsuccessfulOr
import insyncwithfoo.ryecharm.processCompletedSuccessfully
import insyncwithfoo.ryecharm.runInForeground
import insyncwithfoo.ryecharm.runIntention
import insyncwithfoo.ryecharm.rye.commands.Rye
import insyncwithfoo.ryecharm.rye.commands.VersionBumpType
import insyncwithfoo.ryecharm.rye.commands.rye
import insyncwithfoo.ryecharm.unableToRunCommand
Expand All @@ -37,39 +33,26 @@ internal abstract class BumpProjectVersion(val bumpType: VersionBumpType) :
editor != null && file?.virtualFile?.isPyprojectToml == true

override fun invoke(project: Project, editor: Editor?, file: PsiFile?) {
val document = file!!.viewProvider.document ?: return
val rye = project.rye ?: return project.unableToRunCommand()
val command = rye.version(bumpType)

invoke(project, rye, file!!, editor!!.document)
}

private fun invoke(project: Project, rye: Rye, file: PsiFile, document: Document) {
fileDocumentManager.saveDocumentAsIs(document)

project.runIntention {
val command = rye.version(bumpType)

project.runInForeground(command) { output ->
file.virtualFile?.refresh()
project.handleOutput(command, output)
}
}
project.runCommandAndLoadOutput(command, file)
}

private suspend fun VirtualFile.refresh() {
private fun Project.runCommandAndLoadOutput(command: Command, file: PsiFile) = runIntention {
val output = runInForeground(command)
val (asynchronous, recursive) = Pair(false, false)

ProgressContext.IO.launch {
refresh(asynchronous, recursive)
}
}

private fun Project.handleOutput(command: Command, output: ProcessOutput) {
file.virtualFile?.refresh(asynchronous, recursive)

notifyIfProcessIsUnsuccessfulOr(command, output) {
extractNewVersionAndNotify(command, output)
notifyNewVersion(command, output)
}
}

private fun Project.extractNewVersionAndNotify(command: Command, output: ProcessOutput) {
private fun Project.notifyNewVersion(command: Command, output: ProcessOutput) {
val newVersion = extractNewVersion(output.stdout)
?: return unknownError(command, output)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ internal class ShowVersion : AnAction(), DumbAware {
val project = event.project ?: defaultProject
val uv = project.uv ?: return project.unableToRunCommand()

project.runUVVersionAndShowOutput(uv)
project.runCommandAndShowOutput(uv)
}

private fun Project.runUVVersionAndShowOutput(uv: UV) = runAction {
private fun Project.runCommandAndShowOutput(uv: UV) = runAction {
val command = uv.version()

runInBackground(command) { output ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,10 @@ internal class SynchronizeProject : AnAction(), ExternalIntentionAction, WriteIn

private fun Project.runUVSyncAndReport(uv: UV) = runIntention {
val command = uv.sync()
val output = runInBackground(command)

runInBackground(command) { output ->
notifyIfProcessIsUnsuccessfulOr(command, output) {
processCompletedSuccessfully(message("notifications.environmentSynchronized.body"))
}
notifyIfProcessIsUnsuccessfulOr(command, output) {
processCompletedSuccessfully(message("notifications.environmentSynchronized.body"))
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/messages/ryecharm.properties
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ configurations.ruff.logFile.label = Log file:
configurations.ruff.suggestExecutableOnProjectOpen.label = Project open
configurations.ruff.suggestExecutableOnPackagesChange.label = Packages change

configurations.ruff.autoRestartServers.label = Automatically restart server on configuration change
configurations.ruff.autoRestartServers.label = Automatically restart servers on configuration change

######################################## endregion

Expand Down

0 comments on commit 5ba4212

Please sign in to comment.