Skip to content

Commit

Permalink
Merge pull request #2615 from ckipp01/dap-color
Browse files Browse the repository at this point in the history
Add init option to strip color from DAP communication.
  • Loading branch information
ckipp01 authored Mar 15, 2021
2 parents 20230b2 + 1cb0dd4 commit fc8e6c4
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 23 deletions.
9 changes: 9 additions & 0 deletions docs/integrations/new-editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ The currently available settings for `InitializationOptions` are listed below.
"debuggingProvider": boolean,
"decorationProvider": boolean,
"didFocusProvider": boolean,
"disableColorOutput" boolean,
"doctorProvider": "json" | "html",
"executeClientCommandProvider": boolean,
"globSyntax": "vscode" | "uri"
Expand Down Expand Up @@ -253,6 +254,14 @@ Boolean value to signify that the client supports the

Default value: `false`

##### `disableColorOutput`

Useful for certain DAP clients that are unable to handle color codes for output.
This will remove the color codes coming from whatever DAP server is currently
being used.

Default value: `false`

##### `doctorProvider`

Format that you'd like Doctor to return information in.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ class ClientConfiguration(

def isCopyWorksheetOutputProvider(): Boolean =
initializationOptions.copyWorksheetOutputProvider.getOrElse(false)

def disableColorOutput(): Boolean =
initializationOptions.disableColorOutput.getOrElse(false)
}

