An open API service indexing awesome lists of open source software.

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

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 file

OPTIONS:
-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:

![Code snippet with syntax highlighting](Screenshots/iobat_main-dark.png)

## 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-style

ARGUMENTS:
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;
}
```