https://github.com/leptos-null/lsphighlight
LSP client to output semantic token markup in HTML
https://github.com/leptos-null/lsphighlight
html-generation lsp lsp-client
Last synced: 2 months ago
JSON representation
LSP client to output semantic token markup in HTML
- Host: GitHub
- URL: https://github.com/leptos-null/lsphighlight
- Owner: leptos-null
- License: mit
- Created: 2024-08-02T19:00:25.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2024-08-19T04:27:29.000Z (9 months ago)
- Last Synced: 2025-01-19T17:24:07.404Z (4 months ago)
- Topics: html-generation, lsp, lsp-client
- Language: Swift
- Homepage:
- Size: 545 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
## LspHighlight
LspHighlight is a command line tool designed to act as an LSP client to output a source code file in HTML format with semantic tokens annotated using CSS classes.
### Usage
```
USAGE: lsp-highlight --lsp-server [-Xlsp ...] [--language ]ARGUMENTS:
Path to the source code fileOPTIONS:
-S, --lsp-server Path to the LSP server
-Xlsp Pass flag to the LSP server
--language The LSP language identifier for the given source code file
By default, the program attempts to select the language based on the file name
-h, --help Show help information.
````lsp-highlight` uses , which automatically provides shell completion scripts.
Pass `--generate-completion-script` to `lsp-highlight` to generate the completion script for your shell.```
use --generate-completion-script= with one of:
zsh bash fish
```For more information, see https://apple.github.io/swift-argument-parser/documentation/argumentparser/installingcompletionscripts
### Sample
This section demonstrates how `lsp-highlight` may be used.
We have the code snippet below in a file named `main.m`.
Input source code
(This file is based off of )
```objc
//
// Created by Leptos on 3/16/19.
// Copyright © 2019 Leptos. All rights reserved.
//#import
#import
#import#define TEMPERATURE_EXTREME_STRING "Warning: Temperature considered to be too "
int main(int argc, char *argv[]) {
BOOL silent = NO;
int opt;
while ((opt = getopt(argc, argv, "s")) != -1) {
switch (opt) {
case 's':
silent = YES;
break;
default:
printf("Usage: %s [-s]\n"
" Battery temperature, as provided by IOKit\n"
" -s Silent, print nothing\n"
"\n"
"Exit status is\n"
" 0 if the temperature is within recommended operating temperatures,\n"
" 1 if the temperature is too low,\n"
" 2 if the temperature is too high,\n"
" 3 if the temperature is either too high or low, but which cannot be determined.\n"
, argv[0]);
return 1;
}
}
mach_port_t mainPort;
if (@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)) {
mainPort = kIOMainPortDefault;
} else {
mainPort = kIOMasterPortDefault;
}
io_service_t service = IOServiceGetMatchingService(mainPort, IOServiceMatching("IOPMPowerSource"));
CFNumberRef temperature = IORegistryEntryCreateCFProperty(service, CFSTR(kIOPMPSBatteryTemperatureKey), NULL, 0);
CFStringRef chargeStat = IORegistryEntryCreateCFProperty(service, CFSTR(kIOPMPSBatteryChargeStatusKey), NULL, 0);
IOObjectRelease(service);
double ioTemp = NAN;
if (temperature) {
CFNumberGetValue(temperature, kCFNumberDoubleType, &ioTemp);
CFRelease(temperature);
}
double const celsiusTemp = ioTemp/100;
NSString *chargeStatus = CFBridgingRelease(chargeStat);
int ret = 0;
const char *warningText = NULL;
if ([chargeStatus isEqualToString:@kIOPMBatteryChargeStatusTooHotOrCold]) {
warningText = (TEMPERATURE_EXTREME_STRING "warm or cold");
ret = 3;
} else if ([chargeStatus isEqualToString:@kIOPMBatteryChargeStatusTooHot]) {
warningText = (TEMPERATURE_EXTREME_STRING "warm");
ret = 2;
} else if ([chargeStatus isEqualToString:@kIOPMBatteryChargeStatusTooCold]) {
warningText = (TEMPERATURE_EXTREME_STRING "cold");
ret = 1;
}
if (!silent) {
NSMeasurement *celsius = [[NSMeasurement alloc] initWithDoubleValue:celsiusTemp unit:NSUnitTemperature.celsius];
NSMeasurementFormatter *unitFormatter = [NSMeasurementFormatter new];
unitFormatter.unitOptions = NSMeasurementFormatterUnitOptionsNaturalScale;
unitFormatter.numberFormatter.maximumFractionDigits = 2;
NSString *localizedTemperature = [unitFormatter stringFromMeasurement:celsius];
if (warningText) {
puts(warningText);
}
printf("Battery temperature: %s\n", localizedTemperature.UTF8String);
}
return ret;
}
```We then run `lsp-highlight -S $(xcrun -f clangd) main.m` to produce the following HTML output:
HTML output
```html
//
// Created by Leptos on 3/16/19.
// Copyright © 2019 Leptos. All rights reserved.
//#import <Foundation/Foundation.h>
#import <IOKit/IOKitLib.h>
#import <IOKit/pwr_mgt/IOPM.h>#define TEMPERATURE_EXTREME_STRING "Warning: Temperature considered to be too "
int main(int argc, char *argv[]) {
BOOL silent = NO;
int opt;
while ((opt = getopt(argc, argv, "s")) != -1) {
switch (opt) {
case 's':
silent = YES;
break;
default:
printf("Usage: %s [-s]\n"
" Battery temperature, as provided by IOKit\n"
" -s Silent, print nothing\n"
"\n"
"Exit status is\n"
" 0 if the temperature is within recommended operating temperatures,\n"
" 1 if the temperature is too low,\n"
" 2 if the temperature is too high,\n"
" 3 if the temperature is either too high or low, but which cannot be determined.\n"
, argv[0]);
return 1;
}
}
mach_port_t mainPort;
if (@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)) {
mainPort = kIOMainPortDefault;
} else {
mainPort = kIOMasterPortDefault;
}
io_service_t service = IOServiceGetMatchingService(mainPort, IOServiceMatching("IOPMPowerSource"));
CFNumberRef temperature = IORegistryEntryCreateCFProperty(service, CFSTR(kIOPMPSBatteryTemperatureKey), NULL, 0);
CFStringRef chargeStat = IORegistryEntryCreateCFProperty(service, CFSTR(kIOPMPSBatteryChargeStatusKey), NULL, 0);
IOObjectRelease(service);
double ioTemp = NAN;
if (temperature) {
CFNumberGetValue(temperature, kCFNumberDoubleType, &ioTemp);
CFRelease(temperature);
}
double const celsiusTemp = ioTemp/100;
NSString *chargeStatus = CFBridgingRelease(chargeStat);
int ret = 0;
const char *warningText = NULL;
if ([chargeStatus isEqualToString:@kIOPMBatteryChargeStatusTooHotOrCold]) {
warningText = (TEMPERATURE_EXTREME_STRING "warm or cold");
ret = 3;
} else if ([chargeStatus isEqualToString:@kIOPMBatteryChargeStatusTooHot]) {
warningText = (TEMPERATURE_EXTREME_STRING "warm");
ret = 2;
} else if ([chargeStatus isEqualToString:@kIOPMBatteryChargeStatusTooCold]) {
warningText = (TEMPERATURE_EXTREME_STRING "cold");
ret = 1;
}
if (!silent) {
NSMeasurement *celsius = [[NSMeasurement alloc] initWithDoubleValue:celsiusTemp unit:NSUnitTemperature.celsius];
NSMeasurementFormatter *unitFormatter = [NSMeasurementFormatter new];
unitFormatter.unitOptions = NSMeasurementFormatterUnitOptionsNaturalScale;
unitFormatter.numberFormatter.maximumFractionDigits = 2;
NSString *localizedTemperature = [unitFormatter stringFromMeasurement:celsius];
if (warningText) {
puts(warningText);
}
printf("Battery temperature: %s\n", localizedTemperature.UTF8String);
}
return ret;
}
```We can then place the snippet above into a full HTML document.
With some CSS, this is what the result may look like:
## XcodeLspStyle
This project also includes a tool to generate CSS from a `.xccolortheme` (Xcode theme) file.
This CSS applies styles to the same classes output from `lsp-highlight`.
### Usage
```
USAGE: xcode-lsp-styleARGUMENTS:
Path to the xccolortheme
These can generally be found with `find $(xcode-select -p)/.. ~/Library/Developer/Xcode/UserData -name '*.xccolortheme' -type f`OPTIONS:
-h, --help Show help information.
```### Sample
`xcode-lsp-style "/Applications/Xcode.app/Contents/SharedFrameworks/DVTUserInterfaceKit.framework/Versions/A/Resources/FontAndColorThemes/High Contrast (Dark).xccolortheme"`
CSS output
```css
.lsp-type-modifier {
color: #e1a778;
}
.lsp-type-comment {
color: #7cb454;
}
.lsp-type-keyword {
color: #fc6ba9;
}
.lsp-type-number {
color: #cfbb55;
}
.lsp-type-string {
color: #fc7367;
}
.lsp-type-class {
color: #a4fae5;
}
.lsp-type-class.lsp-modifier-defaultLibrary {
color: #ddc1fe;
}
.lsp-type-enumMember {
color: #72bead;
}
.lsp-type-enumMember.lsp-modifier-defaultLibrary {
color: #c089fe;
}
.lsp-type-function,
.lsp-type-method,
.lsp-type-property {
color: #72bead;
}
.lsp-type-function.lsp-modifier-defaultLibrary,
.lsp-type-method.lsp-modifier-defaultLibrary,
.lsp-type-property.lsp-modifier-defaultLibrary {
color: #c089fe;
}
.lsp-type-macro {
color: #fc8e3e;
}
.lsp-type-macro.lsp-modifier-defaultLibrary {
color: #fc8e3e;
}
.lsp-type-type {
color: #a4fae5;
}
.lsp-type-type.lsp-modifier-defaultLibrary {
color: #ddc1fe;
}
.lsp-type-variable.lsp-modifier-globalScope {
color: #72bead;
}
.lsp-type-variable.lsp-modifier-globalScope.lsp-modifier-defaultLibrary {
color: #c089fe;
}
```