Add syntax highlighting of Pkl code (#1385)

This adds syntax highlighting of Pkl code!

It adds highlighting for:

* Stack frames within error messages
* CLI REPL (highlights as you type, highlights error output)
* Power assertions (coming in https://github.com/apple/pkl/pull/1384)

This uses the lexer for highlighting. It will highlight strings,
numbers, keywords, but doesn't understand how to highlight nodes like
types, function params, etc.
The reason for this is because a single line of code by itself may not
be grammatically valid.
This commit is contained in:
Daniel Chao
2026-01-06 10:33:11 -08:00
committed by GitHub
parent 4f4f03dbca
commit 6b9c670cfd
9 changed files with 315 additions and 27 deletions
@@ -1,5 +1,5 @@
/*
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -192,6 +192,37 @@ class ReplServerTest {
assertThat(result4).contains("Expected value of type `String`, but got type `Int`.")
}
@Test
fun `syntax highlighting on response values`() {
val server =
ReplServer(
SecurityManagers.defaultManager,
HttpClient.dummyClient(),
Loggers.stdErr(),
listOf(
ModuleKeyFactories.standardLibrary,
ModuleKeyFactories.classPath(this::class.java.classLoader),
ModuleKeyFactories.file,
),
listOf(ResourceReaders.environmentVariable(), ResourceReaders.externalProperty()),
mapOf("NAME1" to "value1", "NAME2" to "value2"),
mapOf("name1" to "value1", "name2" to "value2"),
null,
null,
null,
"/".toPath(),
StackFrameTransformers.defaultTransformer,
true,
TraceMode.COMPACT,
)
val responses = server.handleRequest(ReplRequest.Eval("id", "5.ms", false, false))
assertThat(responses).hasSize(1)
val response = responses[0]
assertThat(response).isInstanceOf(ReplResponse.EvalSuccess::class.java)
assertThat((response as ReplResponse.EvalSuccess).result).isEqualTo("\u001B[32m5\u001B[0m.ms")
}
private fun makeEvalRequest(text: String): String {
val responses = server.handleRequest(ReplRequest.Eval("id", text, false, false))