object ClientConfiguration {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ import org.eclipse.{lsp4j => l}
* @param openNewWindowProvider if the client can open a new window after new project creation.
* @param copyWorksheetOutputProvider if the client can execute server CopyWorksheet command and
* copy results to the local buffer.
* @param disableColorOutput in the situation where your DAP client may not handle color codes in
* the output, you can enable this to strip them.
*/
final case class InitializationOptions(
compilerOptions: CompilerInitializationOptions,
Expand All @@ -61,7 +63,8 @@ final case class InitializationOptions(
statusBarProvider: Option[String],
treeViewProvider: Option[Boolean],
openNewWindowProvider: Option[Boolean],
copyWorksheetOutputProvider: Option[Boolean]
copyWorksheetOutputProvider: Option[Boolean],
disableColorOutput: Option[Boolean]
) {
def doctorFormat: Option[DoctorFormat.DoctorFormat] =
doctorProvider.flatMap(DoctorFormat.fromString)
Expand Down Expand Up @@ -94,6 +97,7 @@ object InitializationOptions {
None,
None,
None,
None,
None
)

Expand Down Expand Up @@ -143,7 +147,8 @@ object InitializationOptions {
treeViewProvider = jsonObj.getBooleanOption("treeViewProvider"),
openNewWindowProvider = jsonObj.getBooleanOption("openNewWindowProvider"),
copyWorksheetOutputProvider =
jsonObj.getBooleanOption("copyWorksheetOutputProvider")
jsonObj.getBooleanOption("copyWorksheetOutputProvider"),
disableColorOutput = jsonObj.getBooleanOption("disableColorOutput")
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -620,9 +620,8 @@ class MetalsLanguageServer(
classFinder,
definitionIndex,
stacktraceAnalyzer,
clientConfig.icons(),
semanticdbs,
clientConfig
clientConfig,
semanticdbs
)
scalafixProvider = ScalafixProvider(
buffers,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,11 @@ object DebugProtocol {
}

object OutputNotification {
def unapply(notification: NotificationMessage): Boolean = {
notification.getMethod == "output"
def unapply(
notification: NotificationMessage
): Option[OutputEventArguments] = {
if (notification.getMethod != "output") None
else parse[OutputEventArguments](notification.getParams).toOption
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import scala.meta.internal.metals.DebugUnresolvedAttachRemoteParams
import scala.meta.internal.metals.DebugUnresolvedMainClassParams
import scala.meta.internal.metals.DebugUnresolvedTestClassParams
import scala.meta.internal.metals.DefinitionProvider
import scala.meta.internal.metals.Icons
import scala.meta.internal.metals.JsonParser
import scala.meta.internal.metals.JsonParser._
import scala.meta.internal.metals.Messages
Expand Down Expand Up @@ -68,9 +67,8 @@ class DebugProvider(
classFinder: ClassFinder,
index: OnDemandSymbolIndex,
stacktraceAnalyzer: StacktraceAnalyzer,
icons: Icons,
semanticdbs: Semanticdbs,
clientConfig: ClientConfiguration
clientConfig: ClientConfiguration,
semanticdbs: Semanticdbs
) {

lazy val buildTargetClassesFinder = new BuildTargetClassesFinder(
Expand Down Expand Up @@ -132,7 +130,8 @@ class DebugProvider(
awaitClient,
connectToServer,
classFinder,
stacktraceAnalyzer
stacktraceAnalyzer,
clientConfig.disableColorOutput()
)
}
val server = new DebugServer(sessionName, uri, proxyFactory)
Expand Down Expand Up @@ -409,7 +408,9 @@ class DebugProvider(

private val reportErrors: PartialFunction[Throwable, Unit] = {
case _ if buildClient.buildHasErrors =>
languageClient.metalsStatus(Messages.DebugErrorsPresent(icons))
languageClient.metalsStatus(
Messages.DebugErrorsPresent(clientConfig.icons())
)
languageClient.metalsExecuteClientCommand(
new ExecuteCommandParams(
ClientCommands.FocusDiagnostics.id,
Expand Down Expand Up @@ -449,7 +450,7 @@ class DebugProvider(
case e @ SemanticDbNotFoundException =>
languageClient.metalsStatus(
MetalsStatusParams(
text = s"${icons.alert}Build misconfiguration",
text = s"${clientConfig.icons.alert}Build misconfiguration",
tooltip = e.getMessage(),
command = ClientCommands.RunDoctor.id
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ private[debug] final class DebugProxy(
client: RemoteEndpoint,
server: ServerAdapter,
classFinder: ClassFinder,
stackTraceAnalyzer: StacktraceAnalyzer
stackTraceAnalyzer: StacktraceAnalyzer,
stripColor: Boolean
)(implicit ec: ExecutionContext) {
private val exitStatus = Promise[ExitStatus]()
@volatile private var outputTerminated = false
Expand Down Expand Up @@ -89,11 +90,9 @@ private[debug] final class DebugProxy(
}

private val handleServerMessage: Message => Unit = {
case null =>
() // ignore
case _ if cancelled.get() =>
() // ignore
case OutputNotification() if outputTerminated =>
case null => () // ignore
case _ if cancelled.get() => () // ignore
case OutputNotification(_) if outputTerminated => ()
// ignore. When restarting, the output keeps getting printed for a short while after the
// output window gets refreshed resulting in stale messages being printed on top, before
// any actual logs from the restarted process
Expand Down Expand Up @@ -125,8 +124,15 @@ private[debug] final class DebugProxy(
client.consume(message)
}

case message =>
case message @ OutputNotification(output) if stripColor =>
val raw = output.getOutput()
// As long as the color codes are valid this should correctly strip
// anything that is ESC (U+001B) plus [
val msgWithoutColorCodes = raw.replaceAll("\u001B\\[[;\\d]*m", "");
output.setOutput(msgWithoutColorCodes)
message.setParams(output)
client.consume(message)
case message => client.consume(message)
}

def cancel(): Unit = {
Expand Down Expand Up @@ -155,7 +161,8 @@ private[debug] object DebugProxy {
awaitClient: () => Future[Socket],
connectToServer: () => Future[Socket],
classFinder: ClassFinder,
stacktraceAnalyzer: StacktraceAnalyzer
stacktraceAnalyzer: StacktraceAnalyzer,
stripColor: Boolean
)(implicit ec: ExecutionContext): Future[DebugProxy] = {
for {
server <- connectToServer()
Expand All @@ -173,7 +180,8 @@ private[debug] object DebugProxy {
client,
server,
classFinder,
stacktraceAnalyzer
stacktraceAnalyzer,
stripColor
)
}

Expand Down

0 comments on commit fc8e6c4

Please sign in to comment.