From 6962e80acd5fa607b06bc61e7add4c77c951614d Mon Sep 17 00:00:00 2001 From: Alexander Onnikov Date: Thu, 31 Oct 2024 20:39:47 +0700 Subject: [PATCH] UBERF-8560 Imrove editor code highlight (#7074) --- common/config/rush/pnpm-lock.yaml | 124 ++++++++++++-- packages/highlight/.eslintrc.js | 4 + packages/highlight/.prettierrc | 22 +++ packages/highlight/config/rig.json | 5 + packages/highlight/jest.config.js | 7 + packages/highlight/package.json | 46 +++++ packages/highlight/postcss.config.js | 5 + .../highlight/src/index.ts | 22 ++- .../highlight/src/languages/svelte.ts | 17 +- packages/highlight/src/languages/vlang.ts | 161 ++++++++++++++++++ packages/highlight/svelte.config.js | 5 + packages/highlight/tsconfig.json | 9 + plugins/diffview-resources/package.json | 2 +- .../src/components/FileDiffContent.svelte | 2 +- .../src/components/Highlight.svelte | 3 +- .../diffview-resources/src/highlight/index.ts | 17 -- plugins/diffview-resources/src/index.ts | 2 + .../src/{highlight => }/render.ts | 2 +- plugins/text-editor-resources/package.json | 1 + .../src/components/extension/codeblock.ts | 5 +- rush.json | 5 + 21 files changed, 423 insertions(+), 43 deletions(-) create mode 100644 packages/highlight/.eslintrc.js create mode 100644 packages/highlight/.prettierrc create mode 100644 packages/highlight/config/rig.json create mode 100644 packages/highlight/jest.config.js create mode 100644 packages/highlight/package.json create mode 100644 packages/highlight/postcss.config.js rename plugins/diffview-resources/src/highlight/highlight.ts => packages/highlight/src/index.ts (80%) rename plugins/diffview-resources/src/highlight/languages/svelte-hljs.ts => packages/highlight/src/languages/svelte.ts (61%) create mode 100644 packages/highlight/src/languages/vlang.ts create mode 100644 packages/highlight/svelte.config.js create mode 100644 packages/highlight/tsconfig.json delete mode 100644 plugins/diffview-resources/src/highlight/index.ts rename plugins/diffview-resources/src/{highlight => }/render.ts (97%) diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 25859b30ae..72c47292cb 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -272,6 +272,9 @@ dependencies: '@rush-temp/guest-resources': specifier: file:./projects/guest-resources.tgz version: file:projects/guest-resources.tgz(@types/node@20.11.19)(esbuild@0.20.1)(postcss-load-config@4.0.2)(postcss@8.4.35)(ts-node@10.9.2) + '@rush-temp/highlight': + specifier: file:./projects/highlight.tgz + version: file:projects/highlight.tgz(@types/node@20.11.19)(esbuild@0.20.1)(postcss-load-config@4.0.2)(postcss@8.4.35)(ts-node@10.9.2) '@rush-temp/hr': specifier: file:./projects/hr.tgz version: file:projects/hr.tgz(@types/node@20.11.19)(esbuild@0.20.1)(ts-node@10.9.2) @@ -1232,6 +1235,9 @@ dependencies: '@types/crypto-js': specifier: ^4.1.1 version: 4.2.2 + '@types/csvtojson': + specifier: ^2.0.0 + version: 2.0.0 '@types/diff': specifier: ~5.0.2 version: 5.0.9 @@ -23178,6 +23184,56 @@ packages: typescript: 5.3.3 dev: false + /svelte-preprocess@5.1.3(postcss-load-config@4.0.2)(postcss@8.4.35)(sass@1.71.1)(svelte@4.2.12)(typescript@5.6.2): + resolution: {integrity: sha512-xxAkmxGHT+J/GourS5mVJeOXZzne1FR5ljeOUAMXUkfEhkLEllRreXpbl3dIYJlcJRfL1LO1uIAPpBpBfiqGPw==} + engines: {node: '>= 16.0.0', pnpm: ^8.0.0} + requiresBuild: true + peerDependencies: + '@babel/core': ^7.10.2 + coffeescript: ^2.5.1 + less: ^3.11.3 || ^4.0.0 + postcss: ^7 || ^8 + postcss-load-config: ^2.1.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 + pug: ^3.0.0 + sass: ^1.26.8 + stylus: ^0.55.0 + sugarss: ^2.0.0 || ^3.0.0 || ^4.0.0 + svelte: ^3.23.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0 + typescript: '>=3.9.5 || ^4.0.0 || ^5.0.0' + peerDependenciesMeta: + '@babel/core': + optional: true + coffeescript: + optional: true + less: + optional: true + postcss: + optional: true + postcss-load-config: + optional: true + pug: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + typescript: + optional: true + dependencies: + '@types/pug': 2.0.10 + detect-indent: 6.1.0 + magic-string: 0.30.7 + postcss: 8.4.35 + postcss-load-config: 4.0.2(postcss@8.4.35)(ts-node@10.9.2) + sass: 1.71.1 + sorcery: 0.11.0 + strip-indent: 3.0.0 + svelte: 4.2.12 + typescript: 5.6.2 + dev: false + /svelte@4.2.11: resolution: {integrity: sha512-YIQk3J4X89wOLhjsqIW8tqY3JHPuBdtdOIkASP2PZeAMcSW9RsIjQzMesCrxOF3gdWYC0mKknlKF7OqmLM+Zqg==} engines: {node: '>=16'} @@ -27467,7 +27523,7 @@ packages: dev: false file:projects/diffview-resources.tgz(@types/node@20.11.19)(esbuild@0.20.1)(postcss-load-config@4.0.2)(postcss@8.4.35)(ts-node@10.9.2): - resolution: {integrity: sha512-fi0UUvQTrAAt70IEF8CC7O6h5UfknnXO0xHylpL/Wn7h6oOQHlfPl9VhAx0PJW6TDvw3CltEE35pVSLyDml1CA==, tarball: file:projects/diffview-resources.tgz} + resolution: {integrity: sha512-KZ6MRvsPCXYmTb05Jv0YgDwYMREnlmcyVC06L20SivCexX7nymqt6ul7oKdfu2keE9+qrIJjYtqHxAQUKQ4gFA==, tarball: file:projects/diffview-resources.tgz} id: file:projects/diffview-resources.tgz name: '@rush-temp/diffview-resources' version: 0.0.0 @@ -28170,6 +28226,53 @@ packages: - ts-node dev: false + file:projects/highlight.tgz(@types/node@20.11.19)(esbuild@0.20.1)(postcss-load-config@4.0.2)(postcss@8.4.35)(ts-node@10.9.2): + resolution: {integrity: sha512-xj/v9VAzl0qNSFarmoAujWSXP28ZkYEnnOBqx55GxBMULn54HimvBalNi/tymMwJV0LUSQbPyJbCY+HHV1tcuQ==, tarball: file:projects/highlight.tgz} + id: file:projects/highlight.tgz + name: '@rush-temp/highlight' + version: 0.0.0 + dependencies: + '@types/jest': 29.5.12 + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.6.2) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.6.2) + eslint: 8.56.0 + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0)(eslint-plugin-import@2.29.1)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.56.0)(typescript@5.6.2) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + eslint-plugin-svelte: 2.35.1(eslint@8.56.0)(svelte@4.2.12)(ts-node@10.9.2) + highlight.js: 11.8.0 + jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2) + lowlight: 3.1.0 + prettier: 3.2.5 + prettier-plugin-svelte: 3.2.2(prettier@3.2.5)(svelte@4.2.12) + sass: 1.71.1 + svelte: 4.2.12 + svelte-check: 3.6.9(postcss-load-config@4.0.2)(postcss@8.4.35)(sass@1.71.1)(svelte@4.2.12) + svelte-eslint-parser: 0.33.1(svelte@4.2.12) + svelte-loader: 3.2.0(svelte@4.2.12) + svelte-preprocess: 5.1.3(postcss-load-config@4.0.2)(postcss@8.4.35)(sass@1.71.1)(svelte@4.2.12)(typescript@5.6.2) + ts-jest: 29.1.2(esbuild@0.20.1)(jest@29.7.0)(typescript@5.6.2) + typescript: 5.6.2 + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - '@types/node' + - babel-jest + - babel-plugin-macros + - coffeescript + - esbuild + - less + - node-notifier + - postcss + - postcss-load-config + - pug + - stylus + - sugarss + - supports-color + - ts-node + dev: false + file:projects/hr-assets.tgz(esbuild@0.20.1)(ts-node@10.9.2): resolution: {integrity: sha512-NHRl6EHEnHdUWlcw0CbP7m1ZIKiRytNEO0fXtbXW8aREXmUcplLyHsE6lf0f7Y3iDxtPUm0V7DdfKtmzkuMNtA==, tarball: file:projects/hr-assets.tgz} id: file:projects/hr-assets.tgz @@ -28356,7 +28459,7 @@ packages: dev: false file:projects/import-tool.tgz: - resolution: {integrity: sha512-QBo/RgAGnie95pESqQNJUQSCpQi1rEpXqZz1G1zZMfhAvisZtW2XutmaGMS1oDu2ZB05pk8WOO8x6bfdc+keZg==, tarball: file:projects/import-tool.tgz} + resolution: {integrity: sha512-KD9EB2XXo43QYnx8xp4j9z62JGValTBx2uTS4Egw11rsdAoENIxNxI+68CIKASfY8DMKMMuTmUZ6N6nK/6XSiw==, tarball: file:projects/import-tool.tgz} name: '@rush-temp/import-tool' version: 0.0.0 dependencies: @@ -30465,7 +30568,7 @@ packages: dev: false file:projects/notification-resources.tgz(@types/node@20.11.19)(esbuild@0.20.1)(postcss-load-config@4.0.2)(postcss@8.4.35)(ts-node@10.9.2): - resolution: {integrity: sha512-xpvJbpFBrKB3RPG8SgT9+cJj2IkysBNcl4jQAV69ACUvnTQMh4RS9P31zpaO7CObYXrm9/ImRF0fXbH+AkiJsg==, tarball: file:projects/notification-resources.tgz} + resolution: {integrity: sha512-7qZrSN1845Nti1pousixaoWtM8ISlPYqgw5pK4UtuhEPdrfSq2NkCSSMnl3pOeSU6bVFzAeJ6YlTZs8Jl2wJ7A==, tarball: file:projects/notification-resources.tgz} id: file:projects/notification-resources.tgz name: '@rush-temp/notification-resources' version: 0.0.0 @@ -31360,7 +31463,7 @@ packages: dev: false file:projects/pod-server.tgz(utf-8-validate@6.0.4): - resolution: {integrity: sha512-R0fObVPXSToiK7ioPeEbZ1gZFFjswVFLPCojWYsoNsHg9TL+kTNUdST63PJr4GCr8XVv9VplfYYcEs7qSARvAw==, tarball: file:projects/pod-server.tgz} + resolution: {integrity: sha512-boGyT8HkEJkWqcXXAAZ869HB68/GpHcMTUBZlhkUS9oztHADMfpAbGQ+yVVvypye4e9nsYTF1LhpsDrToOtPYw==, tarball: file:projects/pod-server.tgz} id: file:projects/pod-server.tgz name: '@rush-temp/pod-server' version: 0.0.0 @@ -32804,7 +32907,7 @@ packages: dev: false file:projects/server-ai-bot-resources.tgz(@types/node@20.11.19)(esbuild@0.20.1)(ts-node@10.9.2): - resolution: {integrity: sha512-m+ZYZxCuYOJxhC31c3misAQofis4BG32ek1OPxXXdpOOxPQUFI1WjmwVqJlZDTz3Yt9EXTGv3qkvrNwJuIyWZA==, tarball: file:projects/server-ai-bot-resources.tgz} + resolution: {integrity: sha512-UChmRA0uWxgRKIx9jl1+P4wlGdsdLjsMkR3VOFR3Ya/sYwYV78JOCBIvnsTox/vJha8hx4mynqxaTCSe2nqshA==, tarball: file:projects/server-ai-bot-resources.tgz} id: file:projects/server-ai-bot-resources.tgz name: '@rush-temp/server-ai-bot-resources' version: 0.0.0 @@ -32823,20 +32926,13 @@ packages: ts-jest: 29.1.2(esbuild@0.20.1)(jest@29.7.0)(typescript@5.3.3) typescript: 5.3.3 transitivePeerDependencies: - - '@aws-sdk/credential-providers' - '@babel/core' - '@jest/types' - - '@mongodb-js/zstd' - '@types/node' - babel-jest - babel-plugin-macros - esbuild - - gcp-metadata - - kerberos - - mongodb-client-encryption - node-notifier - - snappy - - socks - supports-color - ts-node dev: false @@ -33152,7 +33248,7 @@ packages: dev: false file:projects/server-client.tgz(bufferutil@4.0.8)(esbuild@0.20.1)(ts-node@10.9.2)(utf-8-validate@6.0.4): - resolution: {integrity: sha512-L1a1mgOD2Qd1S0E6twotWEVeiFeZfvIK5v93gaPH+A5LkkQoOi4qXoEQv/Udul/cDP/MxPFA9HQ3WbdMIn8XYg==, tarball: file:projects/server-client.tgz} + resolution: {integrity: sha512-ixXx7EdCjt/KMKk6pVedAj/27hWqDwCBnHhmTJc694OR8wTEHyIaohP9t8gcjka/ugJRJJjOmAsF1sd8HphW4g==, tarball: file:projects/server-client.tgz} id: file:projects/server-client.tgz name: '@rush-temp/server-client' version: 0.0.0 @@ -35802,7 +35898,7 @@ packages: dev: false file:projects/text-editor-resources.tgz(@types/node@20.11.19)(bufferutil@4.0.8)(esbuild@0.20.1)(highlight.js@11.8.0)(postcss-load-config@4.0.2)(postcss@8.4.35)(ts-node@10.9.2)(utf-8-validate@6.0.4): - resolution: {integrity: sha512-uffVYh80gs1A2XBETq/xa9TBTeZRZxTMb7sD/mjAvolpsXBd/cPCSKqhytZaoEFqIAFnZ6KfEMUqTlNIki4MoQ==, tarball: file:projects/text-editor-resources.tgz} + resolution: {integrity: sha512-0IJEwSBOHUuSL2q4FSBnhVcfzwK0qOc5KcM7cKXbOM8GO/+WgyGRtKULl1b3LDjuBC21wst3eZY3o03qFIBDIQ==, tarball: file:projects/text-editor-resources.tgz} id: file:projects/text-editor-resources.tgz name: '@rush-temp/text-editor-resources' version: 0.0.0 diff --git a/packages/highlight/.eslintrc.js b/packages/highlight/.eslintrc.js new file mode 100644 index 0000000000..bb8fd7450d --- /dev/null +++ b/packages/highlight/.eslintrc.js @@ -0,0 +1,4 @@ +module.exports = { + extends: ['./node_modules/@hcengineering/platform-rig/profiles/ui/eslint.config.json'], + parserOptions: { tsconfigRootDir: __dirname } +} diff --git a/packages/highlight/.prettierrc b/packages/highlight/.prettierrc new file mode 100644 index 0000000000..792942803a --- /dev/null +++ b/packages/highlight/.prettierrc @@ -0,0 +1,22 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "trailingComma": "none", + "tabWidth": 2, + "semi": false, + "singleQuote": true, + "printWidth": 120, + "useTabs": false, + "bracketSpacing": true, + "proseWrap": "preserve", + "plugins": [ + "prettier-plugin-svelte" + ], + "overrides": [ + { + "files": "*.svelte", + "options": { + "parser": "svelte" + } + } + ] +} \ No newline at end of file diff --git a/packages/highlight/config/rig.json b/packages/highlight/config/rig.json new file mode 100644 index 0000000000..bcad6f7c33 --- /dev/null +++ b/packages/highlight/config/rig.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", + "rigPackageName": "@hcengineering/platform-rig", + "rigProfile": "ui" +} diff --git a/packages/highlight/jest.config.js b/packages/highlight/jest.config.js new file mode 100644 index 0000000000..2cfd408b67 --- /dev/null +++ b/packages/highlight/jest.config.js @@ -0,0 +1,7 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'], + roots: ["./src"], + coverageReporters: ["text-summary", "html"] +} diff --git a/packages/highlight/package.json b/packages/highlight/package.json new file mode 100644 index 0000000000..04e522ef7a --- /dev/null +++ b/packages/highlight/package.json @@ -0,0 +1,46 @@ +{ + "name": "@hcengineering/highlight", + "version": "0.6.0", + "main": "src/index.ts", + "author": "Hardcore Engineering Inc.", + "license": "EPL-2.0", + "scripts": { + "build": "compile ui", + "build:docs": "api-extractor run --local", + "format": "format src", + "svelte-check": "do-svelte-check", + "_phase:svelte-check": "do-svelte-check", + "build:watch": "compile ui", + "_phase:build": "compile ui", + "_phase:format": "format src", + "_phase:validate": "compile validate" + }, + "devDependencies": { + "svelte-loader": "^3.2.0", + "sass": "^1.53.0", + "svelte-preprocess": "^5.1.3", + "@hcengineering/platform-rig": "^0.6.0", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "@typescript-eslint/parser": "^6.11.0", + "eslint-config-standard-with-typescript": "^40.0.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-n": "^15.4.0", + "eslint-plugin-promise": "^6.1.1", + "prettier-plugin-svelte": "^3.2.2", + "eslint": "^8.54.0", + "prettier": "^3.1.0", + "svelte-check": "^3.6.9", + "typescript": "^5.3.3", + "jest": "^29.7.0", + "ts-jest": "^29.1.1", + "@types/jest": "^29.5.5", + "eslint-plugin-svelte": "^2.35.1", + "svelte-eslint-parser": "^0.33.1" + }, + "dependencies": { + "svelte": "^4.2.12", + "@hcengineering/ui": "^0.6.15", + "highlight.js": "~11.8.0", + "lowlight": "^3.1.0" + } +} diff --git a/packages/highlight/postcss.config.js b/packages/highlight/postcss.config.js new file mode 100644 index 0000000000..88752c6cb0 --- /dev/null +++ b/packages/highlight/postcss.config.js @@ -0,0 +1,5 @@ +module.exports = { + plugins: [ + require('autoprefixer') + ] +} diff --git a/plugins/diffview-resources/src/highlight/highlight.ts b/packages/highlight/src/index.ts similarity index 80% rename from plugins/diffview-resources/src/highlight/highlight.ts rename to packages/highlight/src/index.ts index ea7ff87dd2..87695f55c3 100644 --- a/plugins/diffview-resources/src/highlight/highlight.ts +++ b/packages/highlight/src/index.ts @@ -1,5 +1,5 @@ // -// Copyright © 2023 Hardcore Engineering Inc. +// Copyright © 2024 Hardcore Engineering Inc. // // Licensed under the Eclipse Public License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. You may @@ -13,16 +13,29 @@ // limitations under the License. // -import hljs from 'highlight.js' -import { hljsDefineSvelte } from './languages/svelte-hljs' +import hljs, { type LanguageFn } from 'highlight.js' +import { all } from 'lowlight' +import { svelte } from './languages/svelte' +import { vlang } from './languages/vlang' -hljs.registerLanguage('svelte', hljsDefineSvelte) +/** @public */ +export const grammars: Record = { + ...all, + svelte, + vlang +} +Object.entries(grammars).forEach((grammar) => { + hljs.registerLanguage(...grammar) +}) + +/** @public */ export interface HighlightOptions { auto?: boolean language: string | undefined } +/** @public */ export function highlightText (text: string, options: HighlightOptions): string { // We should always use highlighter because it sanitizes the input // We have to always use highlighter to ensure that the input is sanitized @@ -38,6 +51,7 @@ export function highlightText (text: string, options: HighlightOptions): string return normalizeHighlightTags(highlighted) } +/** @public */ export function highlightLines (lines: string[], options: HighlightOptions): string[] { const highlighted = highlightText(lines.join('\n'), options) return highlighted.split('\n') diff --git a/plugins/diffview-resources/src/highlight/languages/svelte-hljs.ts b/packages/highlight/src/languages/svelte.ts similarity index 61% rename from plugins/diffview-resources/src/highlight/languages/svelte-hljs.ts rename to packages/highlight/src/languages/svelte.ts index a47af00f5d..0de570970f 100644 --- a/plugins/diffview-resources/src/highlight/languages/svelte-hljs.ts +++ b/packages/highlight/src/languages/svelte.ts @@ -1,4 +1,19 @@ -export function hljsDefineSvelte (hljs: any): any { +// +// Copyright © 2024 Hardcore Engineering Inc. +// +// Licensed under the Eclipse Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. You may +// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// + +export function svelte (hljs: any): any { return { subLanguage: 'xml', contains: [ diff --git a/packages/highlight/src/languages/vlang.ts b/packages/highlight/src/languages/vlang.ts new file mode 100644 index 0000000000..534d63aa14 --- /dev/null +++ b/packages/highlight/src/languages/vlang.ts @@ -0,0 +1,161 @@ +// +// Copyright © 2024 Hardcore Engineering Inc. +// +// Licensed under the Eclipse Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. You may +// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// + +const LITERALS = ['true', 'false', 'nil'] + +const BUILT_INS = [ + 'close', + 'dump', + 'eprint', + 'eprintln', + 'error', + 'exit', + 'it', + 'panic', + 'print_backtrace', + 'print', + 'println' +] + +const TYPES = [ + 'bool', + 'string', + 'i8', + 'i16', + 'i32', + 'i64', + 'i128', + 'int', + 'u8', + 'u16', + 'u32', + 'u64', + 'u128', + 'rune', + 'f32', + 'f64', + 'isize', + 'usize', + 'voidptr', + 'charptr', + 'byteptr', + 'thread' +] + +const KWS = [ + 'as', + 'asm', + 'assert', + 'atomic', + 'break', + 'const', + 'continue', + 'defer', + 'else', + 'enum', + 'fn', + 'for', + 'go', + 'goto', + 'if', + 'import', + 'in', + 'interface', + 'is', + 'isreftype', + 'lock', + 'match', + 'module', + 'mut', + 'nil', + 'none', + 'or', + 'pub', + 'return', + 'rlock', + 'select', + 'shared', + 'sizeof', + 'spawn', + 'static', + 'struct', + 'type', + 'typeof', + 'union', + 'unsafe', + 'volatile', + '__global', + '__offsetof' +] + +export function vlang (hljs: any): any { + const KEYWORDS = { + keyword: KWS, + type: TYPES, + literal: LITERALS, + built_in: BUILT_INS + } + return { + name: 'V', + aliases: ['vlang'], + keywords: KEYWORDS, + illegal: '