Skip to content

Commit

Permalink
feat: Add codemirror syntax highlighting back in and move to a static…
Browse files Browse the repository at this point in the history
… color (#1080)

* feat: Add codemirror syntax highlighting back in and move to a static value for selection color

* feat: Add CSS language

* docs(changeset): Add syntax highlighting back to codemirror
  • Loading branch information
geoffgscott committed Feb 29, 2024
1 parent 1f2921f commit 5bc2ebf
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 27 deletions.
13 changes: 13 additions & 0 deletions .changeset/selfish-pets-live.md
@@ -0,0 +1,13 @@
---
"@scalar/fastify-api-reference": patch
"@scalar/api-client-proxy": patch
"@scalar/swagger-editor": patch
"@scalar/swagger-parser": patch
"@scalar/use-codemirror": patch
"@scalar/api-reference": patch
"@scalar/echo-server": patch
"@scalar/api-client": patch
"@scalar/components": patch
---

Add syntax highlighting back to codemirror
@@ -1,11 +1,11 @@
<script setup lang="ts">
import { CodeMirror, type CodeMirrorLanguage } from '@scalar/use-codemirror'
import { ref } from 'vue'
import { computed, ref } from 'vue'
import { isJsonString } from '../../helpers'
import { type SwaggerEditorInputProps } from '../../types'
defineProps<SwaggerEditorInputProps>()
const props = defineProps<SwaggerEditorInputProps>()
defineEmits<{
(e: 'contentUpdate', value: string): void
Expand All @@ -22,14 +22,16 @@ const codeMirrorRef = ref<typeof CodeMirror | null>(null)
function getSyntaxHighlighting(content?: string): CodeMirrorLanguage {
return isJsonString(content) ? 'json' : 'yaml'
}
const language = computed(() => getSyntaxHighlighting(props.value))
</script>

<template>
<div class="swagger-editor-input">
<CodeMirror
ref="codeMirrorRef"
:content="value"
:language="getSyntaxHighlighting(value)"
:language="language"
lineNumbers
@change="(value: string) => $emit('contentUpdate', value)" />
</div>
Expand Down
4 changes: 3 additions & 1 deletion packages/use-codemirror/package.json
Expand Up @@ -41,10 +41,12 @@
"directory": "packages/use-codemirror"
},
"dependencies": {
"@codemirror/autocomplete": "^6.12.0",
"@codemirror/lang-css": "^6.2.1",
"@codemirror/lang-html": "^6.4.8",
"@codemirror/lang-json": "^6.0.0",
"@codemirror/lang-yaml": "^6.0.0",
"@codemirror/language": "^6.10.1",
"@codemirror/legacy-modes": "^6.0.0",
"@codemirror/state": "^6.4.0",
"@codemirror/view": "^6.23.1",
"@lezer/common": "^1.2.1",
Expand Down
55 changes: 43 additions & 12 deletions packages/use-codemirror/src/hooks/useCodeMirror.ts
@@ -1,11 +1,26 @@
import {
autocompletion,
closeBrackets,
closeBracketsKeymap,
completionKeymap,
} from '@codemirror/autocomplete'
import { css } from '@codemirror/lang-css'
import { html } from '@codemirror/lang-html'
import { json } from '@codemirror/lang-json'
import { type LanguageSupport, StreamLanguage } from '@codemirror/language'
import * as yamlMode from '@codemirror/legacy-modes/mode/yaml'
import { yaml } from '@codemirror/lang-yaml'
import {
type LanguageSupport,
type StreamLanguage,
bracketMatching,
defaultHighlightStyle,
indentOnInput,
syntaxHighlighting,
} from '@codemirror/language'
import { type Extension, StateEffect } from '@codemirror/state'
import {
EditorView,
type KeyBinding,
highlightSpecialChars,
keymap,
lineNumbers as lineNumbersExtension,
} from '@codemirror/view'
Expand Down Expand Up @@ -212,15 +227,16 @@ export const useCodeMirror = (

// ---------------------------------------------------------------------------

const syntaxHighlighting: {
[lang in CodeMirrorLanguage]: LanguageSupport | StreamLanguage<any>
const languageExtensions: {
[lang in CodeMirrorLanguage]: () => LanguageSupport | StreamLanguage<any>
} = {
html: html(),
json: json(),
yaml: StreamLanguage.define(yamlMode.yaml),
html: html,
json: json,
yaml: yaml,
css: css,
}

/** Generate the list of extension from parameters */
/** Generate the list of extension from parameters */
function getCodeMirrorExtensions({
onChange,
onBlur,
Expand Down Expand Up @@ -249,7 +265,8 @@ function getCodeMirrorExtensions({
additionalExtensions?: Extension[]
}) {
const extensions: Extension[] = [
keymap.of([selectAllKeyBinding]),
highlightSpecialChars(),
syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
EditorView.theme({
'.cm-line': {
lineHeight: '20px',
Expand Down Expand Up @@ -283,11 +300,25 @@ function getCodeMirrorExtensions({
if (!withoutTheme) extensions.push(customTheme)

// Read only
if (readOnly) extensions.push(EditorView.editable.of(false))
if (readOnly) {
extensions.push(EditorView.editable.of(false))
} else {
extensions.push(
indentOnInput(),
bracketMatching(),
autocompletion(),
closeBrackets(),
keymap.of([
...completionKeymap,
...closeBracketsKeymap,
selectAllKeyBinding,
]),
)
}

// Syntax highlighting
if (language && typeof syntaxHighlighting[language] === 'string') {
extensions.push(syntaxHighlighting[language] as Extension)
if (language && languageExtensions[language]) {
extensions.push(languageExtensions[language]())
}

// Line numbers
Expand Down
3 changes: 2 additions & 1 deletion packages/use-codemirror/src/themes/index.ts
Expand Up @@ -7,7 +7,8 @@ export const customTheme = createTheme({
background: 'var(--theme-background-2, var(--default-theme-background-2))',
foreground: 'var(--theme-color-1, var(--default-theme-color-1))',
caret: 'var(--theme-color-1, var(--default-theme-color-1))',
selection: 'var(--theme-background-3, var(--default-theme-background-3))',
// Selection likely needs a hardcoded color due to it not accepting variables
selection: 'rgba(151, 183, 205, 0.2)',
selectionMatch: '#e3dcce',
gutterBackground:
'var(--theme-background-2, var(--default-theme-background-2))',
Expand Down
2 changes: 1 addition & 1 deletion packages/use-codemirror/src/types.ts
@@ -1 +1 @@
export type CodeMirrorLanguage = 'html' | 'json' | 'yaml'
export type CodeMirrorLanguage = 'html' | 'json' | 'yaml' | 'css'
38 changes: 29 additions & 9 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 5bc2ebf

Please sign in to comment.