From a8e7fb2c8b2e79ce63f4a5286250f0d093d64559 Mon Sep 17 00:00:00 2001 From: Iulian Dragos Date: Wed, 4 Jul 2012 12:33:18 +0200 Subject: [PATCH] Make standard output/error redirection optional. By default, std out and error are redirected to the log file. This makes it difficult to do println debugging, and often each printed character ends up on a separate line in the log file. This PR makes it an option. Fixes #1001133 --- .../src/scala/tools/eclipse/ScalaPlugin.scala | 11 ++++ .../tools/eclipse/logging/LogManager.scala | 52 +++++++++++++------ .../eclipse/logging/StreamRedirect.scala | 4 ++ .../LoggingPreferenceConstants.scala | 1 + .../ui/properties/LoggingPreferencePage.scala | 3 ++ 5 files changed, 54 insertions(+), 17 deletions(-) diff --git a/org.scala-ide.sdt.core/src/scala/tools/eclipse/ScalaPlugin.scala b/org.scala-ide.sdt.core/src/scala/tools/eclipse/ScalaPlugin.scala index b30a069a56..a3334704e5 100644 --- a/org.scala-ide.sdt.core/src/scala/tools/eclipse/ScalaPlugin.scala +++ b/org.scala-ide.sdt.core/src/scala/tools/eclipse/ScalaPlugin.scala @@ -218,6 +218,17 @@ class ScalaPlugin extends AbstractUIPlugin with PluginLogConfigurator with IReso } } + /** Restart all presentation compilers in the workspace. Need to do it in order + * for them to pick up the new std out/err streams. + */ + def resetAllPresentationCompilers() { + for { + iProject <- ResourcesPlugin.getWorkspace.getRoot.getProjects + if iProject.isOpen + scalaProject <- asScalaProject(iProject) + } scalaProject.resetPresentationCompiler() + } + /** * Return Some(ScalaProject) if the project has the Scala nature, None otherwise. */ diff --git a/org.scala-ide.sdt.core/src/scala/tools/eclipse/logging/LogManager.scala b/org.scala-ide.sdt.core/src/scala/tools/eclipse/logging/LogManager.scala index 9eb34e9cd7..7c65ea4a2c 100644 --- a/org.scala-ide.sdt.core/src/scala/tools/eclipse/logging/LogManager.scala +++ b/org.scala-ide.sdt.core/src/scala/tools/eclipse/logging/LogManager.scala @@ -8,38 +8,56 @@ import org.eclipse.jface.util.PropertyChangeEvent import org.eclipse.jdt.ui.PreferenceConstants import scala.tools.eclipse.util.SWTUtils import java.io.File +import org.eclipse.core.resources.ResourcesPlugin object LogManager extends Log4JFacade with HasLogger { import ui.properties.LoggingPreferenceConstants._ - private def updateLogLevel: IPropertyChangeListener = { - SWTUtils.fnToPropertyChangeListener { event => - if (event.getProperty == LogLevel) { - val level = event.getNewValue.asInstanceOf[String] - setLogLevel(Level.withName(level)) - } + private def updateLogLevel(event: PropertyChangeEvent): Unit = { + if (event.getProperty == LogLevel) { + val level = event.getNewValue.asInstanceOf[String] + setLogLevel(Level.withName(level)) } } - private def updateConsoleAppenderStatus: IPropertyChangeListener = { - SWTUtils.fnToPropertyChangeListener { event => - if (event.getProperty == IsConsoleAppenderEnabled) { - val enable = event.getNewValue.asInstanceOf[Boolean] - withoutConsoleRedirects { - updateConsoleAppender(enable) - } + private def updateConsoleAppenderStatus(event: PropertyChangeEvent): Unit = { + if (event.getProperty == IsConsoleAppenderEnabled) { + val enable = event.getNewValue.asInstanceOf[Boolean] + withoutConsoleRedirects { + updateConsoleAppender(enable) } } } + private def updateStdRedirectStatus(event: PropertyChangeEvent): Unit = { + if (event.getProperty == RedirectStdErrOut) { + val enable = event.getNewValue.asInstanceOf[Boolean] + if (enable) redirectStdOutAndStdErr() + else disableRedirectStdOutAndStdErr() + + // we need to restart the presentation compilers so that + // the std out/err streams are refreshed by Console.in/out + if (enable != event.getOldValue.asInstanceOf[Boolean]) + ScalaPlugin.plugin.resetAllPresentationCompilers() + } + } + override protected def logFileName = "scala-ide.log" override def configure(logOutputLocation: String, preferredLogLevel: Level.Value) { + import SWTUtils.fnToPropertyChangeListener + super.configure(logOutputLocation, preferredLogLevel) - ScalaPlugin.plugin.getPreferenceStore.addPropertyChangeListener(updateLogLevel) - ScalaPlugin.plugin.getPreferenceStore.addPropertyChangeListener(updateConsoleAppenderStatus) - - redirectStdOutAndStdErr() + + val prefStore = ScalaPlugin.plugin.getPreferenceStore + prefStore.addPropertyChangeListener(updateLogLevel _) + prefStore.addPropertyChangeListener(updateConsoleAppenderStatus _) + prefStore.addPropertyChangeListener(updateStdRedirectStatus _) + + if (prefStore.getBoolean(RedirectStdErrOut)) { + redirectStdOutAndStdErr() + ScalaPlugin.plugin.resetAllPresentationCompilers() + } } override protected def setLogLevel(level: Level.Value) { diff --git a/org.scala-ide.sdt.core/src/scala/tools/eclipse/logging/StreamRedirect.scala b/org.scala-ide.sdt.core/src/scala/tools/eclipse/logging/StreamRedirect.scala index fd8ae43d9c..b5af0d6b56 100644 --- a/org.scala-ide.sdt.core/src/scala/tools/eclipse/logging/StreamRedirect.scala +++ b/org.scala-ide.sdt.core/src/scala/tools/eclipse/logging/StreamRedirect.scala @@ -16,6 +16,7 @@ private[logging] object StreamRedirect { val logger = LogManager.getLogger("System.out") val outStream = redirect(msg => logger.debug(msg)) System.setOut(outStream) + Console.setOut(outStream) isStdOutRedirected = true } } @@ -23,6 +24,7 @@ private[logging] object StreamRedirect { def disableRedirectStdOutput(): Unit = synchronized { if(isStdOutRedirected) { System.setOut(defaultStdOut) + Console.setOut(defaultStdOut) isStdOutRedirected = false } } @@ -32,6 +34,7 @@ private[logging] object StreamRedirect { val logger = LogManager.getLogger("System.err") val errStream = redirect(msg => logger.error(msg)) System.setErr(errStream) + Console.setErr(errStream) isStdErrRedirected = true } } @@ -39,6 +42,7 @@ private[logging] object StreamRedirect { def disableRedirectStdError(): Unit = synchronized { if(isStdErrRedirected) { System.setErr(defaultStdErr) + Console.setErr(defaultStdErr) isStdErrRedirected = false } } diff --git a/org.scala-ide.sdt.core/src/scala/tools/eclipse/logging/ui/properties/LoggingPreferenceConstants.scala b/org.scala-ide.sdt.core/src/scala/tools/eclipse/logging/ui/properties/LoggingPreferenceConstants.scala index 4350f2405e..ff144cefd0 100644 --- a/org.scala-ide.sdt.core/src/scala/tools/eclipse/logging/ui/properties/LoggingPreferenceConstants.scala +++ b/org.scala-ide.sdt.core/src/scala/tools/eclipse/logging/ui/properties/LoggingPreferenceConstants.scala @@ -4,4 +4,5 @@ private[logging] object LoggingPreferenceConstants { private final val Prefix = "scala.tools.eclipse.logging.ui.properties." final val LogLevel = Prefix + "LogLevel" final val IsConsoleAppenderEnabled = Prefix + "ConsoleAppenderEnabled" + final val RedirectStdErrOut = Prefix + "RedirectSdtErrOut" } \ No newline at end of file diff --git a/org.scala-ide.sdt.core/src/scala/tools/eclipse/logging/ui/properties/LoggingPreferencePage.scala b/org.scala-ide.sdt.core/src/scala/tools/eclipse/logging/ui/properties/LoggingPreferencePage.scala index 7277e1956b..05bde83546 100644 --- a/org.scala-ide.sdt.core/src/scala/tools/eclipse/logging/ui/properties/LoggingPreferencePage.scala +++ b/org.scala-ide.sdt.core/src/scala/tools/eclipse/logging/ui/properties/LoggingPreferencePage.scala @@ -28,6 +28,7 @@ class LoggingPreferencePage extends FieldEditorPreferencePage with IWorkbenchPre addField(new ComboFieldEditor(LoggingPreferenceConstants.LogLevel, "Log Level", namesAndValues, getFieldEditorParent)) addField(new BooleanFieldEditor(LoggingPreferenceConstants.IsConsoleAppenderEnabled, "Output log in terminal", getFieldEditorParent)) + addField(new BooleanFieldEditor(LoggingPreferenceConstants.RedirectStdErrOut, "Redirect standard out/err to log file", getFieldEditorParent)) } override def createContents(parent: Composite): Control = { @@ -49,10 +50,12 @@ class LoggingPreferencePageInitializer extends AbstractPreferenceInitializer { if(ScalaPlugin.plugin.headlessMode) { store.setDefault(LoggingPreferenceConstants.LogLevel, Level.DEBUG.toString) store.setDefault(LoggingPreferenceConstants.IsConsoleAppenderEnabled, true) + store.setDefault(LoggingPreferenceConstants.RedirectStdErrOut, false) } else { store.setDefault(LoggingPreferenceConstants.LogLevel, LogManager.defaultLogLevel.toString) store.setDefault(LoggingPreferenceConstants.IsConsoleAppenderEnabled, false) + store.setDefault(LoggingPreferenceConstants.RedirectStdErrOut, true) } } } \ No newline at end of file