diff --git a/Src/CSharpier.Rider/CHANGELOG.md b/Src/CSharpier.Rider/CHANGELOG.md
index 214e64bd1..6bd207040 100644
--- a/Src/CSharpier.Rider/CHANGELOG.md
+++ b/Src/CSharpier.Rider/CHANGELOG.md
@@ -2,6 +2,9 @@
# csharpier-rider Changelog
+## [1.3.9]
+- Wait at most 3 seconds for csharpier to format otherwise consider it hung and restart it.
+
## [1.3.8]
- Add displayName attribute to CSharpier options window to speed up Settings dialog.
diff --git a/Src/CSharpier.Rider/README.md b/Src/CSharpier.Rider/README.md
index a6c0b30a9..2f9f30209 100644
--- a/Src/CSharpier.Rider/README.md
+++ b/Src/CSharpier.Rider/README.md
@@ -11,7 +11,6 @@ To use it:
- Optionally configure CSharpier to `Run on Save` under Preferences/Settings | Tools | CSharpier
Please report any [issues](https://github.com/belav/csharpier/issues)
-
## Installation
@@ -20,7 +19,6 @@ Please report any [issues](https://github.com/belav/csharpier/issues)
Settings/Preferences > Plugins > Marketplace > Search for "CSharpier" >
Install Plugin
---
-Plugin based on the [IntelliJ Platform Plugin Template][template].
## Troubleshooting
@@ -33,3 +31,5 @@ Plugin based on the [IntelliJ Platform Plugin Template][template].
- Add entry for "#com.intellij.csharpier.CSharpierLogger"
- Restart Rider
+
+
diff --git a/Src/CSharpier.Rider/gradle.properties b/Src/CSharpier.Rider/gradle.properties
index b6032d139..f039a371f 100644
--- a/Src/CSharpier.Rider/gradle.properties
+++ b/Src/CSharpier.Rider/gradle.properties
@@ -4,7 +4,7 @@
pluginGroup = com.intellij.csharpier
pluginName = csharpier
# SemVer format -> https://semver.org
-pluginVersion = 1.3.8
+pluginVersion = 1.3.9
# See https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
# for insight into build numbers and IntelliJ Platform versions.
diff --git a/Src/CSharpier.Rider/src/main/java/com/intellij/csharpier/CSharpierProcessPipeMultipleFiles.java b/Src/CSharpier.Rider/src/main/java/com/intellij/csharpier/CSharpierProcessPipeMultipleFiles.java
index c601b6361..d8c8ce2e0 100644
--- a/Src/CSharpier.Rider/src/main/java/com/intellij/csharpier/CSharpierProcessPipeMultipleFiles.java
+++ b/Src/CSharpier.Rider/src/main/java/com/intellij/csharpier/CSharpierProcessPipeMultipleFiles.java
@@ -15,6 +15,8 @@
import java.util.concurrent.atomic.AtomicBoolean;
public class CSharpierProcessPipeMultipleFiles implements ICSharpierProcess, Disposable {
+ private final boolean useUtf8;
+ private final String csharpierPath;
Logger logger = CSharpierLogger.getInstance();
Process process = null;
@@ -22,12 +24,18 @@ public class CSharpierProcessPipeMultipleFiles implements ICSharpierProcess, Dis
BufferedReader stdOut;
public CSharpierProcessPipeMultipleFiles(String csharpierPath, boolean useUtf8) {
+ this.csharpierPath = csharpierPath;
+ this.useUtf8 = useUtf8;
+ this.startProcess();
+ }
+
+ private void startProcess() {
try {
- var processBuilder = new ProcessBuilder(csharpierPath, "--pipe-multiple-files");
+ var processBuilder = new ProcessBuilder(this.csharpierPath, "--pipe-multiple-files");
processBuilder.environment().put("DOTNET_NOLOGO", "1");
this.process = processBuilder.start();
- var charset = useUtf8 ? "utf-8" : Charset.defaultCharset().toString();
+ var charset = this.useUtf8 ? "utf-8" : Charset.defaultCharset().toString();
this.stdin = new OutputStreamWriter(this.process.getOutputStream(), charset);
this.stdOut = new BufferedReader(new InputStreamReader(this.process.getInputStream(), charset));
@@ -43,40 +51,56 @@ public CSharpierProcessPipeMultipleFiles(String csharpierPath, boolean useUtf8)
@Override
public String formatFile(String content, String filePath) {
- try {
-
- this.stdin.write(filePath);
- this.stdin.write('\u0003');
- this.stdin.write(content);
- this.stdin.write('\u0003');
- this.stdin.flush();
-
- var stringBuilder = new StringBuilder();
-
- var nextCharacter = this.stdOut.read();
- while (nextCharacter != -1) {
- if (nextCharacter == '\u0003') {
- break;
+ var stringBuilder = new StringBuilder();
+
+ Runnable task = () -> {
+ try {
+ this.stdin.write(filePath);
+ this.stdin.write('\u0003');
+ this.stdin.write(content);
+ this.stdin.write('\u0003');
+ this.stdin.flush();
+
+ var nextCharacter = this.stdOut.read();
+ while (nextCharacter != -1) {
+ if (nextCharacter == '\u0003') {
+ break;
+ }
+ stringBuilder.append((char) nextCharacter);
+ nextCharacter = this.stdOut.read();
}
- stringBuilder.append((char) nextCharacter);
- nextCharacter = this.stdOut.read();
+ } catch (Exception e) {
+ this.logger.error(e);
+ e.printStackTrace();
}
+ };
- var result = stringBuilder.toString();
+ // csharpier will freeze in some instances when "Format on Save" is also installed and the file has compilation errors
+ // this detects that and recovers from it
+ var thread = new Thread(task);
+ thread.start();
+ try {
+ thread.join(3000);
+ } catch (InterruptedException e) {
+ // if we interrupt it we shouldn't log it
+ }
- if (result == null || result.isEmpty())
- {
- this.logger.info("File is ignored by .csharpierignore or there was an error");
- return "";
- }
+ if (thread.isAlive()) {
+ this.logger.warn("CSharpier process appears to be hung, restarting it.");
+ thread.interrupt();
+ this.process.destroy();
+ this.startProcess();
+ return "";
+ }
- return result;
+ var result = stringBuilder.toString();
- } catch (Exception e) {
- this.logger.error(e);
- e.printStackTrace();
+ if (result == null || result.isEmpty()) {
+ this.logger.info("File is ignored by .csharpierignore or there was an error");
return "";
}
+
+ return result;
}
@Override
diff --git a/Src/CSharpier.Rider/src/main/java/com/intellij/csharpier/ReformatWithCSharpierOnSave.java b/Src/CSharpier.Rider/src/main/java/com/intellij/csharpier/ReformatWithCSharpierOnSave.java
index cb7019f6f..fb5b8975b 100644
--- a/Src/CSharpier.Rider/src/main/java/com/intellij/csharpier/ReformatWithCSharpierOnSave.java
+++ b/Src/CSharpier.Rider/src/main/java/com/intellij/csharpier/ReformatWithCSharpierOnSave.java
@@ -16,6 +16,7 @@ public class ReformatWithCSharpierOnSave implements AnActionListener {
private final Logger logger = CSharpierLogger.getInstance();
public ReformatWithCSharpierOnSave() {
+ // TODO this is deprecated and should be switched to https://plugins.jetbrains.com/docs/intellij/messaging-infrastructure.html#subscribing-to-a-topic
Topics.subscribe(AnActionListener.TOPIC, null, this);
}