@@ -19,6 +19,7 @@ typedef NS_ENUM(NSUInteger, CDOutputColorMode) {
1919 CDOutputColorModeNever,
2020 CDOutputColorModeAlways,
2121 CDOutputColorModeHtmlHljs,
22+ CDOutputColorModeHtmlLsp,
2223
2324 CDOutputColorModeCaseCount
2425};
@@ -41,6 +42,7 @@ static void printUsage(const char *progname) {
4142 " never: no output is colored\n "
4243 " always: output to TTYs, pipes, and files are colored using ASNI color escapes\n "
4344 " html-hljs: output to TTYs, pipes, and files are in HTML format annotated with hljs classes\n "
45+ " html-lsp: output to TTYs, pipes, and files are in HTML format annotated with LSP classes\n "
4446 " -i <p>, --image=<p> Reference the mach-o image at path\n "
4547 " by default, dump all classes in this image\n "
4648 " otherwise may specify --class or --protocol\n "
@@ -173,6 +175,50 @@ static void printUsage(const char *progname) {
173175 return build;
174176}
175177
178+ static NSString *lspHtmlForSemanticString (CDSemanticString *const semanticString) {
179+ NSMutableString *build = [NSMutableString string ];
180+ // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#semanticTokenTypes
181+ // https://github.com/leptos-null/LspHighlight/blob/5bce00c/Sources/LspHighlight/LspHighlight.swift#L285
182+ [semanticString enumerateLongestEffectiveRangesUsingBlock: ^(NSString *string, CDSemanticType type) {
183+ NSString *htmlCls = nil ;
184+ switch (type) {
185+ case CDSemanticTypeComment:
186+ htmlCls = @" lsp-type-comment" ;
187+ break ;
188+ case CDSemanticTypeKeyword:
189+ htmlCls = @" lsp-type-keyword" ;
190+ break ;
191+ case CDSemanticTypeVariable:
192+ htmlCls = @" lsp-type-variable" ;
193+ break ;
194+ case CDSemanticTypeRecordName:
195+ htmlCls = @" lsp-type-struct" ;
196+ break ;
197+ case CDSemanticTypeClass:
198+ htmlCls = @" lsp-type-class" ;
199+ break ;
200+ case CDSemanticTypeProtocol:
201+ htmlCls = @" lsp-type-type" ;
202+ break ;
203+ case CDSemanticTypeNumeric:
204+ htmlCls = @" lsp-type-number" ;
205+ break ;
206+ default :
207+ break ;
208+ }
209+ if (htmlCls != nil ) {
210+ [build appendString: @" <span class=\" " ];
211+ [build appendString: htmlCls];
212+ [build appendString: @" \" >" ];
213+ }
214+ [build appendString: sanitizeForHTML (string)];
215+ if (htmlCls != nil ) {
216+ [build appendString: @" </span>" ];
217+ }
218+ }];
219+ return build;
220+ }
221+
176222static NSString *linesForSemanticStringColorMode (CDSemanticString *const semanticString, CDOutputColorMode const colorMode, BOOL const isOutputTTY) {
177223 BOOL shouldColor = NO ;
178224 switch (colorMode) {
@@ -187,6 +233,8 @@ static void printUsage(const char *progname) {
187233 break ;
188234 case CDOutputColorModeHtmlHljs:
189235 return hljsHtmlForSemanticString (semanticString);
236+ case CDOutputColorModeHtmlLsp:
237+ return lspHtmlForSemanticString (semanticString);
190238 default :
191239 NSCAssert (NO , @" Unknown case: %lu " , (unsigned long )colorMode);
192240 break ;
@@ -248,6 +296,8 @@ int main(int argc, char *argv[]) {
248296 outputColorMode = CDOutputColorModeAlways;
249297 } else if (strcmp (stringyOption, " html-hljs" ) == 0 ) {
250298 outputColorMode = CDOutputColorModeHtmlHljs;
299+ } else if (strcmp (stringyOption, " html-lsp" ) == 0 ) {
300+ outputColorMode = CDOutputColorModeHtmlLsp;
251301 } else {
252302 printUsage (argv[0 ]);
253303 return 1 ;
0 commit comments