├── .eslintrc
├── .gitignore
├── .nvmrc
├── .yarn
└── install-state.gz
├── .yarnrc.yml
├── README.md
├── components
├── CodeEditor
│ ├── CodeEditor.js
│ └── index.js
├── CodeEditorOld
│ ├── CodeEditor.js
│ ├── CodeEditor.module.scss
│ ├── CodeEditorSetup.js
│ ├── CodeEditorUtils.js
│ └── index.js
├── CodeMirror6Instance
│ ├── CodeMirror6Instance.js
│ ├── CodeMirror6InstanceHooks.js
│ ├── extensions
│ │ ├── autocomplete.js
│ │ ├── codeFolding.js
│ │ ├── defaultExtensions.js
│ │ ├── emmet.js
│ │ ├── extensions.js
│ │ ├── fonts.js
│ │ ├── indentation.js
│ │ ├── index.js
│ │ ├── languages.js
│ │ ├── lineNumbers.js
│ │ ├── lineWrapping.js
│ │ ├── matchBrackets.js
│ │ ├── onChange.js
│ │ ├── readOnly.js
│ │ ├── themes.js
│ │ ├── themes
│ │ │ ├── OLD
│ │ │ │ ├── classic.module.scss
│ │ │ │ ├── duotone-dark.module.scss
│ │ │ │ ├── duotone-light.module.scss
│ │ │ │ ├── highcontrast-dark.module.scss
│ │ │ │ ├── highcontrast-light.module.scss
│ │ │ │ ├── mdn-like.module.scss
│ │ │ │ ├── oceanic-dark.module.scss
│ │ │ │ ├── oceanic-light.module.scss
│ │ │ │ ├── panda.module.scss
│ │ │ │ ├── solarized-dark.module.scss
│ │ │ │ ├── solarized-light.module.scss
│ │ │ │ ├── synthwave.module.scss
│ │ │ │ ├── tomorrow-night.module.scss
│ │ │ │ ├── twilight.module.scss
│ │ │ │ └── xq-light.module.scss
│ │ │ ├── debug.js
│ │ │ ├── highContrastDark.js
│ │ │ └── twilight.js
│ │ ├── useExtensionCompartment.js
│ │ └── useExtensions.js
│ └── index.js
├── CodeSamples
│ ├── CodeSamples.js
│ ├── CodeSamples.module.scss
│ └── index.js
└── EditorSettings
│ ├── EditorSettings.js
│ ├── EditorSettings.module.scss
│ └── index.js
├── data
├── code.js
├── editorSettings.js
├── languages.js
└── supportLevels.js
├── netlify.toml
├── next.config.js
├── package.json
├── pages
├── _app.js
├── _document.js
├── console.js
├── index.js
├── shared.js
├── sync.js
└── yjs.js
├── styles
├── Home.module.scss
├── OLD-THEMES
│ ├── _theme-bits.scss
│ ├── classic.scss
│ ├── duotone-dark.scss
│ ├── duotone-light.scss
│ ├── highcontrast-dark.scss
│ ├── highcontrast-light.scss
│ ├── mdn-like.scss
│ ├── oceanic-dark.scss
│ ├── oceanic-light.scss
│ ├── panda.scss
│ ├── solarized-dark.scss
│ ├── solarized-light.scss
│ ├── tomorrow-night.scss
│ ├── twilight.scss
│ └── xq-light.scss
└── globals.css
└── yarn.lock
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["next", "next/core-web-vitals"]
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env.local
29 | .env.development.local
30 | .env.test.local
31 | .env.production.local
32 |
33 | # vercel
34 | .vercel
35 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v16.15.0
--------------------------------------------------------------------------------
/.yarn/install-state.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codepen/CodeMirror-6-Needs/e0a3964977ae107bf67956a0ae32e87eb261483b/.yarn/install-state.gz
--------------------------------------------------------------------------------
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | nodeLinker: node-modules
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # A Playground to Figure Out Everything We Need Out of CodeMirror 6
2 |
3 | It's a [Next.js](https://nextjs.org/docs) app as that is the context we hope to be using [CodeMirror 6](https://codemirror.net/6/) in.
4 |
5 | Here's [a quick Netlify deployment](https://objective-blackwell-d4efc9.netlify.app/) to see what we mean.
6 |
7 | # TODOs
8 |
9 | - [ ] Port all our [existing syntax highlighting](https://github.com/codepen/CodeMirror-6-Needs/tree/main/styles/OLD-THEMES) themes to the [new format](https://github.com/codepen/CodeMirror-6-Needs/blob/main/themes/twilight.js).
10 |
11 | - [ ] Make [language packages](https://codemirror.net/6/examples/lang-package/) for...
12 |
13 | - [ ] Haml
14 | - [ ] Slim
15 | - [ ] Nunjucks
16 | - [ ] Sass (.scss format)
17 | - [ ] Sass (.sass format)
18 | - [ ] Less
19 | - [ ] Stylus
20 | - [ ] JSX (supported with JS package?)
21 | - [ ] CoffeeScript
22 | - [ ] TypeScript
23 | - [ ] LiveScript
24 |
25 | - [ ] Make [Emmet Work](https://github.com/emmetio/codemirror-plugin/issues/13)
26 |
27 | - [ ] [Search functionality](https://codemirror.net/6/docs/ref/#search)
28 |
29 | - [ ] [Commenting Functionality](https://codemirror.net/6/docs/ref/#comment)
30 |
31 | - [ ] Decide on supporting [Rectangular Selection](https://codemirror.net/6/docs/ref/#rectangular-selection)
32 |
33 | # Concerns
34 |
35 | - **Bundle Size**: With all the various packages needed for CM6, will the final bundle come down to an acceptable size? This repo is odd in that it includes Prettier at the moment to replicate our cody tidying features and for changing indentation, and that represents most of the JavaScript in the bundle. How can we see _only_ what CodeMirror contributes? `yarn run analyze` makes a visualization, so if we could remove Prettier from that it would be more accurate.
36 |
37 | - **Key Bindings**: CodeMirror 5 support Sublime Text and Vim key bindings. It's not clear if CodeMirror 6 does. Do we absolutely need them or not?
38 |
39 | # Notes from Marijn Haverbeke we need to look at
40 |
41 | - "Indent Width" is controlled with the `indentUnit` [1] facet. There's autoindentation logic and an `indentSelection` command, but I don't think there currently is a convenient way to reindent the entire document. Not sure if doing that implicitly would be a good idea—it might mess up manual formatting or even break things in whitespace-sensitive languages.
42 |
43 | - "Tabs or Spaces" whether autoindentation uses tabs or spaces is also controlled by `indentUnit` [1]. The column width of tabs is controlled by `EditorState.tabSize` [2]
44 |
45 | - "Line Wrapping" is enabled with the `EditorView.lineWrapping` extension [3].
46 |
47 | - "Autocomplete" -- there's a rather solid module for handling autocompletion, but only robust completion sources for a few languages (HTML, XML, SQL). I have some unconcrete plans for adding some form of scope tracking to the system, which could help a lot with completion in languages like JS, but I don't know if/when that will materialize.
48 |
49 | - "Font Size" you can just change with CSS, and then follow up with a call to `requestMeasure` [4] to make sure the editor adjusts its internal info about the layout.
50 |
51 | - "Do we have to re-initialize the editor to change the theme or can we dispatch a change for a dynamically imported theme?" if you reconfigure [5] your theme extension, the highlighting will update immediately.
52 |
53 | - "Key bindings": There's some people working on vim bindings, but I don't have plans to port over the Sublime and Emacs bindings in the near future. The default bindings are based on VS Code (though they don't cover everything VS Code does).
54 |
55 | [1]: https://codemirror.net/6/docs/ref/#language.indentUnit
56 | [2]: https://codemirror.net/6/docs/ref/#state.EditorState%5EtabSize
57 | [3]: https://codemirror.net/6/docs/ref/#view.EditorView^lineWrapping
58 | [4]: https://codemirror.net/6/docs/ref/#view.EditorView.requestMeasure
59 | [5]: https://codemirror.net/6/examples/config/#dynamic-configuration
60 |
--------------------------------------------------------------------------------
/components/CodeEditor/CodeEditor.js:
--------------------------------------------------------------------------------
1 | import CodeMirror6Instance from "../CodeMirror6Instance";
2 |
3 | export default function CodeEditor({
4 | title,
5 | language,
6 | value,
7 | editorSettings,
8 | onInit,
9 | ...props
10 | }) {
11 | return (
12 |
13 |
19 |
20 | );
21 | }
22 |
--------------------------------------------------------------------------------
/components/CodeEditor/index.js:
--------------------------------------------------------------------------------
1 | import CodeEditor from "./CodeEditor";
2 |
3 | export default CodeEditor;
4 |
--------------------------------------------------------------------------------
/components/CodeEditorOld/CodeEditor.js:
--------------------------------------------------------------------------------
1 | import { useRef, useEffect } from "react";
2 | // import dynamic from "next/dynamic";
3 | import classNames from "classnames";
4 | import { editorSetup } from "./CodeEditorSetup";
5 | import { EditorState, Compartment } from "@codemirror/state";
6 | import { EditorView, keymap } from "@codemirror/view";
7 | import { defaultTabBinding } from "@codemirror/commands";
8 | import { adjustIndentWidth, CodeMirrorLanguageByType } from "./CodeEditorUtils";
9 | import styles from "./CodeEditor.module.scss";
10 | import { LANGUAGES } from "../../data/languages";
11 |
12 | // TODO: Attempt dynamic imports
13 | // https://nextjs.org/docs/advanced-features/dynamic-import#with-named-exports
14 | // const DynamicComponent = dynamic(
15 | // () =>
16 | // import("../../themes/twilight").then((mod) => {
17 | // console.log("mod", { mod });
18 | // return mod.twilight;
19 | // }),
20 | // {
21 | // ssr: false,
22 | // }
23 | // );
24 | // console.log(DynamicComponent);
25 |
26 | // import { oneDark } from "@codemirror/theme-one-dark";
27 |
28 | // TODO: Convert more themes, dynamically load them when requested.
29 | import { twilight } from "../../themes/twilight";
30 | // TODO: In reality we won't load multiple themes at once.
31 | import { oneDark } from "../../themes/oneDark";
32 |
33 | // TODO: EditorSettings - rebuild with new settings or try to update compartments?
34 |
35 | export default function CodeEditor({
36 | className,
37 | title,
38 | language,
39 | value,
40 | editorSettings,
41 | working,
42 | workingNotes,
43 | style,
44 | ...props
45 | }) {
46 | const indentWidth = Number(editorSettings.indentWidth);
47 | const container = useRef();
48 | const view = useRef();
49 | const compartments = {
50 | language: new Compartment(),
51 | tabSize: new Compartment(),
52 | // indentUnit: new Compartment(),
53 | };
54 |
55 | // TODO: Dynamic language switching without destroying the whole instance. Do we need lifecycle Component methods?
56 | useEffect(() => {
57 | // To prevent Next.js fast refresh from adding additional editors
58 | if (container.current.children[0]) container.current.children[0].remove();
59 |
60 | const lang = CodeMirrorLanguageByType(language);
61 | let langOptions = {};
62 | if (language === LANGUAGES.JSX) {
63 | langOptions.jsx = true;
64 | }
65 |
66 | let theme = twilight;
67 | if (editorSettings.theme === "oneDark") {
68 | theme = oneDark;
69 | }
70 |
71 | let startState = EditorState.create({
72 | doc: value,
73 | extensions: [
74 | editorSetup(editorSettings),
75 | keymap.of(defaultTabBinding),
76 | compartments.tabSize.of(EditorState.tabSize.of(indentWidth)),
77 | // compartments.indentUnit.of(EditorState.indentUnit.of(indentUnit)),
78 | compartments.language.of(lang && lang(langOptions)),
79 | theme,
80 | ],
81 | });
82 |
83 | let editorView = new EditorView({
84 | state: startState,
85 | parent: container.current,
86 | lineWrapping: editorSettings.lineWrapping,
87 | });
88 |
89 | view.current = editorView;
90 |
91 | return () => {
92 | editorView.destroy();
93 | };
94 | }, [
95 | indentWidth,
96 | editorSettings.indentUnit,
97 | editorSettings.lineWrapping,
98 | editorSettings.lineNumbers,
99 | editorSettings.codeFolding,
100 | editorSettings.autocomplete,
101 | editorSettings.matchBrackets,
102 | editorSettings.theme,
103 | ]);
104 |
105 | useEffect(() => {
106 | if (view.current) {
107 | // TODO: Try to dispatch rather than rebuild.
108 | // view.current.dispatch({
109 | // effects: compartments.tabSize.reconfigure(
110 | // EditorState.tabSize.of(indentWidth)
111 | // ),
112 | // });
113 |
114 | const formattedValue = adjustIndentWidth({
115 | indentWidth,
116 | language,
117 | value,
118 | });
119 | view.current.dispatch(
120 | view.current.state.update({
121 | changes: {
122 | from: 0,
123 | to: view.current.state.doc.length,
124 | insert: formattedValue,
125 | },
126 | })
127 | );
128 | }
129 | }, [indentWidth, language, value]);
130 |
131 | const { fontSize, fontFamily } = editorSettings;
132 | useEffect(() => {
133 | // Is there a better way to "refresh" the view if font-size and such change?
134 | view.current.requestMeasure();
135 | }, [fontSize, fontFamily]);
136 |
137 | // TODO: This doesn't work. But it feels like it would be better to dispatch a change to the theme.
138 | const { theme } = editorSettings;
139 | // useEffect(() => {
140 | // if (theme === "twilight") {
141 | // view.current.dispatch({
142 | // effects: compartments.theme.reconfigure(twilight),
143 | // });
144 | // }
145 | // if (theme === "oneDark") {
146 | // view.current.dispatch({
147 | // effects: compartments.theme.reconfigure(oneDark),
148 | // });
149 | // }
150 | // }, [theme]);
151 |
152 | return (
153 |
163 | );
164 | }
165 |
--------------------------------------------------------------------------------
/components/CodeEditorOld/CodeEditor.module.scss:
--------------------------------------------------------------------------------
1 | .editor {
2 | :global(.cm-scroller) {
3 | font-size: var(--font-size);
4 | /* For some reason, the default .cm-scroller styles have an !important font family declaration. */
5 | font-family: var(--font-family) !important;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/components/CodeEditorOld/CodeEditorSetup.js:
--------------------------------------------------------------------------------
1 | import {
2 | highlightSpecialChars,
3 | drawSelection,
4 | highlightActiveLine,
5 | keymap,
6 | } from "@codemirror/view";
7 | export { EditorView } from "@codemirror/view";
8 | import { EditorState } from "@codemirror/state";
9 | export { EditorState } from "@codemirror/state";
10 | import { history, historyKeymap } from "@codemirror/history";
11 | import { foldGutter, foldKeymap } from "@codemirror/fold";
12 | import { indentOnInput } from "@codemirror/language";
13 | import { lineNumbers, highlightActiveLineGutter } from "@codemirror/gutter";
14 | import { defaultKeymap } from "@codemirror/commands";
15 | import { bracketMatching } from "@codemirror/matchbrackets";
16 | import { closeBrackets, closeBracketsKeymap } from "@codemirror/closebrackets";
17 | import { highlightSelectionMatches, searchKeymap } from "@codemirror/search";
18 | import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
19 | import { commentKeymap } from "@codemirror/comment";
20 | import { rectangularSelection } from "@codemirror/rectangular-selection";
21 | import { defaultHighlightStyle } from "@codemirror/highlight";
22 | import { lintKeymap } from "@codemirror/lint";
23 |
24 | /*
25 | - [the default command bindings](https://codemirror.net/6/docs/ref/#commands.defaultKeymap)
26 | - [line numbers](https://codemirror.net/6/docs/ref/#gutter.lineNumbers)
27 | - [special character highlighting](https://codemirror.net/6/docs/ref/#view.highlightSpecialChars)
28 | - [the undo history](https://codemirror.net/6/docs/ref/#history.history)
29 | - [a fold gutter](https://codemirror.net/6/docs/ref/#fold.foldGutter)
30 | - [custom selection drawing](https://codemirror.net/6/docs/ref/#view.drawSelection)
31 | - [multiple selections](https://codemirror.net/6/docs/ref/#state.EditorState^allowMultipleSelections)
32 | - [reindentation on input](https://codemirror.net/6/docs/ref/#language.indentOnInput)
33 | - [the default highlight style](https://codemirror.net/6/docs/ref/#highlight.defaultHighlightStyle) (as fallback)
34 | - [bracket matching](https://codemirror.net/6/docs/ref/#matchbrackets.bracketMatching)
35 | - [bracket closing](https://codemirror.net/6/docs/ref/#closebrackets.closeBrackets)
36 | - [autocompletion](https://codemirror.net/6/docs/ref/#autocomplete.autocompletion)
37 | - [rectangular selection](https://codemirror.net/6/docs/ref/#rectangular-selection.rectangularSelection)
38 | - [active line highlighting](https://codemirror.net/6/docs/ref/#view.highlightActiveLine)
39 | - [active line gutter highlighting](https://codemirror.net/6/docs/ref/#gutter.highlightActiveLineGutter)
40 | - [selection match highlighting](https://codemirror.net/6/docs/ref/#search.highlightSelectionMatches)
41 | - [search](https://codemirror.net/6/docs/ref/#search.searchKeymap)
42 | - [commenting](https://codemirror.net/6/docs/ref/#comment.commentKeymap)
43 | - [linting](https://codemirror.net/6/docs/ref/#lint.lintKeymap)
44 | */
45 |
46 | const alwaysOn = [
47 | highlightSpecialChars(),
48 | history(),
49 | drawSelection(),
50 | EditorState.allowMultipleSelections.of(true),
51 | indentOnInput(),
52 | defaultHighlightStyle.fallback,
53 | rectangularSelection(),
54 | highlightActiveLine(),
55 | highlightSelectionMatches(),
56 | keymap.of([
57 | ...closeBracketsKeymap,
58 | ...defaultKeymap,
59 | ...searchKeymap,
60 | ...historyKeymap,
61 | ...foldKeymap,
62 | ...commentKeymap,
63 | ...completionKeymap,
64 | ...lintKeymap,
65 | ]),
66 | ];
67 |
68 | function editorSetup(editorSettings) {
69 | let completeSetup = [...alwaysOn];
70 |
71 | // NOTE: Order matters here!
72 | // If foldGutter went first, it will render to the left of the line numbers in the gutter.
73 | if (editorSettings.lineNumbers) {
74 | completeSetup.push(lineNumbers());
75 | completeSetup.push(highlightActiveLineGutter());
76 | }
77 |
78 | if (editorSettings.codeFolding) {
79 | completeSetup.push(foldGutter());
80 | }
81 | if (editorSettings.autocomplete) {
82 | completeSetup.push(autocompletion());
83 | }
84 |
85 | if (editorSettings.matchBrackets) {
86 | completeSetup.push(bracketMatching());
87 | completeSetup.push(closeBrackets());
88 | }
89 |
90 | return completeSetup;
91 | }
92 |
93 | export { editorSetup };
94 |
--------------------------------------------------------------------------------
/components/CodeEditorOld/CodeEditorUtils.js:
--------------------------------------------------------------------------------
1 | import { LANGUAGES } from "../../data/languages";
2 |
3 | // TODO: Dynamic imports
4 | import { css } from "@codemirror/lang-css";
5 | import { html } from "@codemirror/lang-html";
6 | import { javascript } from "@codemirror/lang-javascript";
7 | import { markdown } from "@codemirror/lang-markdown";
8 |
9 | import prettier from "prettier/standalone";
10 | import parserBabel from "prettier/parser-babel";
11 | import parserHtml from "prettier/parser-html";
12 | import parserCss from "prettier/parser-postcss";
13 |
14 | export function CodeMirrorLanguageByType(type) {
15 | switch (type) {
16 | // These seem fine
17 | case LANGUAGES.HTML:
18 | return html;
19 | case LANGUAGES.CSS:
20 | return css;
21 | case LANGUAGES.MARKDOWN:
22 | return markdown;
23 |
24 | case LANGUAGES.JAVASCRIPT:
25 | case LANGUAGES.JSX:
26 | return javascript;
27 |
28 | // TODO: Not quite right.
29 | case LANGUAGES.SCSS:
30 | case LANGUAGES.SASS:
31 | case LANGUAGES.LESS:
32 | case LANGUAGES.STYLUS:
33 | return css;
34 |
35 | // TODO entirely
36 | case LANGUAGES.HAML:
37 | case LANGUAGES.PUG:
38 | case LANGUAGES.SLIM:
39 | case LANGUAGES.NUNJUCKS:
40 | return html;
41 |
42 | case LANGUAGES.COFFEESCRIPT:
43 | case LANGUAGES.TYPESCRIPT:
44 | case LANGUAGES.LIVESCRIPT:
45 | return javascript;
46 | }
47 | }
48 |
49 | export function adjustIndentWidth({ language, value, indentWidth }) {
50 | // TODO: Only do Prettier on an Indent Width change.
51 | // TODO: See if CodeMirror has an official way of doing indentation changes.
52 | // Do Prettier!
53 | // https://prettier.io/docs/en/browser.html
54 | let parser = "babel";
55 | if (language === "html") parser = "html";
56 | if (language === "scss" || language === "css" || parser === "less")
57 | parser = "css";
58 | // TODO: Do Prettier on the other supported languages
59 | if (
60 | language === "js" ||
61 | language === "html" ||
62 | language === "css" ||
63 | language === "scss" ||
64 | language === "less"
65 | ) {
66 | // prettier can throw hard errors if the parser fails.
67 | try {
68 | // replace entire document with prettified version
69 | const formattedValue = prettier.format(value, {
70 | parser: parser,
71 | plugins: [parserBabel, parserHtml, parserCss],
72 | tabWidth: indentWidth,
73 | // semi: true,
74 | trailingComma: "none",
75 | // useTabs: indentWith === "tabs",
76 | bracketSpacing: true,
77 | jsxBracketSameLine: false,
78 | });
79 | return formattedValue;
80 | } catch (err) {
81 | console.error(err);
82 | }
83 | }
84 | return value;
85 | }
86 |
--------------------------------------------------------------------------------
/components/CodeEditorOld/index.js:
--------------------------------------------------------------------------------
1 | import CodeEditor from "./CodeEditor";
2 |
3 | export default CodeEditor;
4 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/CodeMirror6Instance.js:
--------------------------------------------------------------------------------
1 | import { useCodeMirror6Instance } from "./CodeMirror6InstanceHooks";
2 | import PropTypes from "prop-types";
3 | import { INDENT_VALUES } from "../../data/editorSettings";
4 |
5 | function CodeMirror6Instance(props) {
6 | const cm6props = useCodeMirror6Instance(props);
7 | return
;
8 | }
9 |
10 | CodeMirror6Instance.propTypes = {
11 | value: PropTypes.string,
12 | state: PropTypes.object,
13 | extensions: PropTypes.arrayOf(
14 | PropTypes.oneOfType([PropTypes.object, PropTypes.func])
15 | ),
16 | onInit: PropTypes.func,
17 | onChange: PropTypes.func,
18 | readOnly: PropTypes.bool,
19 | editorSettings: PropTypes.shape({
20 | theme: PropTypes.string,
21 | fontSize: PropTypes.number,
22 | lineHeight: PropTypes.number,
23 | fontFamily: PropTypes.string,
24 | indentWidth: PropTypes.number,
25 | indentUnit: PropTypes.oneOf(Object.values(INDENT_VALUES)),
26 | lineNumbers: PropTypes.bool,
27 | lineWrapping: PropTypes.bool,
28 | codeFolding: PropTypes.bool,
29 | matchBrackets: PropTypes.bool,
30 | autocomplete: PropTypes.bool,
31 | emmet: PropTypes.bool,
32 | }),
33 | };
34 |
35 | export default CodeMirror6Instance;
36 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/CodeMirror6InstanceHooks.js:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef, useState } from "react";
2 | import { EditorState } from "@codemirror/state";
3 | import { EditorView } from "codemirror";
4 | import { useExtensions } from "./extensions/useExtensions";
5 |
6 | export function useCodeMirror6Instance(props) {
7 | const ref = useRef();
8 | const [editorView, setEditorView] = useState(null);
9 |
10 | const extensions = useExtensions(props, editorView);
11 |
12 | // Initialize CodeMirror6 View
13 | useEffect(() => {
14 | const editorState =
15 | props.state ||
16 | EditorState.create({
17 | doc: props.value,
18 | extensions,
19 | });
20 |
21 | const editorView = new EditorView({
22 | state: editorState,
23 | parent: ref.current,
24 | });
25 |
26 | // NOTE: State is available as `editorView.state`
27 | setEditorView(editorView);
28 |
29 | props.onInit && props.onInit(editorView);
30 |
31 | // Destroy when unmounted.
32 | return () => editorView.destroy();
33 | // eslint-disable-next-line react-hooks/exhaustive-deps
34 | }, []);
35 |
36 | const { value } = props;
37 | useEffect(() => {
38 | const validValue = value || value === "";
39 | if (!editorView || !validValue) return;
40 |
41 | const currentValue = editorView.state.doc.toString();
42 | if (value !== currentValue) {
43 | // https://codemirror.net/docs/migration/#making-changes
44 | // NOTE: "To completely reset a state—for example to load a new document—it is recommended to create a new state instead of a transaction. That will make sure no unwanted state (such as undo history events) sticks around."
45 | // editorView.setState(EditorState.create())
46 | editorView.dispatch({
47 | changes: { from: 0, to: editorView.state.doc.length, insert: value },
48 | });
49 | }
50 | }, [value, editorView]);
51 |
52 | // Swap out state
53 | useEffect(() => {
54 | if (props.state && props.state !== editorView.state) {
55 | editorView.setState(props.state);
56 | }
57 | }, [props.state, editorView]);
58 |
59 | return { ref };
60 | }
61 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/autocomplete.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 | import { useExtensionCompartment } from "./useExtensionCompartment";
3 | import { autocompletion } from "@codemirror/autocomplete";
4 |
5 | export function useAutocomplete(editorSettings, editorView) {
6 | const [compartment, updateCompartment] = useExtensionCompartment(editorView);
7 |
8 | useEffect(() => {
9 | updateCompartment(editorSettings.autocomplete ? autocompletion() : []);
10 | }, [editorSettings.autocomplete, updateCompartment]);
11 |
12 | return compartment;
13 | }
14 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/codeFolding.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 | import { useExtensionCompartment } from "./useExtensionCompartment";
3 | import { codeFolding, foldGutter, foldKeymap } from "@codemirror/language";
4 | import { keymap } from "@codemirror/view";
5 |
6 | export function useCodeFolding(editorSettings, editorView) {
7 | const [compartment, updateCompartment] = useExtensionCompartment(editorView);
8 |
9 | useEffect(() => {
10 | updateCompartment(
11 | editorSettings.codeFolding
12 | ? [
13 | // https://codemirror.net/docs/ref/#language.codeFolding
14 | codeFolding(),
15 | keymap.of(foldKeymap),
16 | // https://codemirror.net/docs/ref/#language.foldGutter
17 | foldGutter(),
18 | ]
19 | : []
20 | );
21 | }, [editorSettings.codeFolding, updateCompartment]);
22 |
23 | return compartment;
24 | }
25 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/defaultExtensions.js:
--------------------------------------------------------------------------------
1 | import {
2 | crosshairCursor,
3 | drawSelection,
4 | dropCursor,
5 | highlightSpecialChars,
6 | keymap,
7 | rectangularSelection,
8 | } from "@codemirror/view";
9 | import {
10 | defaultKeymap,
11 | history,
12 | historyKeymap,
13 | indentWithTab,
14 | } from "@codemirror/commands";
15 | import { EditorState } from "@codemirror/state";
16 | import {
17 | defaultHighlightStyle,
18 | indentOnInput,
19 | syntaxHighlighting,
20 | } from "@codemirror/language";
21 | import { searchKeymap } from "@codemirror/search";
22 | import { lintKeymap } from "@codemirror/lint";
23 |
24 | // Adapted from basicSetup. Using this custom setup instead to better support our Editor Settings and desired CodePen experience.
25 | // https://codemirror.net/docs/ref/#codemirror.basicSetup
26 | // https://github.com/codemirror/basic-setup/blob/main/src/codemirror.ts
27 | // import { basicSetup } from "codemirror";
28 |
29 | export const defaultKeymaps = keymap.of([
30 | ...defaultKeymap,
31 | ...searchKeymap,
32 | ...historyKeymap,
33 | ...lintKeymap,
34 |
35 | // NOTE: This keymap refers to the `tab` key, NOT tabs vs spaces.
36 | // NOTE: `indentWithTab` should be loaded after Emmet to ensure Emmet completions can take precedence
37 | // NOTE: Warn users about ESC + Tab https://codemirror.net/examples/tab/
38 | indentWithTab,
39 | ]);
40 |
41 | export const defaultExtensions = [
42 | syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
43 | highlightSpecialChars(),
44 | history(),
45 |
46 | drawSelection(),
47 | // Multi cursor/select
48 | [
49 | EditorState.allowMultipleSelections.of(true),
50 | rectangularSelection(),
51 | crosshairCursor(),
52 | ],
53 |
54 | dropCursor(),
55 | indentOnInput(),
56 | defaultKeymaps,
57 | ];
58 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/emmet.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 | import { keymap } from "@codemirror/view";
3 |
4 | // Import Expand Abbreviation command
5 | import {
6 | abbreviationTracker,
7 | emmetConfig,
8 | expandAbbreviation,
9 | } from "@emmetio/codemirror6-plugin";
10 | import { useExtensionCompartment } from "./useExtensionCompartment";
11 | import { LANGUAGES } from "../../../data/languages";
12 | import { Prec } from "@codemirror/state";
13 |
14 | const emmetSupportedModes = [
15 | LANGUAGES.HTML,
16 | LANGUAGES.PUG,
17 | LANGUAGES.CSS,
18 | LANGUAGES.SCSS,
19 | LANGUAGES.STYLUS,
20 | LANGUAGES.LESS,
21 | LANGUAGES.JSX,
22 | // "sass",
23 | // "vue", // Is the mode in the Vue custom editor actually "js"?
24 | // May need JS here? for JSX?
25 | ];
26 |
27 | const validEmmetEditorMode = (mode) => {
28 | return emmetSupportedModes.includes(mode);
29 | };
30 |
31 | import { EmmetKnownSyntax } from "@emmetio/codemirror6-plugin";
32 |
33 | export const LANGUAGES_TO_EMMET_SYNTAX = {
34 | [LANGUAGES.CSS]: EmmetKnownSyntax.css,
35 | [LANGUAGES.HAML]: EmmetKnownSyntax.haml,
36 | [LANGUAGES.HTML]: EmmetKnownSyntax.html,
37 | [LANGUAGES.JSX]: EmmetKnownSyntax.jsx,
38 | [LANGUAGES.LESS]: EmmetKnownSyntax.css,
39 | [LANGUAGES.MARKDOWN]: EmmetKnownSyntax.html,
40 | [LANGUAGES.NUNJUCKS]: EmmetKnownSyntax.html,
41 | [LANGUAGES.VUE]: EmmetKnownSyntax.vue,
42 | [LANGUAGES.PUG]: EmmetKnownSyntax.pug,
43 | [LANGUAGES.SASS]: EmmetKnownSyntax.sass,
44 | [LANGUAGES.SCSS]: EmmetKnownSyntax.scss,
45 | [LANGUAGES.SLIM]: EmmetKnownSyntax.slim,
46 | [LANGUAGES.STYLUS]: EmmetKnownSyntax.stylus,
47 | };
48 |
49 | export function getEmmetSyntax(language) {
50 | const lang = language; // Gotta tell TypeScript to knock it off :rolling_eyes:
51 | if (lang && lang in LANGUAGES_TO_EMMET_SYNTAX) {
52 | return LANGUAGES_TO_EMMET_SYNTAX[lang];
53 | }
54 |
55 | return false;
56 | }
57 |
58 | export function useEmmetExtension(language, editorSettings, editorView) {
59 | const [compartment, updateCompartment] = useExtensionCompartment(editorView);
60 |
61 | const enabled = editorSettings.emmet;
62 |
63 | useEffect(() => {
64 | // Emmet only works properly on certain languages
65 | const canUseEmmet = enabled && validEmmetEditorMode(language);
66 |
67 | updateCompartment(
68 | canUseEmmet
69 | ? [
70 | emmetConfig.of({
71 | syntax: getEmmetSyntax(language),
72 | preview: true,
73 | config: {
74 | markup: {
75 | snippets: {
76 | foo: "invalid snippet",
77 | // The above will break this VALID snippet below:
78 | foo2: "button",
79 | },
80 | },
81 | stylesheet: {
82 | snippets: {},
83 | },
84 | },
85 | }),
86 |
87 | Prec.high(abbreviationTracker()),
88 | ]
89 | : []
90 | );
91 | }, [language, enabled, updateCompartment]);
92 |
93 | return compartment;
94 | }
95 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/extensions.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 | import { useExtensionCompartment } from "./useExtensionCompartment";
3 |
4 | export function useExtraExtensions({ extensions }, editorView) {
5 | const [compartment, updateCompartment] = useExtensionCompartment(editorView);
6 |
7 | useEffect(() => {
8 | updateCompartment(extensions || []);
9 | }, [extensions, updateCompartment]);
10 |
11 | return compartment;
12 | }
13 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/fonts.js:
--------------------------------------------------------------------------------
1 | import { useEffect, useMemo } from "react";
2 | import { EditorView } from "codemirror";
3 | import { useExtensionCompartment } from "./useExtensionCompartment";
4 |
5 | export function useFonts({ fontSize, fontFamily, lineHeight }, editorView) {
6 | const [compartment, updateCompartment] = useExtensionCompartment(editorView);
7 |
8 | // const Theme = useMemo(
9 | // () =>
10 | // []
11 | // );
12 |
13 | useEffect(() => {
14 | const Theme = EditorView.theme({
15 | "&": {
16 | fontSize: `${fontSize}px`,
17 | },
18 | ".cm-scroller": {
19 | fontFamily: fontFamily,
20 | lineHeight: lineHeight,
21 | },
22 | });
23 | updateCompartment([Theme]);
24 | }, [lineHeight, fontSize, fontFamily, updateCompartment]);
25 |
26 | return compartment;
27 | }
28 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/indentation.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 | import { useExtensionCompartment } from "./useExtensionCompartment";
3 |
4 | import { indentationMarkers } from "@replit/codemirror-indentation-markers";
5 | import { INDENT_VALUES } from "../../../data/editorSettings";
6 | import { indentUnit } from "@codemirror/language";
7 | import { EditorState } from "@codemirror/state";
8 |
9 | export function useIndentation(editorSettings, editorView) {
10 | const [compartment, updateCompartment] = useExtensionCompartment(editorView);
11 |
12 | const shouldIndentWithTab = editorSettings.indentUnit === INDENT_VALUES.TABS;
13 | const indentSize = editorSettings.indentWidth;
14 |
15 | useEffect(() => {
16 | const indentUnitValue = shouldIndentWithTab ? "\t" : " ".repeat(indentSize);
17 |
18 | updateCompartment([
19 | indentUnit.of(indentUnitValue),
20 | EditorState.tabSize.of(indentSize),
21 | indentationMarkers(),
22 | ]);
23 | }, [shouldIndentWithTab, indentSize, updateCompartment]);
24 |
25 | // TODO: convert tabs & spaces
26 | /*
27 | From: https://codemirror.net/examples/change/
28 | When dispatching a transaction, you can also pass an array of changes. The from/to in each of these changes refer to positions in the start document, not to the document created by previously listed changes.
29 |
30 | For example, to replace all tabs in a document with two spaces, you could do something like this:
31 |
32 | ```
33 | let text = view.state.doc.toString(), pos = 0
34 | let changes = []
35 | for (let next; (next = text.indexOf("\t", pos)) > -1;) {
36 | changes.push({from: next, to: next + 1, insert: " "})
37 | pos = next + 1
38 | }
39 | view.dispatch({changes})
40 | ```
41 | */
42 |
43 | return compartment;
44 | }
45 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/index.js:
--------------------------------------------------------------------------------
1 | export * from "./useExtensions";
2 | export * from "./useExtensionCompartment";
3 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/languages.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 | import { languages } from "@codemirror/language-data";
3 | import { useExtensionCompartment } from "./useExtensionCompartment";
4 | import { LANGUAGES } from "../../../data/languages";
5 |
6 | // TODO: Detect language by file extension
7 | // NOTE: May be able to use @codemirror/language-data for file extensions and lazy loading certain languages https://codemirror.net/docs/ref/#language.LanguageDescription
8 |
9 | function getLanguageFallback(language) {
10 | switch (language) {
11 | case LANGUAGES.NUNJUCKS:
12 | case LANGUAGES.PUG:
13 | case LANGUAGES.HAML:
14 | case LANGUAGES.SLIM:
15 | return LANGUAGES.HTML;
16 | }
17 |
18 | return language;
19 | }
20 |
21 | const htmlLanguage = languages.find((lang) => lang.name === "HTML");
22 |
23 | function getCodeMirrorLanguageData(language, matchBrackets) {
24 | language = getLanguageFallback(language);
25 |
26 | let languageData = languages.find(
27 | (lang) => lang.name === language || lang.alias.includes(language)
28 | );
29 |
30 | if (languageData === htmlLanguage) {
31 | // For HTML, we need to manually override the loader here to turn off `matchClosingTags` and `autoCloseTags` so that we can enable them.
32 | // TODO: Should this be a distinct option, or paired with `matchBrackets` for simplicity?
33 | languageData.load = function () {
34 | return import("@codemirror/lang-html").then((m) =>
35 | m.html({
36 | // `matchClosingTags` is part of the language configuration, so we can't easily split that off into a standalone extension.
37 | matchClosingTags: matchBrackets,
38 | // `autoCloseTags` is a separate extension exported from `@codemirror/lang-html` so we could split that out, but it kinda makes sense to just leave it here.
39 | autoCloseTags: matchBrackets,
40 | })
41 | );
42 | };
43 | }
44 |
45 | return languageData;
46 | }
47 |
48 | export function useLanguageExtension({ language, editorSettings }, editorView) {
49 | const [languageCompartment, updateCompartment] =
50 | useExtensionCompartment(editorView);
51 |
52 | const matchBrackets = editorSettings?.matchBrackets ? true : false;
53 |
54 | useEffect(() => {
55 | async function loadLanguage() {
56 | const lang = getCodeMirrorLanguageData(language, matchBrackets);
57 |
58 | if (lang) {
59 | const languageExtension = await lang.load();
60 | updateCompartment(languageExtension);
61 | }
62 | }
63 |
64 | loadLanguage();
65 | }, [language, matchBrackets, updateCompartment]);
66 |
67 | return languageCompartment;
68 | }
69 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/lineNumbers.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 | import { useExtensionCompartment } from "./useExtensionCompartment";
3 | import { lineNumbers } from "@codemirror/view";
4 |
5 | export function useLineNumbers(editorSettings, editorView) {
6 | const [compartment, updateCompartment] = useExtensionCompartment(editorView);
7 |
8 | useEffect(() => {
9 | updateCompartment(
10 | editorSettings.lineNumbers
11 | ? // https://codemirror.net/docs/ref/#view.lineNumbers
12 | lineNumbers()
13 | : []
14 | );
15 | }, [editorSettings.lineNumbers, updateCompartment]);
16 |
17 | return compartment;
18 | }
19 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/lineWrapping.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 | import { EditorView } from "codemirror";
3 | import { useExtensionCompartment } from "./useExtensionCompartment";
4 |
5 | export function useLineWrapping({ lineWrapping }, editorView) {
6 | const [compartment, updateCompartment] = useExtensionCompartment(editorView);
7 |
8 | useEffect(() => {
9 | updateCompartment(lineWrapping ? EditorView.lineWrapping : null);
10 | }, [lineWrapping, updateCompartment]);
11 |
12 | return compartment;
13 | }
14 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/matchBrackets.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 | import { useExtensionCompartment } from "./useExtensionCompartment";
3 | import { bracketMatching } from "@codemirror/language";
4 | import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
5 | import { keymap } from "@codemirror/view";
6 |
7 | export function useMatchBrackets({ matchBrackets }, editorView) {
8 | const [compartment, updateCompartment] = useExtensionCompartment(editorView);
9 |
10 | useEffect(() => {
11 | updateCompartment(
12 | matchBrackets
13 | ? [bracketMatching(), closeBrackets(), keymap.of(closeBracketsKeymap)]
14 | : []
15 | );
16 | }, [matchBrackets, updateCompartment]);
17 |
18 | return compartment;
19 | }
20 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/onChange.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 | import { useExtensionCompartment } from "./useExtensionCompartment";
3 | import { EditorView } from "codemirror";
4 |
5 | export function useOnChange({ onChange }, editorView) {
6 | const [compartment, updateCompartment] = useExtensionCompartment(editorView);
7 |
8 | useEffect(() => {
9 | updateCompartment(onChange ? EditorView.updateListener.of(onChange) : []);
10 | }, [onChange, updateCompartment]);
11 |
12 | return compartment;
13 | }
14 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/readOnly.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 | import { EditorState } from "@codemirror/state";
3 | import { useExtensionCompartment } from "./useExtensionCompartment";
4 | import {
5 | EditorView,
6 | highlightActiveLine,
7 | highlightActiveLineGutter,
8 | } from "@codemirror/view";
9 |
10 | const hideCursorTheme = EditorView.theme({
11 | ".cm-cursor-primary": {
12 | display: "none",
13 | opacity: 0,
14 | },
15 | });
16 |
17 | export function useReadOnly({ readOnly }, editorView) {
18 | const [compartment, updateCompartment] = useExtensionCompartment(editorView);
19 |
20 | useEffect(() => {
21 | const value = [EditorState.readOnly.of(readOnly)];
22 | if (readOnly) {
23 | // Hide cursor if read only
24 | value.push(hideCursorTheme);
25 | } else {
26 | // Highlight active lines if not read only
27 | value.push(highlightActiveLine(), highlightActiveLineGutter());
28 | }
29 | updateCompartment(value);
30 | }, [readOnly, updateCompartment]);
31 |
32 | return compartment;
33 | }
34 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/themes.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 | // import { oneDark } from "@codemirror/theme-one-dark";
3 |
4 | import { useExtensionCompartment } from "./useExtensionCompartment";
5 |
6 | import * as themeMirror from "thememirror";
7 | import { debug } from "./themes/debug";
8 |
9 | // TODO: Port themes
10 | // https://codemirror.net/examples/styling/
11 | // https://codemirror.net/docs/migration/#dom-structure
12 |
13 | export const THEMES = {
14 | HIGH_CONTRAST_DARK: "High Contrast Dark",
15 | TWILIGHT: "Twilight",
16 | ONE_DARK: "One Dark",
17 | // https://github.com/craftzdog/cm6-themes/
18 | SOLARIZED_DARK: "Solarized Dark",
19 | SOLARIZED_LIGHT: "Solarized Light",
20 | MATERIAL_DARK: "Material Dark",
21 | };
22 |
23 | export const THEME_LOADERS = {
24 | [THEMES.ONE_DARK]: () =>
25 | import("@codemirror/theme-one-dark").then(({ oneDark }) => oneDark),
26 | [THEMES.TWILIGHT]: () =>
27 | import("./themes/twilight").then(({ twilight }) => twilight),
28 | [THEMES.HIGH_CONTRAST_DARK]: () =>
29 | import("./themes/highContrastDark").then(
30 | ({ highContrastDark }) => highContrastDark
31 | ),
32 | [THEMES.SOLARIZED_DARK]: () =>
33 | import("cm6-theme-solarized-dark").then(
34 | ({ solarizedDark }) => solarizedDark
35 | ),
36 | [THEMES.SOLARIZED_LIGHT]: () =>
37 | import("cm6-theme-solarized-light").then(
38 | ({ solarizedLight }) => solarizedLight
39 | ),
40 | [THEMES.MATERIAL_DARK]: () =>
41 | import("cm6-theme-material-dark").then(({ materialDark }) => materialDark),
42 |
43 | // [THEMES.DRACULA]: () => import("thememirror").then(({ dracula }) => dracula),
44 | };
45 |
46 | // Automatically adding the ThemeMirror instead of manually setting up the lazy loading for each of these themes.
47 | Object.entries(themeMirror).forEach(([key, theme]) => {
48 | if (key !== "createTheme") {
49 | THEMES[key] = key;
50 | THEME_LOADERS[key] = () => theme;
51 | }
52 | });
53 |
54 | export function useThemeExtension({ theme }, editorView) {
55 | const [compartment, updateCompartment] = useExtensionCompartment(editorView);
56 |
57 | useEffect(() => {
58 | async function loadTheme() {
59 | const themeLoader = THEME_LOADERS[theme];
60 | if (themeLoader) {
61 | const loadedTheme = await themeLoader();
62 | updateCompartment([debug, loadedTheme]);
63 | }
64 | }
65 |
66 | loadTheme();
67 | }, [theme, updateCompartment]);
68 |
69 | return compartment;
70 | }
71 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/themes/OLD/classic.module.scss:
--------------------------------------------------------------------------------
1 | .root {
2 | --black: #000;
3 | --blue: #219;
4 | --red: #a11;
5 | --green: #164;
6 | --lightGray: #ccc;
7 | --midGray: #555;
8 | --purple: #708;
9 |
10 | background: white;
11 | color: #222;
12 |
13 | :global {
14 | .cm-keyword {
15 | // const, var, let
16 | color: var(--blue);
17 | }
18 | .cm-atom {
19 | // tag part of
20 | color: var(--blue);
21 | }
22 | .cm-def {
23 | // params part of function(params) {
24 | color: var(--purple);
25 | }
26 | .cm-variable {
27 | // coffeescript var
28 | color: var(--blue);
29 | }
30 | .cm-variable-2 {
31 | // for (key in [this]), markdown li, decimals without 0 in front
32 | color: var(--black);
33 | }
34 | .cm-variable-3 {
35 | color: var(--black);
36 | }
37 | .cm-header {
38 | color: var(--red);
39 | }
40 | .cm-number {
41 | color: var(--green);
42 | }
43 | .cm-property {
44 | // margin part of margin: 10px;, getElementById
45 | color: var(--blue);
46 | }
47 | .cm-attribute {
48 | color: var(--midGray);
49 | }
50 | .cm-builtin {
51 | color: var(--blue);
52 | }
53 | .cm-qualifier {
54 | color: var(--blue);
55 | }
56 | .cm-operator {
57 | // CoffeeScript ->
58 | color: var(--black);
59 | }
60 | .cm-meta {
61 | // @font-face
62 | color: var(--blue);
63 | }
64 | .cm-string {
65 | // href=["val"]
66 | color: var(--red);
67 | }
68 | .cm-string-2 {
69 | // match([this])
70 | color: var(--red);
71 | }
72 | .cm-tag {
73 | color: var(--blue);
74 | }
75 | .cm-bracket {
76 | color: var(--black);
77 | }
78 | .cm-comment {
79 | // /* this comment */
80 | color: var(--lightGray);
81 | }
82 | }
83 |
84 | // Mode Overrides
85 | &[data-mode='htmlmixed'] {
86 | :global {
87 | .cm-atom {
88 | color: var(--red);
89 | }
90 | }
91 | }
92 | &[data-mode='text/css'] {
93 | :global {
94 | .cm-tag {
95 | color: var(--blue);
96 | }
97 | }
98 | }
99 |
100 | :global {
101 | .CodeMirror-cursor {
102 | border-left-color: black;
103 | }
104 | .CodeMirror-selected {
105 | background: rgba(black, 0.05);
106 | }
107 | .CodeMirror-focused .CodeMirror-selected {
108 | background: rgba(black, 0.1);
109 | }
110 | .CodeMirror-matchingbracket,
111 | .CodeMirror-matchingtag {
112 | text-decoration: underline;
113 | text-decoration-color: rgba(black, 0.5);
114 | }
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/themes/OLD/duotone-dark.module.scss:
--------------------------------------------------------------------------------
1 | .root {
2 | --purple: #9b87fd;
3 | --orange: #ffcc99;
4 | --lightGray: #eeebff;
5 | --darkGray: #6c6783;
6 |
7 | background: #2a2734;
8 | color: var(--lightGray);
9 |
10 | :global {
11 | .cm-keyword {
12 | // const, var, let
13 | color: var(--orange);
14 | }
15 | .cm-atom {
16 | // tag part of
17 | color: var(--orange);
18 | }
19 | .cm-def {
20 | // params part of function(params) {
21 | color: var(--lightGray);
22 | }
23 | .cm-variable {
24 | // coffeescript var
25 | color: var(--orange);
26 | }
27 | .cm-variable-2 {
28 | // for (key in [this]), markdown li, decimals without 0 in front
29 | color: var(--purple);
30 | }
31 | .cm-variable-3 {
32 | color: var(--purple);
33 | }
34 | .cm-header {
35 | color: var(--lightGray);
36 | }
37 | .cm-number {
38 | color: var(--orange);
39 | }
40 | .cm-property {
41 | // margin part of margin: 10px;, getElementById
42 | color: var(--purple);
43 | }
44 | .cm-attribute {
45 | color: var(--orange);
46 | }
47 | .cm-builtin {
48 | color: var(--lightGray);
49 | }
50 | .cm-qualifier {
51 | color: var(--lightGray);
52 | }
53 | .cm-operator {
54 | // CoffeeScript ->
55 | color: var(--orange);
56 | }
57 | .cm-meta {
58 | // @font-face
59 | color: var(--orange);
60 | }
61 | .cm-string {
62 | // href=["val"]
63 | color: var(--orange);
64 | }
65 | .cm-string-2 {
66 | // match([this])
67 | color: var(--purple);
68 | }
69 | .cm-tag {
70 | color: var(--lightGray);
71 | }
72 | .cm-bracket {
73 | color: var(--darkGray);
74 | }
75 | .cm-comment {
76 | // /* this comment */
77 | color: var(--darkGray);
78 | }
79 | }
80 |
81 | :global {
82 | .CodeMirror-cursor {
83 | border-left-color: var(--lightGray);
84 | }
85 | .CodeMirror-selected {
86 | background: #221f2a;
87 | }
88 | .CodeMirror-focused .CodeMirror-selected {
89 | background: #3e3b51;
90 | }
91 | .CodeMirror-matchingbracket,
92 | .CodeMirror-matchingtag {
93 | text-decoration: underline;
94 | text-decoration-color: rgba(black, 0.5);
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/themes/OLD/duotone-light.module.scss:
--------------------------------------------------------------------------------
1 | .root {
2 | --lightTan: #b6ad9a;
3 | --tan: #b29762;
4 | --medTan: #896724;
5 | --darkTan: #2d2006;
6 | --blue: #1657da;
7 | --medBlue: #0e4ecd;
8 | --darkBlue: #063289;
9 |
10 | background: #faf8f5;
11 | color: var(--tan);
12 |
13 | :global {
14 | .cm-keyword {
15 | // const, var, let
16 | color: var(--tan);
17 | }
18 | .cm-atom {
19 | // tag part of
20 | color: var(--tan);
21 | }
22 | .cm-def {
23 | // params part of function(params) {
24 | color: var(--darkTan);
25 | }
26 | .cm-variable {
27 | // coffeescript var
28 | color: var(--tan);
29 | }
30 | .cm-variable-2 {
31 | // for (key in [this]), markdown li, decimals without 0 in front
32 | color: var(--tan);
33 | }
34 | .cm-variable-3 {
35 | color: var(--tan);
36 | }
37 | .cm-header {
38 | color: var(--darkTan);
39 | }
40 | .cm-number {
41 | color: var(--tan);
42 | }
43 | .cm-property {
44 | // margin part of margin: 10px;, getElementById
45 | color: var(--blue);
46 | }
47 | .cm-attribute {
48 | color: var(--tan);
49 | }
50 | .cm-builtin {
51 | color: var(--darkTan);
52 | }
53 | .cm-qualifier {
54 | color: var(--darkTan);
55 | }
56 | .cm-operator {
57 | // CoffeeScript ->
58 | color: var(--medBlue);
59 | }
60 | .cm-meta {
61 | // @font-face
62 | color: var(--tan);
63 | }
64 | .cm-string {
65 | // href=["val"]
66 | color: var(--darkBlue);
67 | }
68 | .cm-string-2 {
69 | // match([this])
70 | color: var(--tan);
71 | }
72 | .cm-tag {
73 | color: var(--darkTan);
74 | }
75 | .cm-bracket {
76 | color: var(--lightTan);
77 | }
78 | .cm-comment {
79 | // /* this comment */
80 | color: var(--lightTan);
81 | }
82 | }
83 |
84 | :global {
85 | .CodeMirror-cursor {
86 | border-left-color: black;
87 | }
88 | .CodeMirror-selected {
89 | background: #e9e7e0;
90 | }
91 | .CodeMirror-focused .CodeMirror-selected {
92 | background: #e7e0d0;
93 | }
94 | .CodeMirror-matchingbracket,
95 | .CodeMirror-matchingtag {
96 | text-decoration: underline;
97 | text-decoration-color: rgba(black, 0.5);
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/themes/OLD/highcontrast-dark.module.scss:
--------------------------------------------------------------------------------
1 | /*
2 | Note this is the CodePen Brand theme. It uses many colors from the CodePen global scope.
3 | */
4 |
5 | .root {
6 | --white: #fff;
7 | --yellow: #ffdd40;
8 | --green: #a3d65a;
9 | --teal: #2bc7b9;
10 | --blue: #5e91f2;
11 | --purple: #ae63e4;
12 | --blueSlate: #88afbf;
13 | --red: #ff3c41;
14 | --orange: #ff8d41;
15 | --pink: #d75093;
16 | --gray: #c7c9d3;
17 | --darkGray: #9b9dad;
18 |
19 | background: #131417;
20 | color: #d5d7de;
21 |
22 | :global {
23 | .cm-keyword {
24 | color: var(--yellow);
25 | }
26 | .cm-atom {
27 | color: var(--red);
28 | }
29 | .cm-def {
30 | color: var(--blue);
31 | }
32 | .cm-variable {
33 | color: var(--gray);
34 | }
35 | .cm-variable-2 {
36 | color: var(--green);
37 | }
38 | .cm-variable-3 {
39 | color: var(--white);
40 | }
41 | .cm-header {
42 | color: var(--red);
43 | }
44 | .cm-number {
45 | color: var(--teal);
46 | }
47 | .cm-property {
48 | color: var(--blue);
49 | }
50 | .cm-attribute {
51 | color: var(--gray);
52 | }
53 | .cm-builtin {
54 | color: var(--purple);
55 | }
56 | .cm-qualifier {
57 | color: var(--yellow);
58 | }
59 | .cm-operator {
60 | color: var(--green);
61 | }
62 | .cm-meta {
63 | color: var(--blue);
64 | }
65 | .cm-string {
66 | color: var(--teal);
67 | }
68 | .cm-string-2 {
69 | color: var(--pink);
70 | }
71 | .cm-tag {
72 | color: var(--yellow);
73 | }
74 | .cm-bracket {
75 | color: var(--darkGray);
76 | }
77 | .cm-comment {
78 | color: var(--blueSlate);
79 | }
80 | }
81 |
82 | // Mode Overrides
83 | &[data-mode='htmlmixed'] {
84 | :global {
85 | .cm-atom {
86 | color: var(--red);
87 | }
88 | }
89 | }
90 | &[data-mode='text/css'] {
91 | :global {
92 | .cm-tag {
93 | color: var(--orange);
94 | }
95 | }
96 | }
97 |
98 | :global {
99 | .CodeMirror-cursor {
100 | border-left-color: var(--white);
101 | }
102 | .CodeMirror-selected {
103 | background: #1e2129;
104 | }
105 | .CodeMirror-focused .CodeMirror-selected {
106 | background: #272c3b;
107 | }
108 | .CodeMirror-matchingbracket,
109 | .CodeMirror-matchingtag {
110 | text-decoration: underline;
111 | text-decoration-color: rgba(white, 0.5);
112 | }
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/themes/OLD/highcontrast-light.module.scss:
--------------------------------------------------------------------------------
1 | .root {
2 | --red: #ca2825;
3 | --teal: #0b6d6c;
4 | --orange: #d26d13;
5 | --purple: #7c47b2;
6 | --bluePurple: #575db7;
7 | --blue: #3172bc;
8 | --green: #048500;
9 | --gray: #5a5f73;
10 | --pink: #a3386c;
11 |
12 | background: #fffefb;
13 | color: #886969;
14 |
15 | :global {
16 | .cm-keyword {
17 | // const, var, let
18 | color: var(--red);
19 | }
20 | .cm-atom {
21 | // tag part of
22 | color: var(--teal);
23 | }
24 | .cm-def {
25 | // params part of function(params) {
26 | color: var(--purple);
27 | }
28 | .cm-variable {
29 | // coffeescript var
30 | color: var(--bluePurple);
31 | }
32 | .cm-variable-2 {
33 | // for (key in [this]), markdown li, decimals without 0 in front
34 | color: var(--purple);
35 | }
36 | .cm-variable-3 {
37 | color: black;
38 | }
39 | .cm-header {
40 | color: var(--red);
41 | }
42 | .cm-number {
43 | color: var(--green);
44 | }
45 | .cm-property {
46 | // margin part of margin: 10px;, getElementById
47 | color: var(--teal);
48 | }
49 | .cm-attribute {
50 | color: var(--gray);
51 | }
52 | .cm-builtin {
53 | color: var(--purple);
54 | }
55 | .cm-qualifier {
56 | color: var(--red);
57 | }
58 | .cm-operator {
59 | // CoffeeScript ->
60 | color: var(--teal);
61 | }
62 | .cm-meta {
63 | // @font-face
64 | color: var(--blue);
65 | }
66 | .cm-string {
67 | // href=["val"]
68 | color: var(--teal);
69 | }
70 | .cm-string-2 {
71 | // match([this])
72 | color: var(--pink);
73 | }
74 | .cm-tag {
75 | color: var(--pink);
76 | }
77 | .cm-bracket {
78 | color: var(--gray);
79 | }
80 | .cm-tag.cm-bracket {
81 | color: var(--gray);
82 | }
83 | .cm-comment {
84 | // /* this comment */
85 | color: var(--gray);
86 | }
87 | }
88 |
89 | // Mode Overrides
90 | &[data-mode='htmlmixed'] {
91 | :global {
92 | .cm-atom {
93 | color: var(--teal);
94 | }
95 | }
96 | }
97 | &[data-mode='text/css'] {
98 | :global {
99 | .cm-tag {
100 | color: var(--orange);
101 | }
102 | }
103 | }
104 |
105 | :global {
106 | .CodeMirror-cursor {
107 | border-left-color: black;
108 | }
109 | .CodeMirror-selected {
110 | background: #ecf2f9;
111 | }
112 | .CodeMirror-focused .CodeMirror-selected {
113 | background: #e4e8ed;
114 | }
115 | .CodeMirror-matchingbracket,
116 | .CodeMirror-matchingtag {
117 | text-decoration: underline;
118 | text-decoration-color: rgba(black, 0.5);
119 | }
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/themes/OLD/mdn-like.module.scss:
--------------------------------------------------------------------------------
1 | .root {
2 | --lightGray: #6d6d6d;
3 | --darkGray: #1b1b1b;
4 | --red: #a30008;
5 | --green: #005a38;
6 | --blue: #005282;
7 |
8 | background: #f4f4f4;
9 | color: var(--darkGray);
10 |
11 | :global {
12 | .cm-keyword {
13 | // const, var, let
14 | color: var(--blue);
15 | }
16 | .cm-atom {
17 | // tag part of
18 | color: var(--red);
19 | }
20 | .cm-def {
21 | // params part of function(params) {
22 | color: var(--green);
23 | }
24 | .cm-variable {
25 | // coffeescript var
26 | color: var(--blue);
27 | }
28 | .cm-variable-2 {
29 | // for (key in [this]), markdown li, decimals without 0 in front
30 | color: var(--green);
31 | }
32 | .cm-variable-3 {
33 | color: var(--green);
34 | }
35 | .cm-header {
36 | color: var(--red);
37 | }
38 | .cm-number {
39 | color: var(--darkGray);
40 | }
41 | .cm-property {
42 | // margin part of margin: 10px;, getElementById
43 | color: var(--red);
44 | }
45 | .cm-attribute {
46 | color: var(--green);
47 | }
48 | .cm-builtin {
49 | color: var(--darkGray);
50 | }
51 | .cm-qualifier {
52 | color: var(--green);
53 | }
54 | .cm-operator {
55 | // CoffeeScript ->
56 | color: var(--green);
57 | }
58 | .cm-meta {
59 | // @font-face
60 | color: var(--red);
61 | }
62 | .cm-string {
63 | // href=["val"]
64 | color: var(--blue);
65 | }
66 | .cm-string-2 {
67 | // match([this])
68 | color: var(--green);
69 | }
70 | .cm-tag {
71 | color: var(--red);
72 | }
73 | .cm-bracket {
74 | color: var(--darkGray);
75 | }
76 | .cm-comment {
77 | // /* this comment */
78 | color: var(--lightGray);
79 | }
80 | }
81 |
82 | :global {
83 | .CodeMirror-cursor {
84 | border-left-color: black;
85 | }
86 | .CodeMirror-selected {
87 | background: #e3edf7;
88 | }
89 | .CodeMirror-focused .CodeMirror-selected {
90 | background: #cae3ff;
91 | }
92 | .CodeMirror-matchingbracket,
93 | .CodeMirror-matchingtag {
94 | text-decoration: underline;
95 | text-decoration-color: rgba(black, 0.5);
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/themes/OLD/oceanic-dark.module.scss:
--------------------------------------------------------------------------------
1 | .root {
2 | --gray: #65737e;
3 | --pink: #c594c5;
4 | --green: #99c794;
5 | --red: #ec5f67;
6 | --yellow: #fac863;
7 | --blue: #6699cc;
8 | --lightBlue: #cdd3de;
9 | --orange: #f99157;
10 |
11 | background: #1b2b34;
12 | color: var(--lightBlue);
13 |
14 | :global {
15 | .cm-keyword {
16 | // const, var, let
17 | color: var(--pink);
18 | }
19 | .cm-atom {
20 | // tag part of
21 | color: var(--pink);
22 | }
23 | .cm-def {
24 | // params part of function(params) {
25 | color: var(--orange);
26 | }
27 | .cm-variable {
28 | // coffeescript var
29 | color: var(--green);
30 | }
31 | .cm-variable-2 {
32 | // for (key in [this]), markdown li, decimals without 0 in front
33 | color: var(--blue);
34 | }
35 | .cm-variable-3 {
36 | color: var(--blue);
37 | }
38 | .cm-header {
39 | color: var(--lightBlue);
40 | }
41 | .cm-number {
42 | color: var(--pink);
43 | }
44 | .cm-property {
45 | // margin part of margin: 10px;, getElementById
46 | color: var(--green);
47 | }
48 | .cm-attribute {
49 | color: var(--green);
50 | }
51 | .cm-builtin {
52 | color: var(--lightBlue);
53 | }
54 | .cm-qualifier {
55 | color: var(--lightBlue);
56 | }
57 | .cm-operator {
58 | // CoffeeScript ->
59 | color: var(--lightBlue);
60 | }
61 | .cm-meta {
62 | // @font-face
63 | color: var(--lightBlue);
64 | }
65 | .cm-string {
66 | // href=["val"]
67 | color: var(--yellow);
68 | }
69 | .cm-string-2 {
70 | // match([this])
71 | color: var(--yellow);
72 | }
73 | .cm-tag {
74 | color: var(--red);
75 | }
76 | .cm-bracket {
77 | color: var(--lightBlue);
78 | }
79 | .cm-comment {
80 | // /* this comment */
81 | color: var(--gray);
82 | }
83 | }
84 |
85 | :global {
86 | .CodeMirror-cursor {
87 | border-left-color: white;
88 | }
89 | .CodeMirror-selected {
90 | background: #161e23;
91 | }
92 | .CodeMirror-focused .CodeMirror-selected {
93 | background: #04151f;
94 | }
95 | .CodeMirror-matchingbracket,
96 | .CodeMirror-matchingtag {
97 | text-decoration: underline;
98 | text-decoration-color: rgba(white, 0.5);
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/themes/OLD/oceanic-light.module.scss:
--------------------------------------------------------------------------------
1 | .root {
2 | --brown: #ab7967;
3 | --pink: #b48ead;
4 | --red: #bf616a;
5 | --green: #72a943;
6 | --yellow: #e5ab00;
7 | --blue: #8fa1b3;
8 | --orange: #d08770;
9 | --darkGray: #343d46;
10 | --lightGray: #65737e;
11 |
12 | background: #eff1f5;
13 | color: var(--darkGray);
14 |
15 | :global {
16 | .cm-keyword {
17 | // const, var, let
18 | color: var(--red);
19 | }
20 | .cm-atom {
21 | // tag part of
22 | color: var(--pink);
23 | }
24 | .cm-def {
25 | // params part of function(params) {
26 | color: var(--orange);
27 | }
28 | .cm-variable {
29 | // coffeescript var
30 | color: var(--green);
31 | }
32 | .cm-variable-2 {
33 | // for (key in [this]), markdown li, decimals without 0 in front
34 | color: var(--blue);
35 | }
36 | .cm-variable-3 {
37 | color: var(--blue);
38 | }
39 | .cm-header {
40 | color: var(--darkGray);
41 | }
42 | .cm-number {
43 | color: var(--pink);
44 | }
45 | .cm-property {
46 | // margin part of margin: 10px;, getElementById
47 | color: var(--green);
48 | }
49 | .cm-attribute {
50 | color: var(--green);
51 | }
52 | .cm-builtin {
53 | color: var(--darkGray);
54 | }
55 | .cm-qualifier {
56 | color: var(--darkGray);
57 | }
58 | .cm-operator {
59 | // CoffeeScript ->
60 | color: var(--darkGray);
61 | }
62 | .cm-meta {
63 | // @font-face
64 | color: var(--darkGray);
65 | }
66 | .cm-string {
67 | // href=["val"]
68 | color: var(--orange);
69 | }
70 | .cm-string-2 {
71 | // match([this])
72 | color: var(--darkGray);
73 | }
74 | .cm-tag {
75 | color: var(--red);
76 | }
77 | .cm-tag.cm-bracket {
78 | color: var(--red);
79 | }
80 | .cm-bracket {
81 | color: var(--darkGray);
82 | }
83 | .cm-comment {
84 | // /* this comment */
85 | color: var(--lightGray);
86 | }
87 | }
88 |
89 | :global {
90 | .CodeMirror-cursor {
91 | border-left-color: black;
92 | }
93 | .CodeMirror-selected {
94 | background: #e7ebf1;
95 | }
96 | .CodeMirror-focused .CodeMirror-selected {
97 | background: #dde5f1;
98 | }
99 | .CodeMirror-matchingbracket,
100 | .CodeMirror-matchingtag {
101 | text-decoration: underline;
102 | text-decoration-color: rgba(black, 0.5);
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/themes/OLD/panda.module.scss:
--------------------------------------------------------------------------------
1 | .root {
2 | --white: #f3f3f3;
3 | --lightGray: #e6e6e6;
4 | --midGray: #676b79;
5 | --green: #19f9d8;
6 | --orange: #ffb86c;
7 | --red: #ff2c6d;
8 | --purple: #b084eb;
9 | --lightPink: #ff9ac1;
10 | --pink: #ff75b5;
11 |
12 | background: #292a2b;
13 | color: var(--lightGray);
14 |
15 | :global {
16 | .cm-keyword {
17 | // const, var, let
18 | color: var(--pink);
19 | }
20 | .cm-atom {
21 | // tag part of
22 | color: var(--red);
23 | }
24 | .cm-def {
25 | // params part of function(params) {
26 | color: var(--lightGray);
27 | }
28 | .cm-variable {
29 | // coffeescript var
30 | color: var(--orange);
31 | }
32 | .cm-variable-2 {
33 | // for (key in [this]), markdown li, decimals without 0 in front
34 | color: var(--lightPink);
35 | }
36 | .cm-variable-3 {
37 | color: var(--lightPink);
38 | }
39 | .cm-header {
40 | color: var(--darkGray);
41 | }
42 | .cm-number {
43 | color: var(--orange);
44 | }
45 | .cm-property {
46 | // margin part of margin: 10px;, getElementById
47 | color: var(--white);
48 | }
49 | .cm-attribute {
50 | color: var(--orange);
51 | }
52 | .cm-builtin {
53 | color: var(--lightGray);
54 | }
55 | .cm-qualifier {
56 | color: var(--lightGray);
57 | }
58 | .cm-operator {
59 | // CoffeeScript ->
60 | color: var(--lightGray);
61 | }
62 | .cm-meta {
63 | // @font-face
64 | color: var(--purple);
65 | }
66 | .cm-string {
67 | // href=["val"]
68 | color: var(--green);
69 | }
70 | .cm-string-2 {
71 | // match([this])
72 | color: var(--orange);
73 | }
74 | .cm-tag {
75 | color: var(--red);
76 | }
77 | .cm-tag.cm-bracket {
78 | color: var(--red);
79 | }
80 | .cm-bracket {
81 | color: var(--lightGray);
82 | }
83 | .cm-comment {
84 | // /* this comment */
85 | color: var(--midGray);
86 | }
87 | }
88 |
89 | :global {
90 | .CodeMirror-cursor {
91 | border-left-color: white;
92 | }
93 | .CodeMirror-selected {
94 | background: rgba(black, 0.05);
95 | }
96 | .CodeMirror-focused .CodeMirror-selected {
97 | background: rgba(black, 0.1);
98 | }
99 | .CodeMirror-matchingbracket,
100 | .CodeMirror-matchingtag {
101 | text-decoration: underline;
102 | text-decoration-color: rgba(white, 0.5);
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/themes/OLD/solarized-dark.module.scss:
--------------------------------------------------------------------------------
1 | .root {
2 | --blue: #268bd2;
3 | --green: #859900;
4 | --red: #cb4b16;
5 | --pink: #d33682;
6 | --brown: #b58900;
7 | --slate: #839496;
8 | --lightSlate: #93a1a1;
9 | --darkSlate: #586e75;
10 | --teal: #2aa198;
11 | --purple: #6c71c4;
12 |
13 | background: #002b36;
14 | color: #77897e;
15 |
16 | :global {
17 | .cm-keyword {
18 | // const, var, let
19 | color: var(--blue);
20 | }
21 | .cm-atom {
22 | // tag part of
23 | color: var(--green);
24 | }
25 | .cm-def {
26 | // params part of function(params) {
27 | color: var(--brown);
28 | }
29 | .cm-variable {
30 | // coffeescript var
31 | color: var(--slate);
32 | }
33 | .cm-variable-2 {
34 | // for (key in [this]), markdown li, decimals without 0 in front
35 | color: var(--green);
36 | }
37 | .cm-variable-3 {
38 | color: var(--lightSlate);
39 | }
40 | .cm-header {
41 | color: var(--red);
42 | }
43 | .cm-number {
44 | color: var(--teal);
45 | }
46 | .cm-property {
47 | // margin part of margin: 10px;, getElementById
48 | color: var(--brown);
49 | }
50 | .cm-attribute {
51 | color: var(--slate);
52 | }
53 | .cm-builtin {
54 | color: var(--purple);
55 | }
56 | .cm-qualifier {
57 | color: var(--blue);
58 | }
59 | .cm-operator {
60 | // CoffeeScript ->
61 | color: var(--green);
62 | }
63 | .cm-meta {
64 | // @font-face
65 | color: var(--blue);
66 | }
67 | .cm-string {
68 | // href=["val"]
69 | color: var(--teal);
70 | }
71 | .cm-string-2 {
72 | // match([this])
73 | color: var(--pink);
74 | }
75 | .cm-tag {
76 | color: var(--blue);
77 | }
78 | .cm-tag.cm-bracket {
79 | color: var(--slate);
80 | }
81 | .cm-bracket {
82 | color: var(--slate);
83 | }
84 | .cm-comment {
85 | // /* this comment */
86 | color: var(--darkSlate);
87 | }
88 | }
89 |
90 | // Mode Overrides
91 | &[data-mode='htmlmixed'] {
92 | :global {
93 | .cm-atom {
94 | color: var(--red);
95 | }
96 | }
97 | }
98 | &[data-mode='text/css'] {
99 | :global {
100 | .cm-tag {
101 | color: var(--green);
102 | }
103 | }
104 | }
105 |
106 | :global {
107 | .CodeMirror-cursor {
108 | border-left-color: white;
109 | }
110 | .CodeMirror-selected {
111 | background: #04252f;
112 | }
113 | .CodeMirror-focused .CodeMirror-selected {
114 | background: #00181f;
115 | }
116 | .CodeMirror-matchingbracket,
117 | .CodeMirror-matchingtag {
118 | text-decoration: underline;
119 | text-decoration-color: rgba(white, 0.5);
120 | }
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/themes/OLD/solarized-light.module.scss:
--------------------------------------------------------------------------------
1 | .root {
2 | --blue: #268bd2;
3 | --green: #859900;
4 | --red: #cb4b16;
5 | --brown: #b58900;
6 | --slate: #657b83;
7 | --darkSlate: #586e75;
8 | --teal: #2aa198;
9 | --pink: #d33682;
10 | --lightGray: #93a1a1;
11 |
12 | background: #fdf6e3;
13 | color: #657b83;
14 |
15 | :global {
16 | .cm-keyword {
17 | // const, var, let
18 | color: var(--blue);
19 | }
20 | .cm-atom {
21 | // tag part of
22 | color: var(--green);
23 | }
24 | .cm-def {
25 | // params part of function(params) {
26 | color: var(--brown);
27 | }
28 | .cm-variable {
29 | // coffeescript var
30 | color: var(--slate);
31 | }
32 | .cm-variable-2 {
33 | // for (key in [this]), markdown li, decimals without 0 in front
34 | color: var(--green);
35 | }
36 | .cm-variable-3 {
37 | color: var(--darkSlate);
38 | }
39 | .cm-header {
40 | color: var(--red);
41 | }
42 | .cm-number {
43 | color: var(--teal);
44 | }
45 | .cm-property {
46 | // margin part of margin: 10px;, getElementById
47 | color: var(--brown);
48 | }
49 | .cm-attribute {
50 | color: var(--slate);
51 | }
52 | .cm-builtin {
53 | color: var(--purple);
54 | }
55 | .cm-qualifier {
56 | color: var(--blue);
57 | }
58 | .cm-operator {
59 | // CoffeeScript ->
60 | color: var(--green);
61 | }
62 | .cm-meta {
63 | // @font-face
64 | color: var(--blue);
65 | }
66 | .cm-string {
67 | // href=["val"]
68 | color: var(--teal);
69 | }
70 | .cm-string-2 {
71 | // match([this])
72 | color: var(--pink);
73 | }
74 | .cm-tag {
75 | color: var(--blue);
76 | }
77 | .cm-tag.cm-bracket {
78 | color: var(--slate);
79 | }
80 | .cm-bracket {
81 | color: var(--slate);
82 | }
83 | .cm-comment {
84 | // /* this comment */
85 | color: var(--lightGray);
86 | }
87 | }
88 |
89 | :global {
90 | .CodeMirror-cursor {
91 | border-left-color: black;
92 | }
93 | .CodeMirror-selected {
94 | background: #efecd7;
95 | }
96 | .CodeMirror-focused .CodeMirror-selected {
97 | background: #e9e3c2;
98 | }
99 | .CodeMirror-matchingbracket,
100 | .CodeMirror-matchingtag {
101 | text-decoration: underline;
102 | text-decoration-color: rgba(black, 0.5);
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/themes/OLD/synthwave.module.scss:
--------------------------------------------------------------------------------
1 | .root {
2 | --white: #ffffff;
3 | --yellow: #ffdd40;
4 | --lightGreen: #a3d65a;
5 | --darkGreen: #47cf73;
6 | --teal: #2bc7b9;
7 | --red: #ff3c41;
8 | --blue: #0ebeff;
9 | --darkBlue: #5e91f2;
10 | --purple: #ae63e4;
11 | --lightGray: #c7c9d3;
12 | --darkGray: #9b9dad;
13 | --pink: #d75093;
14 | --slate: #88afbf;
15 | --black: #131417;
16 |
17 | background: repeating-linear-gradient(
18 | to top,
19 | rgba(255, 255, 255, 0.03) 0 2px,
20 | transparent 2px 4px
21 | ),
22 | linear-gradient(to bottom, #200933 75%, #3d0b43);
23 | color: #f1f1f3;
24 |
25 | &::after {
26 | content: '';
27 | height: 50%;
28 | width: 100%;
29 | display: block;
30 | background-image: linear-gradient(
31 | 90deg,
32 | rgba(252, 25, 154, 0.1) 1px,
33 | rgba(0, 0, 0, 0) 1px
34 | ),
35 | linear-gradient(0deg, rgba(252, 25, 154, 0.1) 1px, rgba(0, 0, 0, 0) 1px);
36 | background-position: bottom;
37 | background-repeat: repeat;
38 | background-size: 20px 20px;
39 | left: -25px;
40 | position: absolute;
41 | pointer-events: none;
42 | bottom: 0;
43 | transform: perspective(100px) rotateX(60deg);
44 | z-index: 0;
45 | }
46 |
47 | :global {
48 | .cm-keyword {
49 | // const, var, let
50 | color: var(--yellow);
51 | }
52 | .cm-atom {
53 | // tag part of
54 | color: var(--lightGreen);
55 | }
56 | .cm-def {
57 | // params part of function(params) {
58 | color: var(--blue);
59 | }
60 | .cm-variable {
61 | // coffeescript var
62 | color: var(--lightGray);
63 | }
64 | .cm-variable-2 {
65 | // for (key in [this]), markdown li, decimals without 0 in front
66 | color: var(--darkGreen);
67 | }
68 | .cm-variable-3 {
69 | color: var(--white);
70 | }
71 | .cm-header {
72 | color: var(--red);
73 | }
74 | .cm-number {
75 | color: var(--teal);
76 | }
77 | .cm-property {
78 | // margin part of margin: 10px;, getElementById
79 | color: var(--darkBlue);
80 | }
81 | .cm-attribute {
82 | color: var(--lightGray);
83 | }
84 | .cm-builtin {
85 | color: var(--purple);
86 | }
87 | .cm-qualifier {
88 | color: var(--yellow);
89 | }
90 | .cm-operator {
91 | // CoffeeScript ->
92 | color: var(--darkGreen);
93 | }
94 | .cm-meta {
95 | // @font-face
96 | color: var(--blue);
97 | }
98 | .cm-string {
99 | // href=["val"]
100 | color: var(--real);
101 | }
102 | .cm-string-2 {
103 | // match([this])
104 | color: var(--pink);
105 | }
106 | .cm-tag {
107 | color: var(--yellow);
108 | }
109 | .cm-bracket {
110 | color: var(--darkGray);
111 | }
112 | .cm-tag.cm-bracket {
113 | color: var(--darkGray);
114 | }
115 | .cm-comment {
116 | // /* this comment */
117 | color: var(--slate);
118 | }
119 |
120 | // Theme Extras
121 | .cm-operator,
122 | .cm-variable-3,
123 | .cm-attribute,
124 | .cm-property,
125 | .cm-keyword,
126 | .presentation > .cm-def,
127 | .cm-qualifier {
128 | color: #fc199a;
129 | text-shadow: 0 0 2px #393a33, 0 0 35px #ffffff44, 0 0 10px #fc199a,
130 | 0 0 2px #fc199a;
131 | }
132 |
133 | .cm-def,
134 | .cm-variable-2,
135 | .cm-variable {
136 | color: #61e2ff;
137 | text-shadow: 0 0 2px #001716, 0 0 5px #03edf933, 0 0 10px #ffff6633;
138 | }
139 |
140 | .cm-meta,
141 | .cm-meta + .cm-property,
142 | .cm-string,
143 | .cm-string-2 {
144 | color: #9963ff;
145 | text-shadow: none;
146 | }
147 | .cm-tag,
148 | .cm-callee,
149 | .cm-tag.cm-bracket {
150 | color: #fc0;
151 | text-shadow: 0 0 2px #100c0f, 0 0 3px #ffaa0099, 0 0 5px #ffaa0099,
152 | 0 0 10px #ffaa0099;
153 | }
154 | .cm-comment {
155 | color: #9963ff99;
156 | text-shadow: 0 0 2px #001716, 0 0 5px #03edf933, 0 0 10px #ffff6633;
157 | }
158 | }
159 |
160 | // Mode Overrides
161 | &[data-mode='htmlmixed'] {
162 | :global {
163 | .cm-atom {
164 | color: var(--red);
165 | }
166 | }
167 | }
168 | &[data-mode='text/css'] {
169 | :global {
170 | .cm-tag {
171 | color: var(--orange);
172 | text-shadow: 0 0 2px #100c0f, 0 0 3px #ffaa0099, 0 0 5px #ffaa0099,
173 | 0 0 10px #ffaa0099;
174 | }
175 | }
176 | }
177 | &[data-mode='text/javascript'],
178 | &[data-mode='text/typescript'] {
179 | :global {
180 | .cm-variable + .cm-property {
181 | color: #61e2ff;
182 | text-shadow: 0 0 2px #001716, 0 0 5px #03edf933, 0 0 10px #ffff6633;
183 | }
184 | .cm-property {
185 | color: #fc0;
186 | text-shadow: 0 0 2px #100c0f, 0 0 3px #ffaa0099, 0 0 5px #ffaa0099,
187 | 0 0 10px #ffaa0099;
188 | }
189 | }
190 | }
191 |
192 | :global {
193 | .CodeMirror-cursor {
194 | border-left-color: white;
195 | }
196 | .CodeMirror-selected {
197 | background: rgba(255, 255, 255, 0.05);
198 | }
199 | .CodeMirror-focused .CodeMirror-selected {
200 | background: rgba(255, 255, 255, 0.1);
201 | }
202 | .CodeMirror-matchingbracket,
203 | .CodeMirror-matchingtag {
204 | text-decoration: underline;
205 | text-decoration-color: rgba(255, 255, 255, 0.5);
206 | }
207 |
208 | .CodeMirror-simplescroll-horizontal div,
209 | .CodeMirror-simplescroll-vertical div {
210 | background: rgba(153, 99, 255, 0.5);
211 | }
212 | }
213 | }
214 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/themes/OLD/tomorrow-night.module.scss:
--------------------------------------------------------------------------------
1 | .root {
2 | --white: white;
3 | --midGray: #c3c6c4;
4 | --darkGray: #b7bbc8;
5 | --orange: #dd925f;
6 | --purple: #ae94c0;
7 | --yellow: #efc371;
8 | --green: #b5bc67;
9 |
10 | background: #1d1f20;
11 | color: var(--midGray);
12 |
13 | :global {
14 | .cm-keyword {
15 | // const, var, let
16 | color: var(--yellow);
17 | }
18 | .cm-atom {
19 | // tag part of
20 | color: var(--yellow);
21 | }
22 | .cm-def {
23 | // params part of function(params) {
24 | color: var(--yellow);
25 | }
26 | .cm-variable {
27 | // coffeescript var
28 | color: var(--yellow);
29 | }
30 | .cm-variable-2 {
31 | // for (key in [this]), markdown li, decimals without 0 in front
32 | color: var(--purple);
33 | }
34 | .cm-variable-3 {
35 | color: var(--purple);
36 | }
37 | .cm-header {
38 | color: var(--orange);
39 | }
40 | .cm-number {
41 | color: var(--orange);
42 | }
43 | .cm-property {
44 | // margin part of margin: 10px;, getElementById
45 | color: var(--purple);
46 | }
47 | .cm-attribute {
48 | color: var(--midGray);
49 | }
50 | .cm-builtin {
51 | color: var(--yellow);
52 | }
53 | .cm-qualifier {
54 | color: var(--yellow);
55 | }
56 | .cm-operator {
57 | // CoffeeScript ->
58 | color: var(--midGray);
59 | }
60 | .cm-meta {
61 | // @font-face
62 | color: var(--green);
63 | }
64 | .cm-string {
65 | // href=["val"]
66 | color: var(--green);
67 | }
68 | .cm-string-2 {
69 | // match([this])
70 | color: var(--white);
71 | }
72 | .cm-tag {
73 | color: var(--yellow);
74 | }
75 | .cm-bracket {
76 | color: var(--midGray);
77 | }
78 | .cm-comment {
79 | // /* this comment */
80 | color: var(--darkGray);
81 | }
82 | }
83 |
84 | // Mode Overrides
85 | &[data-mode='htmlmixed'] {
86 | :global {
87 | .cm-atom {
88 | color: var(--green);
89 | }
90 | }
91 | }
92 | &[data-mode='text/css'] {
93 | :global {
94 | .cm-tag {
95 | color: var(--yellow);
96 | }
97 | }
98 | }
99 |
100 | :global {
101 | .CodeMirror-cursor {
102 | border-left-color: white;
103 | }
104 | .CodeMirror-selected {
105 | background: #171813;
106 | }
107 | .CodeMirror-focused .CodeMirror-selected {
108 | background: #0c0c04;
109 | }
110 | .CodeMirror-matchingbracket,
111 | .CodeMirror-matchingtag {
112 | text-decoration: underline;
113 | text-decoration-color: rgba(white, 0.5);
114 | }
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/themes/OLD/twilight.module.scss:
--------------------------------------------------------------------------------
1 | .root {
2 | background: #1d1e22;
3 | color: var(--cp-color-1);
4 |
5 | --yellow: #ddca7e;
6 | --blue: #809bbd;
7 | --purple: #9a8297;
8 | --brown: #a7925a;
9 | --orange: #ff6400;
10 | --burnt: #d0782a;
11 | --green: #96b38a;
12 |
13 | :global {
14 | .cm-keyword {
15 | color: var(--yellow);
16 | }
17 | .cm-atom {
18 | color: var(--yellow);
19 | }
20 | .cm-def {
21 | color: var(--blue);
22 | }
23 | .cm-variable {
24 | color: var(--yellow);
25 | }
26 | .cm-variable-2 {
27 | color: var(--blue);
28 | }
29 | .cm-variable-3 {
30 | color: var(--blue);
31 | }
32 | .cm-header {
33 | color: var(--orange);
34 | }
35 | .cm-number {
36 | color: var(--burnt);
37 | }
38 | .cm-property {
39 | color: var(--purple);
40 | }
41 | .cm-attribute {
42 | color: var(--yellow);
43 | }
44 | .cm-builtin {
45 | color: var(--yellow);
46 | }
47 | .cm-qualifier {
48 | color: var(--yellow);
49 | }
50 | .cm-operator {
51 | color: var(--cp-color-5);
52 | }
53 | .cm-meta {
54 | color: var(--purple);
55 | }
56 | .cm-string {
57 | color: var(--green);
58 | }
59 | .cm-string-2 {
60 | color: var(--green);
61 | }
62 | .cm-tag {
63 | color: var(--brown);
64 | }
65 | .cm-tag.cm-bracket {
66 | // so that the entire HTML is the same color.
67 | color: var(--brown);
68 | }
69 | .cm-bracket {
70 | color: inherit;
71 | }
72 | .cm-comment {
73 | color: var(--cp-color-12);
74 | }
75 | }
76 |
77 | // Mode Overrides
78 | &[data-mode='text/css'] {
79 | :global {
80 | .cm-tag {
81 | color: var(--yellow);
82 | }
83 | }
84 | }
85 | &[data-mode='htmlmixed'] {
86 | :global {
87 | .cm-atom {
88 | color: var(--green);
89 | }
90 | }
91 | }
92 |
93 | :global {
94 | .CodeMirror-cursor {
95 | border-left-color: white;
96 | }
97 | .CodeMirror-selected {
98 | background: #222427;
99 | }
100 | .CodeMirror-focused .CodeMirror-selected {
101 | background: #2a2e33;
102 | }
103 | .CodeMirror-matchingbracket,
104 | .CodeMirror-matchingtag {
105 | text-decoration: underline;
106 | text-decoration-color: rgba(white, 0.5);
107 | }
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/themes/OLD/xq-light.module.scss:
--------------------------------------------------------------------------------
1 | .root {
2 | --white: white;
3 | --black: black;
4 | --purple: #5a5cad;
5 | --darkPurple: #7f007f;
6 | --lightBlue: #6c8cd5;
7 | --blue: #0080ff;
8 | --darkGreen: #164;
9 | --green: #7ea656;
10 | --lightGreen: #cc7;
11 | --teal: #3f7f7f;
12 | --gray: #999;
13 | --red: #f00;
14 |
15 | background: var(--white);
16 | color: var(--black);
17 |
18 | :global {
19 | .cm-keyword {
20 | // const, var, let
21 | color: var(--purple);
22 | }
23 | .cm-atom {
24 | // tag part of
25 | color: var(--lightBlue);
26 | }
27 | .cm-def {
28 | // params part of function(params) {
29 | color: var(--black);
30 | }
31 | .cm-variable {
32 | // coffeescript var
33 | color: var(--black);
34 | }
35 | .cm-variable-2 {
36 | // for (key in [this]), markdown li, decimals without 0 in front
37 | color: var(--black);
38 | }
39 | .cm-variable-3 {
40 | color: var(--black);
41 | }
42 | .cm-header {
43 | color: var(--black);
44 | }
45 | .cm-number {
46 | color: var(--darkGreen);
47 | }
48 | .cm-property {
49 | // margin part of margin: 10px;, getElementById
50 | color: var(--gray);
51 | }
52 | .cm-attribute {
53 | color: var(--darkPurple);
54 | }
55 | .cm-builtin {
56 | color: var(--green);
57 | }
58 | .cm-qualifier {
59 | color: var(--gray);
60 | }
61 | .cm-operator {
62 | // CoffeeScript ->
63 | color: var(--purple);
64 | }
65 | .cm-meta {
66 | // @font-face
67 | color: var(--blue);
68 | }
69 | .cm-string {
70 | // href=["val"]
71 | color: var(--red);
72 | }
73 | .cm-string-2 {
74 | // match([this])
75 | color: var(--black);
76 | }
77 | .cm-tag {
78 | color: var(--teal);
79 | }
80 | .cm-bracket {
81 | color: var(--teal);
82 | }
83 | .cm-comment {
84 | // /* this comment */
85 | color: var(--blue);
86 | }
87 | }
88 |
89 | :global {
90 | .CodeMirror-cursor {
91 | border-left-color: black;
92 | }
93 | .CodeMirror-selected {
94 | background: rgba(black, 0.05);
95 | }
96 | .CodeMirror-focused .CodeMirror-selected {
97 | background: rgba(black, 0.1);
98 | }
99 | .CodeMirror-matchingbracket,
100 | .CodeMirror-matchingtag {
101 | text-decoration: underline;
102 | text-decoration-color: rgba(black, 0.5);
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/themes/debug.js:
--------------------------------------------------------------------------------
1 | import { EditorView } from "codemirror";
2 | import { HighlightStyle, syntaxHighlighting } from "@codemirror/language";
3 | import { tags } from "@lezer/highlight";
4 |
5 | // Helpful "theme" to debug what Lezer tag properly matches each piece of the syntax.
6 | // https://lezer.codemirror.net/docs/ref/#highlight.tags
7 | const debugTheme = EditorView.theme({
8 | ".cm-line span": {
9 | position: "relative",
10 | },
11 | ".cm-line span:hover::after": {
12 | position: "absolute",
13 | bottom: "100%",
14 | left: 0,
15 | background: "black",
16 | color: "white",
17 | border: "solid 2px",
18 | borderRadius: "5px",
19 | content: "var(--tags)",
20 | width: `max-content`,
21 | padding: "1px 4px",
22 | zIndex: 10,
23 | pointerEvents: "none",
24 | },
25 | });
26 | const debugHighlightStyle = HighlightStyle.define(
27 | Object.entries(tags).map(([key, value]) => {
28 | return { tag: value, "--tags": `"tag.${key}"` };
29 | })
30 | );
31 |
32 | const debug = [debugTheme, syntaxHighlighting(debugHighlightStyle)];
33 |
34 | export { debug, debugTheme, debugHighlightStyle };
35 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/themes/highContrastDark.js:
--------------------------------------------------------------------------------
1 | import { HighlightStyle, syntaxHighlighting } from "@codemirror/language";
2 | import { EditorView } from "@codemirror/view";
3 | import { tags } from "@lezer/highlight";
4 |
5 | // TODO: Confirm a match between old & new
6 | const COLORS = {
7 | black: "#131417",
8 | darkestGray: "#1e2129",
9 | darkerGray: "#272c3b",
10 | white: "#fff",
11 | yellow: "#ffdd40",
12 | green: "#47cf73",
13 | teal: "#2bc7b9",
14 | blue: "#5e91f2",
15 | lightBlue: "#0ebeff",
16 | purple: "#ae63e4",
17 | blueSlate: "#88afbf",
18 | red: "#ff3c41",
19 | orange: "#ff8d41",
20 | pink: "#d75093",
21 | gray: "#c7c9d3",
22 | darkGray: "#9b9dad",
23 | };
24 |
25 | const highContrastDarkTheme = EditorView.theme(
26 | {
27 | "&": {
28 | color: COLORS.white,
29 | backgroundColor: COLORS.black,
30 | },
31 | ".cm-content": {
32 | caretColor: COLORS.white,
33 | },
34 | "&.cm-focused .cm-cursor": { borderLeftColor: COLORS.white },
35 | "&.cm-focused .cm-selectionBackground, .cm-selectionBackground, ::selection":
36 | { backgroundColor: COLORS.darkerGray },
37 | ".cm-panels": { backgroundColor: COLORS.black, color: COLORS.white },
38 | ".cm-panels.cm-panels-top": { borderBottom: "2px solid black" },
39 | ".cm-panels.cm-panels-bottom": { borderTop: "2px solid black" },
40 | ".cm-searchMatch": {
41 | backgroundColor: COLORS.blue,
42 | color: COLORS.white,
43 | outline: `1px solid ${COLORS.blue}`,
44 | },
45 | ".cm-searchMatch.cm-searchMatch-selected": {
46 | backgroundColor: "#6199ff2f",
47 | },
48 | ".cm-selectionMatch": { backgroundColor: "#aafe661a" },
49 | ".cm-matchingBracket, .cm-nonmatchingBracket": {
50 | backgroundColor: COLORS.darkGray,
51 | outline: `1px solid ${COLORS.darkGray}`,
52 | },
53 | ".cm-gutters": {
54 | backgroundColor: COLORS.black,
55 | color: COLORS.darkGray,
56 | border: "none",
57 | },
58 | ".cm-activeLineGutter": {
59 | color: COLORS.gray,
60 | },
61 | ".cm-activeLine, .cm-activeLineGutter": {
62 | backgroundColor: COLORS.darkestGray,
63 | },
64 | ".cm-foldPlaceholder": {
65 | backgroundColor: "transparent",
66 | border: "none",
67 | color: "#ddd",
68 | },
69 | ".cm-tooltip": {
70 | border: `1px solid ${COLORS.darkGray}`,
71 | backgroundColor: COLORS.black,
72 | },
73 | // ".cm-tooltip-autocomplete": {
74 | // "& > ul > li[aria-selected]": {
75 | // backgroundColor: "#1d1e22",
76 | // color: COLORS.white,
77 | // },
78 | // },
79 | },
80 | { dark: true }
81 | );
82 |
83 | // https://lezer.codemirror.net/docs/ref/#highlight.tags
84 | const highContrastDarkHighlightStyle = HighlightStyle.define(
85 | [
86 | // @mixin cool, rem, function, return, let, const
87 | { tag: tags.keyword, color: COLORS.yellow },
88 |
89 | // property name, attribute name, variable name
90 | {
91 | tag: tags.name,
92 | color: COLORS.blue,
93 | },
94 |
95 | {
96 | tag: tags.attributeName,
97 | color: COLORS.white,
98 | },
99 |
100 | // JavaScript property name
101 | {
102 | tag: tags.propertyName,
103 | color: COLORS.blue,
104 | },
105 |
106 | // ???
107 | {
108 | tag: [tags.character, tags.macroName, tags.meta],
109 | color: COLORS.blue,
110 | },
111 |
112 | // JavaScript function name
113 | {
114 | tag: [tags.function(tags.variableName)],
115 | color: COLORS.teal,
116 | },
117 |
118 | {
119 | tag: tags.angleBracket,
120 | color: COLORS.gray,
121 | },
122 |
123 | // ???
124 | {
125 | tag: [tags.color, tags.constant(tags.name), tags.standard(tags.name)],
126 | color: COLORS.yellow,
127 | },
128 |
129 | // {
130 | // tag: tags.tagName,
131 | // color: COLORS.orange,
132 | // },
133 |
134 | // variable name
135 | {
136 | tag: [tags.definition(tags.name)],
137 | color: COLORS.lightBlue,
138 | },
139 | {
140 | tag: tags.operator,
141 | color: COLORS.green,
142 | },
143 |
144 | // Semicolon
145 | {
146 | tag: [tags.separator],
147 | color: COLORS.white,
148 | },
149 |
150 | // HTML tag names, selectors
151 | {
152 | tag: [
153 | tags.typeName,
154 | tags.className,
155 | tags.changed,
156 | tags.annotation,
157 | tags.modifier,
158 | tags.self,
159 | tags.namespace,
160 | ],
161 | color: COLORS.yellow,
162 | },
163 |
164 | // 0
165 | { tag: [tags.number], color: COLORS.teal },
166 |
167 | // +
168 | {
169 | tag: [
170 | // tags.operator,
171 | tags.operatorKeyword,
172 | tags.url,
173 | tags.escape,
174 | tags.regexp,
175 | tags.link,
176 | tags.special(tags.string),
177 | ],
178 | color: COLORS.pink,
179 | },
180 |
181 | // Comments
182 | { tag: [tags.comment], color: COLORS.blueSlate },
183 |
184 | { tag: tags.strong, fontWeight: "bold" },
185 | { tag: tags.emphasis, fontStyle: "italic" },
186 | { tag: tags.link, color: "#eee", textDecoration: "underline" },
187 | {
188 | tag: tags.heading,
189 | fontWeight: "bold",
190 | color: "#eee",
191 | },
192 | {
193 | tag: [tags.atom, tags.bool, tags.special(tags.variableName)],
194 | color: COLORS.yellow,
195 | },
196 |
197 | // "bar", quoted HTML attribute value
198 | {
199 | tag: [tags.processingInstruction, tags.string, tags.inserted],
200 | color: COLORS.teal,
201 | },
202 |
203 | // Errors
204 | { tag: [tags.invalid, tags.deleted], color: COLORS.red },
205 | ],
206 | { dark: true }
207 | );
208 |
209 | const highContrastDark = [
210 | highContrastDarkTheme,
211 | syntaxHighlighting(highContrastDarkHighlightStyle),
212 | ];
213 |
214 | export {
215 | highContrastDark,
216 | highContrastDarkHighlightStyle,
217 | highContrastDarkTheme,
218 | };
219 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/themes/twilight.js:
--------------------------------------------------------------------------------
1 | import { HighlightStyle, syntaxHighlighting } from "@codemirror/language";
2 | import { EditorView } from "@codemirror/view";
3 | import { tags } from "@lezer/highlight";
4 |
5 | const twilightTheme = EditorView.theme(
6 | {
7 | "&": {
8 | color: "white",
9 | backgroundColor: "#1d1e22",
10 | },
11 | ".cm-content": {
12 | caretColor: "white",
13 | },
14 | "&.cm-focused .cm-cursor": { borderLeftColor: "white" },
15 | "&.cm-focused .cm-selectionBackground, .cm-selectionBackground, ::selection":
16 | { backgroundColor: "#343539" },
17 | ".cm-panels": { backgroundColor: "#1d1e22", color: "white" },
18 | ".cm-panels.cm-panels-top": { borderBottom: "2px solid black" },
19 | ".cm-panels.cm-panels-bottom": { borderTop: "2px solid black" },
20 | ".cm-searchMatch": {
21 | backgroundColor: "#72a1ff59",
22 | outline: "1px solid #457dff",
23 | },
24 | ".cm-searchMatch.cm-searchMatch-selected": {
25 | backgroundColor: "#6199ff2f",
26 | },
27 | ".cm-activeLine": { backgroundColor: "#333438" },
28 | ".cm-selectionMatch": { backgroundColor: "#aafe661a" },
29 | ".cm-matchingBracket, .cm-nonmatchingBracket": {
30 | backgroundColor: "#bad0f847",
31 | outline: "1px solid #515a6b",
32 | },
33 | ".cm-gutters": {
34 | backgroundColor: "#1d1e22",
35 | color: "#44464e",
36 | border: "none",
37 | },
38 | ".cm-activeLineGutter": {
39 | backgroundColor: "#333438",
40 | color: "#54565e",
41 | },
42 | ".cm-foldPlaceholder": {
43 | backgroundColor: "transparent",
44 | border: "none",
45 | color: "#ddd",
46 | },
47 | ".cm-tooltip": {
48 | border: "1px solid #181a1f",
49 | backgroundColor: "#1d1e22",
50 | },
51 | ".cm-tooltip-autocomplete": {
52 | "& > ul > li[aria-selected]": {
53 | backgroundColor: "#1d1e22",
54 | color: "white",
55 | },
56 | },
57 | },
58 | { dark: true }
59 | );
60 |
61 | const twilightHighlightStyle = HighlightStyle.define([
62 | // @mixin cool, rem, function, return, let, const
63 | { tag: tags.keyword, color: "#ddca7e" },
64 |
65 | // property name, attribute name, variable name
66 | {
67 | tag: tags.name,
68 | color: "#9a8297",
69 | },
70 |
71 | // JavaScript property name
72 | {
73 | tag: tags.propertyName,
74 | color: "#9a8297",
75 | },
76 |
77 | // ???
78 | {
79 | tag: [tags.character, tags.macroName],
80 | color: "blue",
81 | },
82 |
83 | // JavaScript function name
84 | {
85 | tag: [tags.function(tags.variableName), tags.labelName],
86 | color: "#809bbd",
87 | },
88 |
89 | // ???
90 | {
91 | tag: [tags.color, tags.constant(tags.name), tags.standard(tags.name)],
92 | color: "#a7925a",
93 | },
94 |
95 | // variable name
96 | {
97 | tag: [tags.definition(tags.name)],
98 | color: "#809bbd",
99 | },
100 |
101 | // Semicolon
102 | {
103 | tag: [tags.separator],
104 | color: "white",
105 | },
106 |
107 | // HTML tag names, selectors
108 | {
109 | tag: [
110 | tags.typeName,
111 | tags.className,
112 | tags.changed,
113 | tags.annotation,
114 | tags.modifier,
115 | tags.self,
116 | tags.namespace,
117 | ],
118 | color: "#ddca7e",
119 | },
120 |
121 | // 0
122 | { tag: [tags.number], color: "#d0782a" },
123 |
124 | // +
125 | {
126 | tag: [
127 | tags.operator,
128 | tags.operatorKeyword,
129 | tags.url,
130 | tags.escape,
131 | tags.regexp,
132 | tags.link,
133 | tags.special(tags.string),
134 | ],
135 | color: "#809bbd",
136 | },
137 |
138 | // Comments
139 | { tag: [tags.meta, tags.comment], color: "#717790" },
140 |
141 | { tag: tags.strong, fontWeight: "bold" },
142 | { tag: tags.emphasis, fontStyle: "italic" },
143 | { tag: tags.link, color: "#eee", textDecoration: "underline" },
144 | {
145 | tag: tags.heading,
146 | fontWeight: "bold",
147 | color: "#eee",
148 | },
149 | {
150 | tag: [tags.atom, tags.bool, tags.special(tags.variableName)],
151 | color: "#ddca7e",
152 | },
153 |
154 | // "bar", quoted HTML attribute value
155 | {
156 | tag: [tags.processingInstruction, tags.string, tags.inserted],
157 | color: "#96b38a",
158 | },
159 |
160 | // Errors
161 | { tag: [tags.invalid, tags.deleted], color: "red" },
162 | ]);
163 |
164 | const twilight = [twilightTheme, syntaxHighlighting(twilightHighlightStyle)];
165 |
166 | export { twilight, twilightHighlightStyle, twilightTheme };
167 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/useExtensionCompartment.js:
--------------------------------------------------------------------------------
1 | import { useMemo, useCallback } from "react";
2 | import { Compartment } from "@codemirror/state";
3 |
4 | export function useExtensionCompartment(editorView) {
5 | const compartment = useMemo(() => new Compartment(), []);
6 |
7 | const dispatch = editorView?.dispatch;
8 | const updateCompartment = useCallback(
9 | function updateCompartment(extension) {
10 | if (dispatch)
11 | dispatch({
12 | effects: compartment.reconfigure(extension),
13 | });
14 | },
15 | [compartment, dispatch]
16 | );
17 |
18 | return [
19 | // Initial value of [] to prevent extension errors
20 | compartment.of([]),
21 | updateCompartment,
22 | ];
23 | }
24 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/extensions/useExtensions.js:
--------------------------------------------------------------------------------
1 | import { useRef } from "react";
2 | import { defaultExtensions } from "./defaultExtensions";
3 | import { useEmmetExtension } from "./emmet";
4 | import { useLanguageExtension } from "./languages";
5 | import { useThemeExtension } from "./themes";
6 | import { useReadOnly } from "./readOnly";
7 | import { useLineWrapping } from "./lineWrapping";
8 | import { useIndentation } from "./indentation";
9 | import { useFonts } from "./fonts";
10 | import { useLineNumbers } from "./lineNumbers";
11 | import { useCodeFolding } from "./codeFolding";
12 | import { useMatchBrackets } from "./matchBrackets";
13 | import { useAutocomplete } from "./autocomplete";
14 | import { useOnChange } from "./onChange";
15 | import { useExtraExtensions } from "./extensions";
16 |
17 | export function useExtensions(props, editorView) {
18 | const languageExtension = useLanguageExtension(props, editorView);
19 |
20 | const editorSettings = props.editorSettings || {};
21 | // console.log("useExtensions", editorSettings);
22 |
23 | const lineNumbersExtension = useLineNumbers(editorSettings, editorView);
24 | const codeFoldingExtension = useCodeFolding(editorSettings, editorView);
25 | const themeExtension = useThemeExtension(editorSettings, editorView);
26 | const fontsExtension = useFonts(editorSettings, editorView);
27 | const lineWrappingExtension = useLineWrapping(editorSettings, editorView);
28 | const indentationExtension = useIndentation(editorSettings, editorView);
29 | const matchBracketsExtension = useMatchBrackets(editorSettings, editorView);
30 | const autocompleteExtension = useAutocomplete(editorSettings, editorView);
31 | const emmetExtension = useEmmetExtension(
32 | props.language,
33 | editorSettings,
34 | editorView
35 | );
36 | const readOnlyExtension = useReadOnly(props, editorView);
37 | const onChangeExtension = useOnChange(props, editorView);
38 | const extraExtensions = useExtraExtensions(props, editorView);
39 |
40 | // Store as a ref because the extensions themselves are stored in compartments that won't change. We don't need to rebuild this array every time it re-renders.
41 | const extensionsRef = useRef([
42 | // Order for Emmet & default is important to allow `tab` key indentation to work.
43 | emmetExtension,
44 | defaultExtensions,
45 |
46 | // Order can affect gutter layout and cascade precedence.
47 | lineNumbersExtension,
48 | codeFoldingExtension,
49 | languageExtension,
50 |
51 | matchBracketsExtension,
52 | autocompleteExtension,
53 | readOnlyExtension,
54 | themeExtension,
55 | fontsExtension,
56 | lineWrappingExtension,
57 | indentationExtension,
58 | onChangeExtension,
59 | extraExtensions,
60 | ]);
61 |
62 | return extensionsRef.current;
63 | }
64 |
--------------------------------------------------------------------------------
/components/CodeMirror6Instance/index.js:
--------------------------------------------------------------------------------
1 | export { default } from "./CodeMirror6Instance";
2 |
--------------------------------------------------------------------------------
/components/CodeSamples/CodeSamples.js:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 |
3 | import CodeEditor from "../CodeEditor";
4 | import { CODE_SAMPLES } from "../../data/code";
5 | import { SUPPORT_LEVELS } from "../../data/supportLevels";
6 |
7 | import styles from "./CodeSamples.module.scss";
8 |
9 | export default function CodeSamples({ editorSettings }) {
10 | const [supportedFilter, setSupportedFilter] = useState("ALL");
11 | const [nameFilter, setNameFilter] = useState("");
12 |
13 | let filteredSamples = [...CODE_SAMPLES];
14 |
15 | if (supportedFilter && supportedFilter !== "ALL") {
16 | filteredSamples = filteredSamples.filter(
17 | (sample) => sample.supported === supportedFilter
18 | );
19 | }
20 |
21 | if (nameFilter) {
22 | filteredSamples = filteredSamples.filter((sample) =>
23 | sample.language.toLowerCase().includes(nameFilter.toLowerCase())
24 | );
25 | }
26 |
27 | return (
28 |
29 |
30 |
31 | Support Level
32 | setSupportedFilter(e.currentTarget.value)}>
33 | All
34 | {Object.entries(SUPPORT_LEVELS).map(([key, value]) => (
35 |
36 | {key}
37 |
38 | ))}
39 |
40 |
41 |
42 | Name
43 | setNameFilter(e.currentTarget.value)}
46 | />
47 |
48 |
49 | {filteredSamples.map(({ label, code, language, notes, supported }, i) => {
50 | return (
51 |
56 |
{label}
57 | {notes &&
{notes}
}
58 |
64 |
65 | );
66 | })}
67 |
68 | );
69 | }
70 |
--------------------------------------------------------------------------------
/components/CodeSamples/CodeSamples.module.scss:
--------------------------------------------------------------------------------
1 | .root {
2 | display: grid;
3 | grid-template-columns: repeat(auto-fill, minmax(450px, 1fr));
4 | gap: 1rem;
5 | }
6 |
7 | .filters {
8 | display: flex;
9 | gap: 2rem;
10 | justify-content: space-between;
11 | padding: 1rem;
12 | background: #222;
13 | border-radius: 0.5rem;
14 | grid-column: 1 / -1;
15 | }
16 |
17 | .sample {
18 | &,
19 | a {
20 | color: white;
21 | }
22 | h2 {
23 | margin: 0 0 0.5rem 0;
24 | }
25 | }
26 |
27 | .notes {
28 | font-size: 0.9rem;
29 | opacity: 0.66;
30 | }
31 |
32 | .codeEditor {
33 | border: solid 2px #555;
34 | }
35 |
--------------------------------------------------------------------------------
/components/CodeSamples/index.js:
--------------------------------------------------------------------------------
1 | import CodeSamples from "./CodeSamples";
2 |
3 | export default CodeSamples;
4 |
--------------------------------------------------------------------------------
/components/EditorSettings/EditorSettings.js:
--------------------------------------------------------------------------------
1 | import { EDITOR_SETTINGS } from "../../data/editorSettings";
2 | import styles from "./EditorSettings.module.scss";
3 |
4 | export default function EditorSettings({ editorSettings, setEditorSettings }) {
5 | function changeEditorSetting(newSettings) {
6 | return setEditorSettings((editorSettings) => {
7 | return {
8 | ...editorSettings,
9 | ...newSettings,
10 | };
11 | });
12 | }
13 |
14 | return (
15 |
16 | {Object.entries(EDITOR_SETTINGS).map(([key, value]) => {
17 | const { label, options, supported, notes, implemented } = value;
18 | return (
19 |
25 |
{label}
26 |
{
30 | let value = e.target.value;
31 | if (value === "true") value = true;
32 | if (value === "false") value = false;
33 | changeEditorSetting({ [key]: value });
34 | console.log(key, value);
35 | }}
36 | >
37 | {options.map((option) => {
38 | let value = option.value || String(option);
39 | let label = option.label || value;
40 |
41 | return (
42 |
43 | {label}
44 |
45 | );
46 | })}
47 |
48 |
49 | {notes &&
{notes}
}
50 |
51 | );
52 | })}
53 |
54 | );
55 | }
56 |
--------------------------------------------------------------------------------
/components/EditorSettings/EditorSettings.module.scss:
--------------------------------------------------------------------------------
1 | .root {
2 | display: grid;
3 | grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
4 | gap: 1rem;
5 | > div {
6 | flex: 1;
7 | }
8 | label {
9 | display: block;
10 | }
11 | select {
12 | width: 100%;
13 | }
14 | }
15 |
16 | .option {
17 | &[data-implemented="false"] {
18 | opacity: 0.5;
19 | &:hover {
20 | opacity: 0.8;
21 | }
22 | }
23 | }
24 |
25 | .notes {
26 | font-size: 0.7rem;
27 | margin: 0.5rem 0;
28 | opacity: 0.75;
29 | }
30 |
--------------------------------------------------------------------------------
/components/EditorSettings/index.js:
--------------------------------------------------------------------------------
1 | import EditorSettings from "./EditorSettings";
2 | export default EditorSettings;
3 |
--------------------------------------------------------------------------------
/data/code.js:
--------------------------------------------------------------------------------
1 | import { LANGUAGES } from "./languages";
2 | import { SUPPORT_LEVELS } from "./supportLevels";
3 |
4 | /* Languages! https://codemirror.net/6/examples/lang-package/ */
5 | export const CODE_SAMPLES = [
6 | {
7 | language: LANGUAGES.HTML,
8 | label: "HTML",
9 | supported: SUPPORT_LEVELS.SUPPORTED,
10 | notes: null,
11 | code: `
12 |
13 |
14 |
15 |
16 | A Great Demo on CodePen
17 |
18 |
19 |
20 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent bibendum , lorem vel tincidunt imperdiet, nibh elit laoreet felis, a bibendum nisl tortor non orci.
21 |
22 | Vestibulum nunc massa, gravida quis porta nec, feugiat id metus. Nunc ac arcu dolor, quis vestibulum leo. Cras viverra mollis ipsum, non rhoncus lectus aliquam et. Morbi faucibus purus sit amet lacus aliquet elementum. Donec sit amet posuere enim.
23 |
24 |
25 | `,
26 | },
27 | {
28 | language: LANGUAGES.CSS,
29 | label: "CSS",
30 | supported: SUPPORT_LEVELS.SUPPORTED,
31 | notes: null,
32 | code: `body {
33 | background: red;
34 | margin: 0;
35 | }`,
36 | },
37 | {
38 | language: LANGUAGES.JAVASCRIPT,
39 | label: "JavaScript",
40 | supported: SUPPORT_LEVELS.SUPPORTED,
41 | notes: null,
42 | code: `import gsap from 'gsap';
43 |
44 | let foo = "bar";
45 |
46 | const data = {
47 | age: 12
48 | };
49 |
50 | function hello(){
51 | console.log(data.age);
52 | }
53 | `,
54 | },
55 | {
56 | language: LANGUAGES.JSX,
57 | label: "JSX",
58 | supported: SUPPORT_LEVELS.SUPPORTED,
59 | notes: null,
60 | code: `import React from 'react';
61 |
62 | function App() {
63 | return text
;
64 | }
65 |
66 | export default App;
67 | `,
68 | },
69 | {
70 | language: LANGUAGES.MARKDOWN,
71 | label: "Markdown",
72 | supported: SUPPORT_LEVELS.SUPPORTED,
73 | notes: null,
74 | code: `# This is markdown
75 |
76 | Just some *copy* here with a [link](https://codepen.io) in it.
77 |
78 | > blockquote
79 |
80 | Ordered List
81 | 1. First item
82 | 2. Second item
83 | 3. Third item
84 |
85 | Unordered List
86 | - First item
87 | - Second item
88 | - Third item
89 | `,
90 | },
91 | {
92 | language: LANGUAGES.HAML,
93 | label: Haml ,
94 | supported: SUPPORT_LEVELS.NOT_SUPPORTED,
95 | notes: null,
96 | code: `- (1..16).each do |i|
97 | %div #{i}
98 |
99 | %blockquote Hello, World!`,
100 | },
101 | {
102 | language: LANGUAGES.PUG,
103 | label: Pug ,
104 | supported: SUPPORT_LEVELS.NOT_SUPPORTED,
105 | code: `-
106 | var list = ["Uno", "Dos", "Tres",
107 | "Cuatro", "Cinco", "Seis"]
108 | each item in list
109 | li= item
110 |
111 | p
112 | | The pipe always goes at the beginning of its own line,
113 | | not counting indentation.`,
114 | },
115 | {
116 | language: LANGUAGES.SLIM,
117 | label: Slim ,
118 | supported: SUPPORT_LEVELS.NOT_SUPPORTED,
119 | notes: null,
120 | code: `doctype html
121 | html
122 | head
123 | title Slim Examples
124 | meta name="keywords" content="template language"
125 | meta name="author" content=author
126 | javascript:
127 | alert('Slim supports embedded javascript!')
128 |
129 | body
130 | h1 Markup examples
131 |
132 | #content
133 | p This example shows you what a basic Slim file looks like.
134 |
135 | == yield
136 |
137 | - unless items.empty?
138 | table
139 | - items.each do |item|
140 | tr
141 | td.name = item.name
142 | td.price = item.price
143 | - else
144 | p
145 | | No items found. Please add some inventory.
146 | Thank you!
147 |
148 | div id="footer"
149 | = render 'footer'
150 | | Copyright © #{year} #{author}`,
151 | },
152 | {
153 | language: LANGUAGES.SCSS,
154 | label: SCSS ,
155 | supported: SUPPORT_LEVELS.SUPPORTED,
156 | notes: null,
157 | code: `@mixin cool {
158 | padding: 1rem;
159 | }
160 |
161 | .options {
162 | display: grid;
163 | grid-template-columns: repeat(5, 1fr);
164 | gap: 1rem;
165 | margin: 0 0 1rem 0;
166 | > div {
167 | flex: 1;
168 | }
169 | label {
170 | display: block;
171 | }
172 | select {
173 | width: 100%;
174 | }
175 | }
176 | `,
177 | },
178 | {
179 | language: LANGUAGES.SASS,
180 | label: Sass ,
181 | supported: SUPPORT_LEVELS.SUPPORTED,
182 | code: `// SASS SYNTAX
183 | $font-stack: Helvetica, sans-serif
184 | $primary-color: #333
185 |
186 | body
187 | font: 100% $font-stack
188 | color: $primary-color`,
189 | },
190 | {
191 | language: LANGUAGES.SCSS,
192 | label: Less ,
193 | supported: SUPPORT_LEVELS.SUPPORTED,
194 | code: `// Variables
195 | @link-color: #428bca; // sea blue
196 | @link-color-hover: darken(@link-color, 10%);
197 |
198 | // Usage
199 | a,
200 | .link {
201 | color: @link-color;
202 | }
203 | a:hover {
204 | color: @link-color-hover;
205 | }
206 | .widget {
207 | color: #fff;
208 | background: @link-color;
209 | }`,
210 | },
211 | {
212 | language: LANGUAGES.STYLUS,
213 | label: Stylus ,
214 | supported: SUPPORT_LEVELS.SUPPORTED,
215 | notes: "Legacy mode",
216 | code: `border-radius()
217 | -webkit-border-radius: arguments
218 | -moz-border-radius: arguments
219 | border-radius: arguments
220 |
221 | body
222 | font: 12px Helvetica, Arial, sans-serif
223 |
224 | a.button
225 | border-radius(5px)`,
226 | },
227 | {
228 | language: LANGUAGES.COFFEESCRIPT,
229 | label: CoffeeScript ,
230 | supported: SUPPORT_LEVELS.SUPPORTED,
231 | notes: "Legacy mode",
232 | code: `# Assignment:
233 | number = 42
234 | opposite = true
235 |
236 | # Conditions:
237 | number = -42 if opposite
238 |
239 | # Functions:
240 | square = (x) -> x * x
241 |
242 | # Arrays:
243 | list = [1, 2, 3, 4, 5]
244 |
245 | # Objects:
246 | math =
247 | root: Math.sqrt
248 | square: square
249 | cube: (x) -> x * square x
250 |
251 | # Splats:
252 | race = (winner, runners...) ->
253 | print winner, runners
254 |
255 | # Existence:
256 | alert "I knew it!" if elvis?
257 |
258 | # Array comprehensions:
259 | cubes = (math.cube num for num in list)`,
260 | },
261 | {
262 | language: LANGUAGES.TYPESCRIPT,
263 | label: TypeScript ,
264 | supported: SUPPORT_LEVELS.SUPPORTED,
265 | notes: null,
266 | code: `type Cat = { meows: true };
267 | type Dog = { barks: true };
268 | type Cheetah = { meows: true; fast: true };
269 | type Wolf = { barks: true; howls: true };
270 |
271 | // We can create a conditional type which lets extract
272 | // types which only conform to something which barks.
273 |
274 | type ExtractDogish = A extends { barks: true } ? A : never;
275 |
276 | // Then we can create types which ExtractDogish wraps:
277 |
278 | // A cat doesn't bark, so it will return never
279 | type NeverCat = ExtractDogish;
280 | // A wolf will bark, so it returns the wolf shape
281 | type Wolfish = ExtractDogish;
282 | `,
283 | },
284 | {
285 | language: LANGUAGES.LIVESCRIPT,
286 | label: LiveScript ,
287 | supported: SUPPORT_LEVELS.SUPPORTED,
288 | notes: "Legacy mode",
289 | code: `# Easy listing of implicit objects
290 | table1 =
291 | * id: 1
292 | name: 'george'
293 | * id: 2
294 | name: 'mike'
295 | * id: 3
296 | name: 'donald'
297 |
298 | table2 =
299 | * id: 2
300 | age: 21
301 | * id: 1
302 | age: 20
303 | * id: 3
304 | age: 26`,
305 | },
306 | {
307 | language: LANGUAGES.NUNJUCKS,
308 | label: Nunjucks ,
309 | supported: SUPPORT_LEVELS.NOT_SUPPORTED,
310 | notes: null,
311 | code: `{% extends "base.html" %}
312 |
313 | {% block header %}
314 | {{ title }}
315 | {% endblock %}
316 |
317 | {% block content %}
318 |
319 | {% for name, item in items %}
320 | {{ name }}: {{ item }}
321 | {% endfor %}
322 |
323 | {% endblock %}`,
324 | },
325 | ];
326 |
--------------------------------------------------------------------------------
/data/editorSettings.js:
--------------------------------------------------------------------------------
1 | import { THEMES } from "../components/CodeMirror6Instance/extensions/themes";
2 | import { SUPPORT_LEVELS } from "./supportLevels";
3 |
4 | export const INDENT_VALUES = {
5 | TABS: "Tabs",
6 | SPACES: "Spaces",
7 | };
8 |
9 | export const EDITOR_SETTINGS = {
10 | theme: {
11 | label: "Syntax Highlighting",
12 | default: THEMES.TWILIGHT,
13 | options: Object.values(THEMES), // [THEMES.ONE_DARK, THEMES.TWILIGHT], //Object.values(THEMES),
14 | // "Solarized Dark",
15 | // "Tomorrow Night",
16 | // "Oceanic Dark",
17 | // "Panda",
18 | // "DuoTone Dark",
19 | // "High Contrast Dark",
20 | // "Classic",
21 | // "Solarized Light",
22 | // "XQ Light",
23 | // "Oceanic Light",
24 | // "MDN Like",
25 | // "DuoTone Light",
26 | // "High Contrast Light",
27 |
28 | supported: SUPPORT_LEVELS.SUPPORTED,
29 | implemented: true,
30 | notes: "We have lots of themes to port over; may want to drop ",
31 | },
32 |
33 | fontSize: {
34 | label: "Font Size",
35 | default: 14,
36 | options: [10, 12, 14, 16, 18, 20, 22, 24],
37 | supported: SUPPORT_LEVELS.SUPPORTED,
38 | implemented: true,
39 | notes: (
40 | <>
41 |
42 | Implemented via Theme
43 |
44 | >
45 | ),
46 | },
47 |
48 | lineHeight: {
49 | label: "Line Height",
50 | default: 1.4,
51 | options: [1, 1.2, 1.4, 1.6, 1.8, 2],
52 | supported: SUPPORT_LEVELS.SUPPORTED,
53 | implemented: true,
54 | notes: null,
55 | },
56 |
57 | fontFamily: {
58 | label: "Font",
59 | default: "Source Code Pro",
60 | options: [
61 | "Monaco",
62 | "Hack",
63 | "Inconsolata",
64 | "Source Code Pro",
65 | "Monoid",
66 | "Fantasque Sans Mono",
67 | "Input Mono",
68 | "DejaVu Sans Mono",
69 | "FireCode Medium",
70 | "Operator Mono",
71 | "Dank Mono",
72 | "Gintronic",
73 | "Courier Prime",
74 | "JetBrains Mono",
75 | "Recursive",
76 | "MonoLisa",
77 | "Codelia",
78 | "Comic Code",
79 | ],
80 | supported: SUPPORT_LEVELS.SUPPORTED,
81 | implemented: true,
82 | notes: null,
83 | },
84 |
85 | indentWidth: {
86 | label: "Indent Width",
87 | default: 2,
88 | options: [2, 4, 6, 8],
89 | supported: SUPPORT_LEVELS.SUPPORTED,
90 | implemented: true,
91 | notes: (
92 | <>
93 | NOTE: Does not convert previous indentations to a new width. There are
94 | some ways to do that through{" "}
95 | Prettier . Is there an
96 | official CodeMirror way of altering indent width of pre-authored code
97 | for spaces?
98 | >
99 | ),
100 | },
101 |
102 | indentUnit: {
103 | label: "Tabs or Spaces",
104 | default: INDENT_VALUES.SPACES,
105 | options: [INDENT_VALUES.SPACES, INDENT_VALUES.TABS],
106 | supported: SUPPORT_LEVELS.SUPPORTED,
107 | implemented: true,
108 | notes: (
109 | <>NOTE: Does not convert previous indentations to the new indent unit. >
110 | ),
111 | },
112 |
113 | lineNumbers: {
114 | label: "Line Numbers",
115 | default: true,
116 | options: [true, false],
117 | supported: SUPPORT_LEVELS.SUPPORTED,
118 | implemented: true,
119 | notes: (
120 | <>
121 |
122 | Officially supported
123 |
124 | >
125 | ),
126 | },
127 |
128 | lineWrapping: {
129 | label: "Line Wrapping",
130 | default: true,
131 | options: [true, false],
132 | supported: SUPPORT_LEVELS.SUPPORTED,
133 | implemented: true,
134 | notes: (
135 | <>
136 |
137 | Officially supported
138 |
139 | >
140 | ),
141 | },
142 |
143 | codeFolding: {
144 | label: "Code Folding",
145 | default: true,
146 | options: [true, false],
147 | supported: SUPPORT_LEVELS.SUPPORTED,
148 | implemented: true,
149 | notes: (
150 | <>
151 |
152 | Officially supported.
153 |
154 | >
155 | ),
156 | },
157 |
158 | matchBrackets: {
159 | label: "Match & Close Brackets / Tags",
160 | default: true,
161 | options: [true, false],
162 | supported: SUPPORT_LEVELS.SUPPORTED,
163 | implemented: true,
164 | notes: (
165 | <>
166 |
167 |
168 | Officially supported.
169 |
170 |
171 |
172 | TODO: CodePen has traditionally paired this concept with{" "}
173 |
174 | Close Brackets
175 |
176 | , but they are different plugins in CodeMirror. Should we separate or
177 | combine?
178 |
179 |
180 |
181 | TODO: There's also the concept of{" "}
182 |
183 | `matchClosingTags` and `autoCloseTags` for HTML
184 | {" "}
185 | (possibly JSX as well?). Do we want this all linked to one option? In
186 | the interest of simplicity, they do all seem related.
187 |
188 | >
189 | ),
190 | },
191 |
192 | /* https://codemirror.net/6/docs/ref/#autocomplete */
193 | autocomplete: {
194 | label: "Autocomplete",
195 | default: true,
196 | options: [true, false],
197 | supported: SUPPORT_LEVELS.PARTIAL_SUPPORT,
198 | implemented: true,
199 | notes: (
200 | <>
201 |
202 | Officially supported
203 |
204 | . Need to figure out which languages it works on. Doesn't seem to
205 | do simple stuff in JavaScript like `document`, or `querySelector`. Also
206 | we need to pipe in authored JavaScript, so autocomplete works on
207 | user-authored code.
208 | >
209 | ),
210 | },
211 |
212 | emmet: {
213 | label: "Emmet",
214 | default: true,
215 | options: [true, false],
216 | supported: SUPPORT_LEVELS.SUPPORTED,
217 | implemented: true,
218 | notes: (
219 | <>
220 |
221 | Implemented as a plugin
222 | {" "}
223 | by Sergey.
224 | >
225 | ),
226 | },
227 | };
228 |
229 | export const EDITOR_SETTINGS_DEFAULTS = Object.entries(EDITOR_SETTINGS).reduce(
230 | (obj, [key, value]) => {
231 | obj[key] = value.default;
232 | return obj;
233 | },
234 | {}
235 | );
236 |
--------------------------------------------------------------------------------
/data/languages.js:
--------------------------------------------------------------------------------
1 | export const LANGUAGES = {
2 | HTML: "html",
3 | CSS: "css",
4 | MARKDOWN: "markdown",
5 | JAVASCRIPT: "js",
6 | JSX: "jsx",
7 | SCSS: "scss",
8 | SASS: "sass",
9 | LESS: "less",
10 | STYLUS: "stylus",
11 | HAML: "haml",
12 | PUG: "pug",
13 | SLIM: "slim",
14 | NUNJUCKS: "nunjucks",
15 | COFFEESCRIPT: "coffeescript",
16 | TYPESCRIPT: "typescript",
17 | LIVESCRIPT: "livescript",
18 | };
19 |
--------------------------------------------------------------------------------
/data/supportLevels.js:
--------------------------------------------------------------------------------
1 | export const SUPPORT_LEVELS = {
2 | SUPPORTED: "SUPPORTED",
3 | NOT_SUPPORTED: "NOT_SUPPORTED",
4 | PARTIAL_SUPPORT: "PARTIAL_SUPPORT",
5 | };
6 |
--------------------------------------------------------------------------------
/netlify.toml:
--------------------------------------------------------------------------------
1 | [[plugins]]
2 | package = "@netlify/plugin-nextjs"
3 |
4 | [build]
5 | publish = ".next"
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | import withBundleAnalyzer from "@next/bundle-analyzer";
2 |
3 | const bundleAnalyzer = withBundleAnalyzer({
4 | enabled: process.env.ANALYZE === "true",
5 | });
6 |
7 | export default bundleAnalyzer({
8 | reactStrictMode: true,
9 | target: "serverless",
10 | });
11 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "codemirror-6-needs",
3 | "version": "1.0.0",
4 | "private": true,
5 | "type": "module",
6 | "scripts": {
7 | "dev": "next dev -p 3009",
8 | "build": "next build",
9 | "export": "next export",
10 | "start": "next start",
11 | "lint": "next lint",
12 | "analyze": "ANALYZE=true yarn build"
13 | },
14 | "dependencies": {
15 | "@codemirror/autocomplete": "^6.18.0",
16 | "@codemirror/commands": "^6.6.0",
17 | "@codemirror/language": "^6.10.2",
18 | "@codemirror/language-data": "6.5.1",
19 | "@codemirror/legacy-modes": "^6.0.0",
20 | "@codemirror/lint": "^6.0.0",
21 | "@codemirror/search": "^6.5.6",
22 | "@codemirror/state": "^6.4.1",
23 | "@codemirror/theme-one-dark": "^6.0.0",
24 | "@codemirror/view": "^6.32.0",
25 | "@emmetio/codemirror6-plugin": "^0.3.2",
26 | "@netlify/plugin-nextjs": "^4.9.1",
27 | "@next/bundle-analyzer": "^11.0.1",
28 | "@replit/codemirror-indentation-markers": "^0.20.0",
29 | "classnames": "^2.3.1",
30 | "cm6-theme-material-dark": "^0.2.0",
31 | "cm6-theme-solarized-dark": "^0.2.0",
32 | "cm6-theme-solarized-light": "^0.2.0",
33 | "codemirror": "^6.0.1",
34 | "next": "^12.2",
35 | "prettier": "^2.3.1",
36 | "react": "18.3.1",
37 | "react-dom": "18.3.1",
38 | "sass": "^1.70.0",
39 | "thememirror": "^2.0.0",
40 | "y-codemirror.next": "^0.3.0",
41 | "y-webrtc": "^10.2.3",
42 | "yjs": "^13.6.14"
43 | },
44 | "devDependencies": {
45 | "eslint": "7.29.0",
46 | "eslint-config-next": "11.0.1"
47 | },
48 | "packageManager": "yarn@4.1.1+sha256.f3cc0eda8e5560e529c7147565b30faa43b4e472d90e8634d7134a37c7f59781"
49 | }
50 |
--------------------------------------------------------------------------------
/pages/_app.js:
--------------------------------------------------------------------------------
1 | import "../styles/globals.css";
2 |
3 | function MyApp({ Component, pageProps }) {
4 | return ;
5 | }
6 |
7 | export default MyApp;
8 |
--------------------------------------------------------------------------------
/pages/_document.js:
--------------------------------------------------------------------------------
1 | import { Html, Head, Main, NextScript } from "next/document";
2 |
3 | export default function Document() {
4 | return (
5 |
6 |
7 |
8 |
13 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/pages/console.js:
--------------------------------------------------------------------------------
1 | import { useState, Component } from "react";
2 | import Head from "next/head";
3 | import EditorSettings from "../components/EditorSettings";
4 | import { EDITOR_SETTINGS_DEFAULTS } from "../data/editorSettings";
5 | import { LANGUAGES } from "../data/languages";
6 | import styles from "../styles/Home.module.scss";
7 |
8 | import CodeMirror6Instance from "../components/CodeMirror6Instance";
9 |
10 | import { EditorView, Decoration } from "@codemirror/view";
11 | import { StateField, StateEffect, Range, RangeSet } from "@codemirror/state";
12 | import {
13 | ensureSyntaxTree,
14 | foldable,
15 | foldAll,
16 | foldCode,
17 | foldEffect,
18 | foldService,
19 | language,
20 | syntaxTreeAvailable,
21 | } from "@codemirror/language";
22 |
23 | const consoleLineClasses = {
24 | clear: "cm-console-clear",
25 | error: "cm-console-error",
26 | warn: "cm-console-warn",
27 | info: "cm-console-info",
28 | };
29 |
30 | const consoleEntriesTheme = EditorView.baseTheme({
31 | [`.${consoleLineClasses.clear}`]: {
32 | fontStyle: "italic",
33 | opacity: 0.5,
34 | },
35 | [`.${consoleLineClasses.error}`]: {
36 | background: "hsl(358.462deg 100% 61.7647% / 35%)",
37 | },
38 | [`.${consoleLineClasses.warn}`]: {
39 | background: "hsl(49.3194deg 100% 62.549% / 35%)",
40 | },
41 | [`.${consoleLineClasses.info}`]: {
42 | background: "hsl(206.418deg 52.7559% 50.1961% / 50%)",
43 | },
44 | });
45 |
46 | const addConsoleEntryEffect = StateEffect.define();
47 | const removeConsoleEntryEffect = StateEffect.define();
48 |
49 | const consoleEntriesField = StateField.define({
50 | create() {
51 | return Decoration.none; //RangeSet.empty;
52 | },
53 | update(consoleEntries, tr) {
54 | consoleEntries = consoleEntries.map(tr.changes);
55 | for (let e of tr.effects) {
56 | if (e.is(addConsoleEntryEffect)) {
57 | let { log, from, to } = e.value;
58 | console.log("adding console decoration", log);
59 |
60 | const toAdd = [Decoration.mark({ logId: log.id }).range(from, to)];
61 | const type = log.function;
62 | if (consoleLineClasses[type]) {
63 | const lines = getLines(tr.state, from, to);
64 | toAdd.push(
65 | ...lines.map((line) =>
66 | Decoration.line({
67 | class: consoleLineClasses[type],
68 | logId: log.id,
69 | }).range(line.from)
70 | )
71 | );
72 | }
73 | consoleEntries = consoleEntries.update({
74 | add: toAdd,
75 | sort: true,
76 | });
77 | } else if (e.is(removeConsoleEntryEffect)) {
78 | let { log } = e.value;
79 | consoleEntries = consoleEntries.update({
80 | filter(from, to, value) {
81 | return value.spec.logId !== log.id;
82 | },
83 | });
84 | }
85 | }
86 | return consoleEntries;
87 | },
88 | provide: (f) => EditorView.decorations.from(f),
89 | });
90 |
91 | function getLines(state, from, to) {
92 | const lines = [];
93 | // Loop through lines
94 | for (let pos = from; pos <= to; ) {
95 | let line = state.doc.lineAt(pos);
96 | lines.push(line);
97 | // Next line
98 | pos = line.to + 1;
99 | }
100 |
101 | return lines;
102 | }
103 |
104 | function findConsoleEntryRange(view, log) {
105 | const range = { from: 0, to: 0 };
106 |
107 | const field = view.state.field(consoleEntriesField);
108 | field.between(0, view.state.doc.length, function (from, to, value) {
109 | if (value.spec.logId === log.id) {
110 | range.from = Math.min(from, range.from);
111 | range.to = Math.max(to, range.to);
112 | // console.log({ from, to, range });
113 | }
114 | });
115 |
116 | return range;
117 | }
118 |
119 | async function foldLog(view, log) {
120 | // const range = findConsoleEntryRange(view, log);
121 | // const { from, to } = range;
122 | // setTimeout(() => {
123 | // const langField = view.state.field(language, false);
124 | // console.log("language", langField);
125 | // let f = foldable(view.state, from + 1, to - 1);
126 | // console.log("foldable", f);
127 | // // foldAll(view);
128 | // }, 100);
129 | // view.dispatch({});
130 | // let available = syntaxTreeAvailable(view.state, to);
131 | // console.log("before", { available });
132 | // let tree = await ensureSyntaxTree(view.state, to + 1, 1000);
133 | // available = syntaxTreeAvailable(view.state, to);
134 | // console.log("after", { available, tree });
135 | // setTimeout(() => {
136 | // let available = syntaxTreeAvailable(view.state, to);
137 | // let tree = ensureSyntaxTree(view.state, to + 1, 1000);
138 | // console.log("setTimeout", { available, tree });
139 | // // let f = foldable(view.state, from, to + 1);
140 | // // console.log("foldable", f);
141 | // // foldAll(view);
142 | // // view.dispatch({ effects: [foldEffect.of({ from, to: to + 1 })] });
143 | // });
144 | }
145 |
146 | async function addConsoleEntry(view, log) {
147 | const value = log.arguments.join(" ");
148 | let from = view.state.doc.length;
149 | let to = from;
150 |
151 | // const type = log.function;
152 | // if (type === "clear") {
153 | // from = 0;
154 | // }
155 |
156 | const insertLineBreak = from !== 0;
157 |
158 | const lineDecorationsData = {
159 | log,
160 | from: insertLineBreak ? from + 1 : 0,
161 | };
162 | lineDecorationsData.to = lineDecorationsData.from + value.length;
163 |
164 | let effects = [addConsoleEntryEffect.of(lineDecorationsData)];
165 |
166 | // Ensure that the necessary extensions are added.
167 | if (!view.state.field(consoleEntriesField, false)) {
168 | effects.push(
169 | StateEffect.appendConfig.of([consoleEntriesField, consoleEntriesTheme])
170 | );
171 | }
172 |
173 | view.dispatch({
174 | changes: {
175 | from,
176 | to,
177 | insert: (insertLineBreak ? view.state.lineBreak : "") + value,
178 | },
179 | effects,
180 | });
181 |
182 | await foldLog(view, log);
183 | }
184 |
185 | function removeConsoleEntry(view, log) {
186 | const range = findConsoleEntryRange(view, log);
187 |
188 | // if (insertLineBreak) {
189 | // console.log("insertLineBreak!", range.from);
190 | // range.from = Math.max(0, from - 1);
191 | // }
192 |
193 | console.log("field before", view.state.field(consoleEntriesField));
194 |
195 | console.log("removing", log.id, range);
196 |
197 | view.dispatch({
198 | changes: {
199 | from: range.from,
200 | to: Math.min(view.state.doc.length, range.to + 1),
201 | },
202 | effects: [removeConsoleEntryEffect.of({ log })],
203 | });
204 |
205 | // const firstLine = view.state.doc.line(1);
206 | // if (firstLine.text === "") {
207 | // console.log(firstLine);
208 |
209 | // view.dispatch({
210 | // changes: {
211 | // from: firstLine.from,
212 | // to: firstLine.to + 1,
213 | // },
214 | // });
215 | // }
216 | // console.log("field after", view.state.field(consoleEntriesField));
217 | }
218 |
219 | class ConsoleLog extends Component {
220 | componentDidMount() {
221 | if (this.props.view) {
222 | this.remove = addConsoleEntry(this.props.view, this.props.log);
223 | }
224 | }
225 |
226 | componentWillUnmount() {
227 | removeConsoleEntry(this.props.view, this.props.log);
228 | // Remove lines. We should get some kind of Range back from the addConsoleLog function that can then be removed.
229 | }
230 |
231 | render() {
232 | return (
233 |
234 | {this.props.log.id}: {this.props.log.arguments.join(" ")}
235 |
236 | );
237 | }
238 | }
239 |
240 | export default function Console() {
241 | const [editorSettings, setEditorSettings] = useState({
242 | ...EDITOR_SETTINGS_DEFAULTS,
243 | lineNumbers: false,
244 | });
245 |
246 | const [view, setView] = useState();
247 | const [lastLog, setLastLog] = useState(8);
248 | const [logs, setLogs] = useState(LOGS.slice(0, lastLog));
249 |
250 | function addLogs() {
251 | setLogs((logs) => {
252 | return [...logs, LOGS[lastLog]];
253 | });
254 | setLastLog((lastLog + 1) % LOGS.length);
255 | }
256 |
257 | function removeLogs() {
258 | setLogs((logs) => {
259 | let logs2 = [...logs];
260 | logs2.shift();
261 | return logs2; //.slice(1 - logs.length);
262 | });
263 | }
264 |
265 | function onInit(view) {
266 | setView(view);
267 | }
268 |
269 | return (
270 |
271 |
272 |
CodeMirror 6 Console
273 |
274 |
275 |
276 |
277 | CodeMirror 6 Console
278 |
279 |
280 |
287 |
288 | Add Log
289 | Remove Log
290 |
296 | {view &&
297 | logs.map((log) => (
298 |
299 | ))}
300 |
301 |
302 |
303 | );
304 | }
305 |
306 | const LOGS = [
307 | {
308 | function: "log",
309 | arguments: ["\n\txyz\n\t123\n
"],
310 | id: "1655911665381322333141",
311 | },
312 | {
313 | function: "log",
314 | arguments: ['"console.log"'],
315 | id: "16559116653812341",
316 | },
317 | {
318 | function: "error",
319 | arguments: ['"console.error"'],
320 | id: "1655911665381",
321 | },
322 | {
323 | function: "warn",
324 | arguments: ['"console.warn"'],
325 | id: "1655911665385",
326 | },
327 | {
328 | function: "info",
329 | arguments: ['"console.info"'],
330 | id: "1655911665382",
331 | },
332 | {
333 | function: "log",
334 | arguments: ['"regular console.log log\nwith multiple lines!"'],
335 | id: "1655911665381322341",
336 | },
337 |
338 | {
339 | arguments: ["Console was cleared"],
340 | complexity: 1,
341 | function: "clear",
342 | id: "1655911665379",
343 | },
344 | {
345 | function: "log",
346 | arguments: ["1"],
347 | id: "165591166538333",
348 | },
349 | {
350 | function: "log",
351 | arguments: ["2"],
352 | id: "165591165653833334",
353 | },
354 | {
355 | function: "log",
356 | arguments: ["3"],
357 | id: "1655911665383537223",
358 | },
359 | {
360 | function: "log",
361 | arguments: ["4"],
362 | id: "165591163653833673",
363 | },
364 | {
365 | function: "log",
366 | arguments: ["5"],
367 | id: "165591166538353343",
368 | },
369 | {
370 | function: "log",
371 | arguments: ["6"],
372 | id: "1655911665383253634399",
373 | },
374 | {
375 | function: "log",
376 | arguments: ["7"],
377 | id: "1655911665383363311341",
378 | },
379 | {
380 | function: "log",
381 | arguments: ["8"],
382 | id: "165591166538303634463234",
383 | },
384 | {
385 | function: "log",
386 | arguments: ["9"],
387 | id: "1655911665383392634323",
388 | },
389 | {
390 | function: "debug",
391 | arguments: ['"debug"'],
392 | id: "1655911665380",
393 | },
394 | {
395 | function: "log",
396 | arguments: ['"multiple\nlines\nin\none\nlog"'],
397 | id: "1655911665383",
398 | },
399 | {
400 | function: "table",
401 | arguments: ['"table"'],
402 | id: "1655911665384",
403 | },
404 | {
405 | function: "info",
406 | arguments: ['"[WDS] Hot Module Replacement enabled."'],
407 | id: "1655911665392",
408 | },
409 | {
410 | function: "info",
411 | arguments: ['"[WDS] Live Reloading enabled."'],
412 | id: "1655911665393",
413 | },
414 | ];
415 |
--------------------------------------------------------------------------------
/pages/index.js:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import Head from "next/head";
3 | import CodeSamples from "../components/CodeSamples";
4 | import EditorSettings from "../components/EditorSettings";
5 | import { EDITOR_SETTINGS_DEFAULTS } from "../data/editorSettings";
6 | import styles from "../styles/Home.module.scss";
7 |
8 | export default function Home() {
9 | // TODO: Get controls working via editorSettings object.
10 | const [editorSettings, setEditorSettings] = useState(
11 | EDITOR_SETTINGS_DEFAULTS
12 | );
13 |
14 | console.log(editorSettings);
15 |
16 | return (
17 |
18 |
19 |
CodeMirror 6 Needs
20 |
21 |
22 |
23 |
34 |
35 |
36 | Settings
37 |
38 |
42 |
43 |
44 |
45 | Samples
46 |
47 |
48 |
49 |
50 |
51 | );
52 | }
53 |
--------------------------------------------------------------------------------
/pages/shared.js:
--------------------------------------------------------------------------------
1 | import { useState, useEffect, useRef } from "react";
2 | import Head from "next/head";
3 | import EditorSettings from "../components/EditorSettings";
4 | import CodeEditor from "../components/CodeEditor";
5 | import { EDITOR_SETTINGS_DEFAULTS } from "../data/editorSettings";
6 | import { LANGUAGES } from "../data/languages";
7 | import styles from "../styles/Home.module.scss";
8 |
9 | import { AnnotationType, EditorState, StateEffect } from "@codemirror/state";
10 | import { Annotation } from "@codemirror/state";
11 | import { useExtensions } from "../components/CodeMirror6Instance/extensions/useExtensions";
12 | import CodeMirror6Instance from "../components/CodeMirror6Instance";
13 |
14 | const syncAnnotation = new AnnotationType(Boolean);
15 |
16 | class SyncedState {
17 | constructor() {
18 | this.addView = this.addView.bind(this);
19 | this.syncDispatch = this.syncDispatch.bind(this);
20 | }
21 |
22 | views = [];
23 |
24 | addView(view) {
25 | this.views.push(view);
26 |
27 | // Get them all on the same state.
28 | if (this.views.length > 1) {
29 | view.setState(this.views[0].state);
30 | }
31 |
32 | // Have to override _dispatch as that's what the config option goes to.
33 | view._dispatch = this.syncDispatch({
34 | views: this.views,
35 | view,
36 | });
37 | }
38 |
39 | syncDispatch({ views, view }) {
40 | return (tr) => {
41 | view.update([tr]);
42 | // If not an empty change and not a sync change, then apply the change to all other views.
43 | if (!tr.annotation(syncAnnotation)) {
44 | console.log("sync dispatch", views.indexOf(view), tr);
45 |
46 | // Mark this as a sync transaction.
47 | const annotations = syncAnnotation.of(true);
48 | let transaction;
49 |
50 | if (!tr.changes.empty) {
51 | transaction = {
52 | // Mark this as a sync transaction.
53 | annotations,
54 | changes: tr.changes,
55 | };
56 | } else if (tr.effects.length) {
57 | transaction = {
58 | annotations,
59 | effects: tr.effects,
60 | };
61 | }
62 |
63 | if (transaction) {
64 | views.forEach((v) => {
65 | if (v === view) return;
66 | v.dispatch(transaction);
67 | });
68 | }
69 | }
70 | };
71 | }
72 | }
73 |
74 | export default function Shared() {
75 | const [editorSettings, setEditorSettings] = useState(
76 | EDITOR_SETTINGS_DEFAULTS
77 | );
78 |
79 | const syncedStateRef = useRef(new SyncedState());
80 | const syncedState = syncedStateRef.current;
81 |
82 | function onInit(editorView) {
83 | syncedState.addView(editorView);
84 | }
85 |
86 | const [fileValue, setFileValue] = useState(
87 | `\n \n Hello World\n \n`
88 | );
89 | const [submittedValue, setSubmittedValue] = useState(fileValue);
90 |
91 | function onSubmit() {
92 | console.log("onSubmit", fileValue);
93 | setSubmittedValue(fileValue);
94 | }
95 |
96 | function onChange(update) {
97 | if (update.docChanged) {
98 | console.log("onChange", update);
99 | let value = update.state.doc.toString();
100 | setFileValue(value);
101 | }
102 | }
103 |
104 | return (
105 |
106 |
107 |
CodeMirror 6 Shared State
108 |
109 |
110 |
111 |
112 | CodeMirror 6 Shared State
113 |
114 |
115 |
116 |
117 |
setFileValue("hello")}>File Contents
118 |
125 |
126 |
130 |
131 | {syncedState && (
132 |
139 |
146 |
147 |
148 |
149 |
150 |
151 | )}
152 |
153 |
154 | );
155 | }
156 |
--------------------------------------------------------------------------------
/pages/sync.js:
--------------------------------------------------------------------------------
1 | import { useState, useRef } from "react";
2 | import Head from "next/head";
3 | import EditorSettings from "../components/EditorSettings";
4 | import { EDITOR_SETTINGS_DEFAULTS } from "../data/editorSettings";
5 | import { LANGUAGES } from "../data/languages";
6 | import styles from "../styles/Home.module.scss";
7 |
8 | import CodeMirror6Instance from "../components/CodeMirror6Instance";
9 | import { AnnotationType } from "@codemirror/state";
10 | import { ViewPlugin } from "@codemirror/view";
11 |
12 | const syncAnnotation = new AnnotationType(Boolean);
13 | const annotations = syncAnnotation.of(true);
14 |
15 | class SyncedState {
16 | constructor() {
17 | const views = [];
18 | this.views = views;
19 |
20 | this.plugin = ViewPlugin.fromClass(
21 | class {
22 | constructor(view) {
23 | views.push(view);
24 | this.view = view;
25 | this.mounted = false;
26 | // Have to delay the setState because we can't call it directly in an `update` call.
27 | requestAnimationFrame(() => {
28 | if (views.length > 1 && view !== views[0]) {
29 | const value = views[0].state.doc.toString();
30 | // setState is a bit aggressive, forcing all extensions and such to be replaced. Dispatching the new value ensures we can just be concerned with the value sync.
31 | // view.setState(views[0].state);
32 | view.dispatch({
33 | annotations: syncAnnotation,
34 | changes: {
35 | from: 0,
36 | to: view.state.doc.length,
37 | insert: value,
38 | },
39 | });
40 | }
41 | // Set a mounted flag so we know the values are in sync.
42 | this.mounted = true;
43 | });
44 | }
45 |
46 | destroy() {
47 | this.mounted = false;
48 | // Remove this view from the array.
49 | views.splice(views.indexOf(this.view), 1);
50 | }
51 |
52 | update(u) {
53 | if (this.mounted && u.docChanged) {
54 | const transactions = u.transactions
55 | .filter(
56 | // filter out non-sync transactions without changes.
57 | (tr) => !tr.annotation(syncAnnotation) && !tr.changes.empty
58 | )
59 | .map((tr) => {
60 | // Send through changes only, marked as a syncAnnotation
61 | return { changes: tr.changes, annotations };
62 | });
63 |
64 | views.forEach((v) => {
65 | // Don't dispatch the transactions on this view again.
66 | if (v === u.view) return;
67 | transactions.forEach((tr) => v.dispatch(tr));
68 | });
69 | }
70 | }
71 | }
72 | );
73 | }
74 | }
75 |
76 | export default function Shared() {
77 | const [editorSettings, setEditorSettings] = useState(
78 | EDITOR_SETTINGS_DEFAULTS
79 | );
80 |
81 | const syncedStateRef = useRef(new SyncedState());
82 | const syncedState = syncedStateRef.current;
83 |
84 | const [fileValue, setFileValue] = useState(
85 | `\n \n Hello World\n \n`
86 | );
87 | const [submittedValue, setSubmittedValue] = useState(fileValue);
88 |
89 | function onSubmit() {
90 | // console.log("onSubmit", fileValue);
91 | setSubmittedValue(fileValue);
92 | }
93 |
94 | function onChange(update) {
95 | if (update.docChanged) {
96 | // console.log("onChange", update);
97 | let value = update.state.doc.toString();
98 | setFileValue(value);
99 | }
100 | }
101 |
102 | return (
103 |
104 |
105 |
CodeMirror 6 Shared State
106 |
107 |
108 |
109 |
110 | CodeMirror 6 Shared State
111 |
112 |
113 |
114 |
115 |
setFileValue("hello")}>File Contents
116 |
123 |
124 |
129 |
130 | {syncedState && (
131 |
138 |
145 |
146 |
152 |
158 |
164 |
165 | )}
166 |
167 |
168 | );
169 | }
170 |
--------------------------------------------------------------------------------
/pages/yjs.js:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from "react";
2 | import Head from "next/head";
3 | import EditorSettings from "../components/EditorSettings";
4 | import { EDITOR_SETTINGS_DEFAULTS } from "../data/editorSettings";
5 | import { LANGUAGES } from "../data/languages";
6 | import styles from "../styles/Home.module.scss";
7 |
8 | import CodeMirror6Instance from "../components/CodeMirror6Instance";
9 |
10 | import * as Y from "yjs";
11 | import { yCollab } from "y-codemirror.next";
12 |
13 | export default function SharedYjs() {
14 | const [editorSettings, setEditorSettings] = useState(
15 | EDITOR_SETTINGS_DEFAULTS
16 | );
17 |
18 | const [fileValue, setFileValue] = useState(
19 | `\n \n Hello World\n \n`
20 | );
21 | const [submittedValue, setSubmittedValue] = useState(fileValue);
22 |
23 | const [yText, setYText] = useState();
24 | useEffect(() => {
25 | const yDoc = new Y.Doc();
26 | const yText = yDoc.getText("file-id");
27 | setYText(yText);
28 |
29 | // Keep file in sync with yText "on change"
30 | yText.observe(function (event, transaction) {
31 | console.log({ yText, event, transaction });
32 | setFileValue(yText.toString());
33 | });
34 | }, []);
35 |
36 | // Ensure the yText stays in sync with the main value.
37 | useEffect(() => {
38 | if (yText && yText.toString() !== submittedValue) {
39 | yText.applyDelta([
40 | // If there's content, delete it all
41 | yText.length > 0 ? { delete: yText.length } : {},
42 | // Insert the new value
43 | { insert: submittedValue },
44 | ]);
45 | }
46 | }, [yText, submittedValue]);
47 |
48 | function onSubmit() {
49 | setSubmittedValue(fileValue);
50 | }
51 |
52 | return (
53 |
54 |
55 |
CodeMirror 6 Y.js Integration
56 |
57 |
58 |
59 |
63 |
64 |
65 |
66 |
setFileValue("hello")}>File Contents
67 |
74 |
75 |
80 |
81 |
82 |
94 |
95 |
96 | );
97 | }
98 |
99 | function SyncedCodeMirror({ yText, editorSettings }) {
100 | const [extensions, setExtensions] = useState();
101 | useEffect(() => {
102 | if (!yText) return null;
103 | const undoManager = new Y.UndoManager(yText);
104 | setExtensions(yCollab(yText, null, { undoManager }));
105 | }, [yText]);
106 |
107 | // Don't render until the extensions are ready.
108 | if (!extensions) return null;
109 |
110 | return (
111 | {
116 | // Make sure the initial document value is the yText value. Really should ensure there's a value set on the
117 | console.log("oninit", yText.toString());
118 | view.dispatch({
119 | changes: {
120 | from: 0,
121 | to: view.state.doc.length,
122 | insert: yText.toString(),
123 | },
124 | });
125 | }}
126 | />
127 | );
128 | }
129 |
--------------------------------------------------------------------------------
/styles/Home.module.scss:
--------------------------------------------------------------------------------
1 | .main {
2 | display: grid;
3 | grid-template-columns: minmax(auto, 18em) 2fr;
4 | gap: 1rem;
5 | padding: 1rem;
6 | align-items: start;
7 |
8 | h2,
9 | h3 {
10 | margin: 0 0 1rem;
11 | }
12 | }
13 |
14 | .header {
15 | grid-column: 1 / -1;
16 | border-bottom: 3px solid #333;
17 | padding-bottom: 1rem;
18 | h1 {
19 | margin: 0;
20 | }
21 | p {
22 | max-width: 750px;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/styles/OLD-THEMES/_theme-bits.scss:
--------------------------------------------------------------------------------
1 | @mixin light-theme-stuff {
2 | .CodeMirror-cursor {
3 | border-left-color: black !important;
4 | }
5 | .CodeMirror-selected {
6 | background: rgba(black, 0.05);
7 | }
8 | .CodeMirror-focused .CodeMirror-selected {
9 | background: rgba(black, 0.1);
10 | }
11 | .CodeMirror-matchingbracket {
12 | border-bottom: 1px solid rgba(black, 0.5);
13 | }
14 | .CodeMirror-matchingtag {
15 | border-bottom: 1px solid rgba(black, 0.3);
16 | }
17 | .expander {
18 | span {
19 | text-shadow: none;
20 | }
21 | &:hover,
22 | &:focus {
23 | span {
24 | color: $gray-dark-4;
25 | }
26 | }
27 | }
28 | .powers {
29 | border-bottom: 1px solid rgba(black, 0.075);
30 | }
31 | .cm-searching {
32 | background: rgba(black, 0.1);
33 | outline: 2px solid rgba(black, 0.5);
34 | }
35 | .console-command-line {
36 | color: $gray-dark-3;
37 | background: $gray-light-6;
38 | border-bottom: 1px solid $gray-light-3;
39 | border-top: 1px solid $gray-light-3;
40 | }
41 | .console-command-line-input {
42 | color: $gray-dark-5;
43 | }
44 | .CodeMirror-hints,
45 | .emmet-abbreviation-preview {
46 | border: 1px solid $gray-light-3;
47 | background: white;
48 | }
49 | .CodeMirror-hint {
50 | color: black;
51 | }
52 | li.CodeMirror-hint-active {
53 | background: $blue;
54 | color: white;
55 | }
56 |
57 | /*
58 | When you have a light theme active, the Editor View should go FULL ON WHITE!
59 | */
60 |
61 | .main-header .header-wrap {
62 | box-shadow: 0 2px 5px rgba(black, 0.2);
63 | }
64 |
65 | body.room-editor,
66 | body.editor, // mobile
67 | body.room-collab,
68 | body.room-professor,
69 | body.room-pres {
70 | .main-header,
71 | .main-header .header-wrap,
72 | .editor-footer {
73 | background: white;
74 | color: black;
75 | .mini-logo path {
76 | fill: black;
77 | }
78 | }
79 | [data-component='Logo'] svg {
80 | fill: $gray-dark-5;
81 | }
82 |
83 | #item-title {
84 | a,
85 | > span,
86 | + div a {
87 | color: black;
88 | }
89 | }
90 |
91 | .editor-actions {
92 | background: white;
93 | }
94 |
95 | // Buttons
96 | .editor-footer,
97 | .footer-actions,
98 | .footer-actions,
99 | .editor-actions,
100 | .editor-actions-menu,
101 | .footer-right {
102 | .button {
103 | background: var(--button-bg);
104 | color: var(--button-color);
105 | }
106 |
107 | --button-bg: var(--gray-light-6);
108 | --button-color: var(--gray-dark-4);
109 | --button-hover-bg: var(--gray-light-5);
110 | --button-hover-color: var(--gray-dark-5);
111 | }
112 |
113 | .view-switcher {
114 | background: white;
115 | color: black;
116 | .link-list {
117 | a {
118 | color: $gray-dark-3;
119 | &:hover:not(.active) {
120 | color: $gray-dark-2;
121 | background: $gray-light-5;
122 | }
123 | }
124 | .active {
125 | background: $gray-light-3;
126 | }
127 | }
128 | }
129 |
130 | .navigation-wrap,
131 | .editor-footer {
132 | .student-count,
133 | span,
134 | time {
135 | color: $gray-dark-3;
136 | }
137 | }
138 | .editor-footer {
139 | border-top-color: $gray-light-3;
140 | }
141 |
142 | .drawer-comments {
143 | background: white;
144 | color: black;
145 |
146 | .comment-list li:nth-child(odd) {
147 | background: rgba(0, 0, 0, 0.1);
148 | }
149 | .comment-username {
150 | color: $blue;
151 | &:hover,
152 | &:focus {
153 | color: $blue-dark;
154 | }
155 | }
156 | }
157 | .drawer-comments-tab {
158 | background: linear-gradient(to bottom, white, $gray-light-5);
159 | box-shadow: -5px 0 10px -10px rgba($gray-dark-4, 0.3),
160 | 5px 0 10px -10px rgba($gray-dark-4, 0.3);
161 | color: black;
162 | border-color: $yellow;
163 | }
164 |
165 | .editor-resizer-console,
166 | .editor-resizer {
167 | background: $gray-light-3;
168 | }
169 | .result {
170 | background: white;
171 | }
172 | .loading-text {
173 | color: $gray-dark-5;
174 | } // specific to layouts
175 | &.layout-side .resizer {
176 | background: white;
177 | box-shadow: -1px 0 1px rgba(black, 0.1), 1px 0 1px rgba(black, 0.1);
178 | }
179 | &.layout-top .resizer,
180 | &.layout-top .top-boxes .editor-resizer {
181 | background: white;
182 | border: 0;
183 | box-shadow: 0 -1px 1px rgba(black, 0.1), 0 1px 1px rgba(black, 0.1);
184 | }
185 | }
186 |
187 | /* Buttons */
188 |
189 | // body.solarized-light,
190 | // body.xq-light,
191 | // body.duotone-light,
192 | // body.mdn-like,
193 | // body.highcontrast-light,
194 | // body.oceanic-light,
195 | // body.classic {
196 | // }
197 |
198 | /* Projects */
199 | .project-editor-warning {
200 | background: rgba(black, 0.5);
201 | }
202 |
203 | // 404 screen for Project Editor
204 | .loading-error-message {
205 | color: black;
206 | opacity: 0.8;
207 | }
208 |
209 | .collaborators-indicators {
210 | > span {
211 | background: $gray-dark-3;
212 | text-shadow: 0 1px 3px rgba(black, 0.3);
213 | }
214 | }
215 | }
216 |
217 | @mixin dark-theme-stuff {
218 | .CodeMirror-cursor {
219 | border-left-color: white !important;
220 | }
221 | .CodeMirror-selected {
222 | background: rgba(white, 0.05);
223 | }
224 | .CodeMirror-focused .CodeMirror-selected {
225 | background: rgba(white, 0.1);
226 | }
227 | .CodeMirror-matchingbracket {
228 | border-bottom: 1px solid rgba(white, 0.5);
229 | }
230 | .CodeMirror-matchingtag {
231 | // longer area... needs to be less intense
232 | border-bottom: 1px solid rgba(white, 0.3);
233 | }
234 | .powers {
235 | border-bottom: 1px solid rgba(white, 0.05);
236 | }
237 | .cm-searching {
238 | background: black;
239 | outline: 2px solid rgba(white, 0.25);
240 | }
241 | .CodeMirror-hints,
242 | .emmet-abbreviation-preview {
243 | border: 1px solid $gray-dark-3;
244 | background: $gray-dark-6;
245 | }
246 | .CodeMirror-hint {
247 | color: white;
248 | }
249 | li.CodeMirror-hint-active {
250 | background: $gray-light-3;
251 | color: black;
252 | }
253 |
254 | /* Projects */
255 | .project-editor-warning {
256 | background: rgba(white, 0.1);
257 | }
258 | }
259 |
260 | @mixin editorStyles($background, $color, $gutter, $scrollbar) {
261 | body.editor {
262 | background: $background;
263 | }
264 | .box.box.box, /* GROSS specificity war with _codemirror.scss */
265 | .editor .top-boxes,
266 | .CodeMirror-gutter-wrapper,
267 | body.project .editor-pane,
268 | body.project .editor {
269 | background: $background;
270 | pre {
271 | color: $color;
272 | }
273 | }
274 | .CodeMirror-guttermarker-subtle,
275 | .CodeMirror-linenumber {
276 | color: $gutter;
277 | }
278 |
279 | #output pre,
280 | #output iframe {
281 | @include scrollbars(0.5em, $scrollbar, none);
282 | }
283 | .CodeMirror-simplescroll-horizontal div,
284 | .CodeMirror-simplescroll-vertical div {
285 | background: $scrollbar;
286 | }
287 | }
288 |
289 | // Generic styles that apply to all themes.
290 | // NOTES
291 | // - .tag and .atom should be the same (for CSS selectors), or do .box-css specific styles
292 | .cm-header {
293 | font-weight: bold;
294 | }
295 |
296 | .cm-strong {
297 | font-weight: bold;
298 | }
299 |
300 | .cm-em {
301 | font-style: italic;
302 | }
303 |
--------------------------------------------------------------------------------
/styles/OLD-THEMES/classic.scss:
--------------------------------------------------------------------------------
1 | @import 'cpstyles/colors';
2 | @import 'cpstyles/bits';
3 |
4 | @import 'editor/themes/theme-bits';
5 | @include light-theme-stuff;
6 |
7 | $black: black;
8 | $blue: #219;
9 | $red: #a11;
10 | $green: #164;
11 | $lightGray: #ccc;
12 | $midGray: #555;
13 | $purple: #708;
14 |
15 | .cm-keyword {
16 | color: $blue;
17 | } // var
18 | .cm-atom {
19 | color: $blue;
20 | } // #tag
21 | .box-html .cm-atom {
22 | color: $red;
23 | } // markdown blockquote
24 | .cm-number {
25 | color: $green;
26 | } // 20, 20px
27 | .cm-unit {
28 | color: $green;
29 | } // px
30 | .cm-def {
31 | color: $purple;
32 | } // function([this])
33 | .cm-variable {
34 | color: $blue;
35 | } // margin, coffeescript var
36 | .cm-variable-2 {
37 | color: $black;
38 | } // for (key in [this]), markdown li, decimals witout 0 in front
39 | .cm-property {
40 | color: $blue;
41 | } // getElementById
42 | .cm-operator {
43 | color: $black;
44 | } // CoffeeScript ->
45 | .cm-comment {
46 | color: $lightGray;
47 | } // /* test */
48 | .cm-string {
49 | color: $red;
50 | } // href=["val"]
51 | .cm-string-2 {
52 | color: $red;
53 | } // match([this])
54 | .cm-meta {
55 | color: $blue;
56 | } // @font-face, -webkit-
57 | .cm-header {
58 | color: $red;
59 | } //
60 | .cm-tag {
61 | color: $blue;
62 | } // body
63 | .box-css .cm-tag {
64 | color: $blue;
65 | } // p
66 | .cm-attribute {
67 | color: $midGray;
68 | } // e.g. href
69 | .cm-strong {
70 | color: $midGray;
71 | } // **markdown**
72 | .cm-em {
73 | color: $midGray;
74 | } // *markdown* _markdown_
75 | .cm-qualifier {
76 | color: $blue;
77 | } // #id
78 | .cm-builtin {
79 | color: $blue;
80 | } // .class
81 |
82 | @include editorStyles(#ffffff, #999999, #cccccc, #cccccc);
83 |
84 | .box-title {
85 | color: #555;
86 | }
87 | .powers {
88 | .mini-button {
89 | background: #999;
90 | &:hover,
91 | &:focus {
92 | background: #635c48;
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/styles/OLD-THEMES/duotone-dark.scss:
--------------------------------------------------------------------------------
1 | @import 'cpstyles/colors';
2 | @import 'cpstyles/bits';
3 |
4 | @import 'editor/themes/theme-bits';
5 | @include dark-theme-stuff;
6 |
7 | .cm-property {
8 | color: #9b87fd;
9 | }
10 | .cm-punctuation,
11 | .cm-unit,
12 | .cm-negative {
13 | color: #e09142;
14 | }
15 | .cm-string {
16 | color: #ffba76;
17 | }
18 | .cm-operator {
19 | color: #ffa852;
20 | }
21 | .cm-positive {
22 | color: #6a51e6;
23 | }
24 | .cm-variable-2,
25 | .cm-variable-3,
26 | .cm-string-2,
27 | .cm-url {
28 | color: #6a51e6;
29 | }
30 | .cm-def,
31 | .cm-tag,
32 | .cm-builtin,
33 | .cm-qualifier,
34 | .cm-header,
35 | .cm-em {
36 | color: #eeebff;
37 | }
38 | .cm-bracket,
39 | .cm-comment {
40 | color: #6c6783;
41 | }
42 | .cm-error,
43 | .cm-invalidchar {
44 | background: rgba(#f00, 0.25);
45 | }
46 | .cm-atom,
47 | .cm-number,
48 | .cm-keyword,
49 | .cm-variable,
50 | .cm-attribute,
51 | .cm-quote,
52 | .cm-hr,
53 | .cm-link {
54 | color: #ffcc99;
55 | }
56 |
57 | @include editorStyles(#2a2734, #6c6783, #545167, #221f2a);
58 |
--------------------------------------------------------------------------------
/styles/OLD-THEMES/duotone-light.scss:
--------------------------------------------------------------------------------
1 | @import 'cpstyles/colors';
2 | @import 'cpstyles/bits';
3 |
4 | @import 'editor/themes/theme-bits';
5 | @include light-theme-stuff;
6 |
7 | .cm-property {
8 | color: #b29762;
9 | }
10 | .cm-punctuation,
11 | .cm-unit,
12 | .cm-negative {
13 | color: #063289;
14 | }
15 | .cm-string {
16 | color: #1657da;
17 | }
18 | .cm-operator {
19 | color: #0e4ecd;
20 | }
21 | .cm-positive {
22 | color: #896724;
23 | }
24 | .cm-variable-2,
25 | .cm-variable-3,
26 | .cm-string-2,
27 | .cm-url {
28 | color: #896724;
29 | }
30 | .cm-def,
31 | .cm-tag,
32 | .cm-builtin,
33 | .cm-qualifier,
34 | .cm-header,
35 | .cm-em {
36 | color: #2d2006;
37 | }
38 | .cm-bracket,
39 | .cm-comment {
40 | color: #b6ad9a;
41 | }
42 | .cm-error,
43 | .cm-invalidchar {
44 | color: #f00;
45 | }
46 |
47 | @include editorStyles(#faf8f5, #b29762, #dbcfb8, #eeeeee);
48 |
49 | .box-title {
50 | color: #2d2006;
51 | }
52 | .powers {
53 | .mini-button {
54 | background: #bbb;
55 | &:hover,
56 | &:focus {
57 | background: #b29762;
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/styles/OLD-THEMES/highcontrast-dark.scss:
--------------------------------------------------------------------------------
1 | @import 'cpstyles/colors';
2 | @import 'cpstyles/bits';
3 |
4 | @import 'editor/themes/theme-bits';
5 | @include dark-theme-stuff;
6 |
7 | .cm-keyword {
8 | color: $yellow;
9 | }
10 | .cm-atom {
11 | color: mix($yellow, $green);
12 | }
13 | .box-html .cm-atom {
14 | color: $red;
15 | }
16 | .cm-def {
17 | color: $blue;
18 | }
19 | .cm-variable {
20 | color: $gray-light-3;
21 | }
22 | .cm-variable-2 {
23 | color: $green;
24 | }
25 | .cm-variable-3 {
26 | color: white;
27 | }
28 | .cm-header {
29 | color: $red;
30 | }
31 | .cm-number {
32 | color: mix($green, $blue);
33 | }
34 | .cm-property {
35 | color: mix($blue, $purple);
36 | }
37 | .cm-attribute {
38 | color: $gray-light-5;
39 | }
40 | .cm-builtin {
41 | color: $purple;
42 | }
43 | .cm-qualifier {
44 | color: $yellow;
45 | }
46 | .cm-operator {
47 | color: $green;
48 | }
49 | .cm-meta {
50 | color: $blue;
51 | }
52 | .cm-string {
53 | color: mix($green, $blue);
54 | }
55 | .cm-string-2 {
56 | color: mix($red, $purple);
57 | }
58 | .cm-tag {
59 | color: $yellow;
60 | }
61 | .box-css .cm-tag {
62 | color: mix($red, $yellow);
63 | }
64 | .cm-tag.cm-bracket {
65 | color: $gray;
66 | }
67 | .cm-comment {
68 | color: desaturate(mix($gray-light-2, $blue), 40%);
69 | }
70 |
71 | @include editorStyles(
72 | $gray-dark-7,
73 | $gray-light-4,
74 | rgba($gray-dark-2, 0.6),
75 | lighten($gray-dark-5, 5%)
76 | );
77 |
78 | .powers {
79 | .mini-button {
80 | background: $gray-dark-4;
81 | &:hover,
82 | &:focus {
83 | background: $gray-light-3;
84 | svg {
85 | fill: black;
86 | }
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/styles/OLD-THEMES/highcontrast-light.scss:
--------------------------------------------------------------------------------
1 | @import 'cpstyles/colors';
2 | @import 'cpstyles/bits';
3 |
4 | @import 'editor/themes/theme-bits';
5 | @include light-theme-stuff;
6 |
7 | .cm-keyword {
8 | color: #ca2825;
9 | }
10 | .cm-atom {
11 | color: #0b6d6c;
12 | }
13 | .box-html .cm-atom {
14 | color: #0b6d6c;
15 | }
16 | .cm-def {
17 | color: #7c47b2;
18 | }
19 | .cm-variable {
20 | color: mix(#7c47b2, #3172bc);
21 | }
22 | .cm-variable-2 {
23 | color: #7c47b2;
24 | }
25 | .cm-variable-3 {
26 | color: #000;
27 | }
28 | .cm-header {
29 | color: #ca2825;
30 | }
31 | .cm-number {
32 | color: #048500;
33 | }
34 | .cm-property {
35 | color: #3172bc;
36 | }
37 | .cm-attribute {
38 | color: #5a5f73;
39 | }
40 | .cm-builtin {
41 | color: #7c47b2;
42 | }
43 | .cm-qualifier {
44 | color: #ca2825;
45 | }
46 | .cm-operator {
47 | color: #0b6d6c;
48 | }
49 | .cm-meta {
50 | color: #3172bc;
51 | }
52 | .cm-string {
53 | color: #0b6d6c;
54 | }
55 | .cm-string-2 {
56 | color: mix(#ca2825, #7c47b2);
57 | }
58 | .cm-tag {
59 | color: #ca2825;
60 | }
61 | .box-css .cm-tag {
62 | color: mix(#ca2825, $yellow-dark);
63 | }
64 | .cm-tag.cm-bracket {
65 | color: #5a5f73;
66 | }
67 | .cm-comment {
68 | color: #5a5f73;
69 | }
70 |
71 | @include editorStyles(mix($yellow, #fff, 2%), #000, #000, rgba(black, 0.05));
72 |
73 | .box-title {
74 | color: #5a5f73;
75 | }
76 | .powers {
77 | .mini-button {
78 | background: rgba(black, 0.3);
79 | &:hover,
80 | &:focus {
81 | background: rgba(black, 0.5);
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/styles/OLD-THEMES/mdn-like.scss:
--------------------------------------------------------------------------------
1 | @import 'cpstyles/colors';
2 | @import 'cpstyles/bits';
3 |
4 | @import 'editor/themes/theme-bits';
5 | @include light-theme-stuff;
6 |
7 | .cm-keyword {
8 | color: #007bbb;
9 | }
10 | .cm-atom {
11 | color: #4d4e53;
12 | }
13 | .cm-number {
14 | color: #4d4e53;
15 | }
16 | .cm-def {
17 | color: #5c4e53;
18 | }
19 | .cm-variable-2,
20 | .cm-tag {
21 | color: #690;
22 | }
23 | .cm-variable-3 {
24 | color: #07a;
25 | }
26 | .cm-variable {
27 | color: #07a;
28 | }
29 | .cm-property {
30 | color: #905;
31 | }
32 | .cm-qualifier {
33 | color: #690;
34 | }
35 | .cm-operator {
36 | color: #cda869;
37 | }
38 | .cm-comment {
39 | color: #777;
40 | }
41 | .cm-string {
42 | color: #07a;
43 | }
44 | .cm-string-2 {
45 | color: #bd6b18;
46 | }
47 | .cm-meta {
48 | color: #000;
49 | }
50 | .cm-builtin {
51 | color: #9b7536;
52 | }
53 | .cm-tag {
54 | color: #9b0064;
55 | }
56 | .cm-attribute {
57 | color: #66993e;
58 | }
59 | .cm-header {
60 | color: #ff6400;
61 | }
62 | .cm-hr {
63 | color: #aeaeae;
64 | }
65 | .cm-link {
66 | color: #ad9361;
67 | font-style: italic;
68 | text-decoration: none;
69 | }
70 | .cm-error {
71 | border-bottom: 1px solid red;
72 | }
73 |
74 | @include editorStyles(
75 | #f7f8f9
76 | url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8AgMAAABHkjHhAAAACVBMVEWAgIBaWlo+Pj7rTFvWAAAAA3RSTlMHCAw+VhR4AAAA+klEQVQoz4WSMW7EQAhFPxKWNh2FCx+HkaZI6RRb5DYbyVfIJXLKDCFoMbaTKSw/8ZnPAPjaH2xgZcUNUDADD7D9LtDBCLZ45fbkvo/30K8yeI64pPwl6znd/3n/Oe93P3ho9qeh72btTFzqkz0rsJle8Zr81OLEwZ1dv/713uWqvu2pl+k0fy7MWtj9r/tN5q/02z89qa/L4Dc2LvM93kezPfXlME/O86EbY/V9GB9ePX8G1/6W+/9h1dq/HGfTfzT3j/xNo7522Bfnqe5jO/fvhVthlfk434v3iO9zG/UOphyPeinPl1J8Gtaa7xPTa/Dk+RIs4deMvwGvcGsmsCvJ0AAAAABJRU5ErkJggg==),
77 | #4d4e53,
78 | #aaaaaa,
79 | #cccccc
80 | );
81 |
82 | .box-title {
83 | color: #555;
84 | }
85 | .powers {
86 | .mini-button {
87 | background: #999;
88 | &:hover,
89 | &:focus {
90 | background: #635c48;
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/styles/OLD-THEMES/oceanic-dark.scss:
--------------------------------------------------------------------------------
1 | @import 'cpstyles/colors';
2 | @import 'cpstyles/bits';
3 |
4 | @import 'editor/themes/theme-bits';
5 | @include dark-theme-stuff;
6 |
7 | .cm-comment {
8 | color: #65737e;
9 | }
10 | .cm-atom {
11 | color: #c594c5;
12 | }
13 | .cm-number {
14 | color: #c594c5;
15 | }
16 | .cm-property,
17 | .cm-attribute {
18 | color: #99c794;
19 | }
20 | .cm-keyword {
21 | color: #ec5f67;
22 | }
23 | .cm-string {
24 | color: #fac863;
25 | }
26 | .cm-variable {
27 | color: #99c794;
28 | }
29 | .cm-variable-2 {
30 | color: #6699cc;
31 | }
32 | .cm-def {
33 | color: #f99157;
34 | }
35 | .cm-error {
36 | background: rgba(#ec5f67, 0.4);
37 | }
38 | .cm-bracket {
39 | color: #cdd3de;
40 | }
41 | .cm-tag {
42 | color: #ec5f67;
43 | } // this overrides .cm-error
44 | .cm-link {
45 | color: #c594c5;
46 | }
47 |
48 | @include editorStyles(#1b2b34, #cdd3de, #5d5d5d, #666666);
49 |
--------------------------------------------------------------------------------
/styles/OLD-THEMES/oceanic-light.scss:
--------------------------------------------------------------------------------
1 | @import 'cpstyles/colors';
2 | @import 'cpstyles/bits';
3 |
4 | @import 'editor/themes/theme-bits';
5 | @include light-theme-stuff;
6 |
7 | .cm-comment {
8 | color: #ab7967;
9 | }
10 | .cm-atom {
11 | color: #b48ead;
12 | }
13 | .cm-number {
14 | color: #b48ead;
15 | }
16 | .cm-property,
17 | .cm-attribute {
18 | color: #a3be8c;
19 | }
20 | .cm-keyword {
21 | color: #bf616a;
22 | }
23 | .cm-string {
24 | color: #e1af1d;
25 | }
26 | .cm-variable {
27 | color: #a3be8c;
28 | }
29 | .cm-variable-2 {
30 | color: #8fa1b3;
31 | }
32 | .cm-def {
33 | color: #d08770;
34 | }
35 | .cm-error {
36 | background: rgba(#bf616a, 0.3);
37 | color: #65737e;
38 | }
39 | .cm-bracket {
40 | color: #343d46;
41 | }
42 | .cm-tag {
43 | color: #bf616a;
44 | }
45 | .cm-link {
46 | color: #b48ead;
47 | }
48 |
49 | @include editorStyles(#eff1f5, #343d46, #bbbbbb, #dddddd);
50 |
51 | .box-title {
52 | color: #555;
53 | }
54 | .powers {
55 | .mini-button {
56 | background: #999;
57 | &:hover,
58 | &:focus {
59 | background: #555;
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/styles/OLD-THEMES/panda.scss:
--------------------------------------------------------------------------------
1 | @import 'cpstyles/colors';
2 | @import 'cpstyles/bits';
3 |
4 | @import 'editor/themes/theme-bits';
5 | @include dark-theme-stuff;
6 |
7 | .cm-comment {
8 | color: #676b79;
9 | font-style: italic;
10 | }
11 | .cm-operator {
12 | color: #f3f3f3;
13 | }
14 | .cm-string {
15 | color: #19f9d8;
16 | }
17 | .cm-string-2 {
18 | color: #ffb86c;
19 | }
20 | .cm-tag {
21 | color: #ff2c6d;
22 | }
23 | .cm-meta {
24 | color: #b084eb;
25 | }
26 | .cm-number {
27 | color: #ffb86c;
28 | }
29 | .cm-atom {
30 | color: #ff2c6d;
31 | }
32 | .cm-keyword {
33 | color: #ff75b5;
34 | }
35 | .cm-variable {
36 | color: #ffb86c;
37 | }
38 | .cm-variable-2 {
39 | color: #ff9ac1;
40 | }
41 | .cm-variable-3 {
42 | color: #ff9ac1;
43 | }
44 | .cm-def {
45 | color: #e6e6e6;
46 | }
47 | .cm-property {
48 | color: #f3f3f3;
49 | }
50 | .cm-unit {
51 | color: #ffb86c;
52 | }
53 | .cm-attribute {
54 | color: #ffb86c;
55 | }
56 |
57 | @include editorStyles(#292a2b, #e6e6e6, #949496, #666666);
58 |
--------------------------------------------------------------------------------
/styles/OLD-THEMES/solarized-dark.scss:
--------------------------------------------------------------------------------
1 | @import "cpstyles/colors";
2 | @import "cpstyles/bits";
3 |
4 | @import "editor/themes/theme-bits";
5 | @include dark-theme-stuff;
6 |
7 | .cm-keyword {
8 | color: #268bd2;
9 | }
10 | .cm-atom {
11 | color: #859900;
12 | }
13 | .box-html .cm-atom {
14 | color: #cb4b16;
15 | }
16 | .cm-def {
17 | color: #b58900;
18 | }
19 | .cm-variable {
20 | color: #839496;
21 | }
22 | .cm-variable-2 {
23 | color: #859900;
24 | }
25 | .cm-variable-3 {
26 | color: #93a1a1;
27 | }
28 | .cm-header {
29 | color: #cb4b16;
30 | }
31 | .cm-number {
32 | color: #2aa198;
33 | }
34 | .cm-property {
35 | color: #b58900;
36 | }
37 | .cm-attribute {
38 | color: #839496;
39 | }
40 | .cm-builtin {
41 | color: #6c71c4;
42 | }
43 | .cm-qualifier {
44 | color: #268bd2;
45 | }
46 | .cm-operator {
47 | color: #859900;
48 | }
49 | .cm-meta {
50 | color: #268bd2;
51 | }
52 | .cm-string {
53 | color: #2aa198;
54 | }
55 | .cm-string-2 {
56 | color: #d33682;
57 | }
58 | .cm-tag {
59 | color: #268bd2;
60 | }
61 | .box-css .cm-tag {
62 | color: #859900;
63 | }
64 | .cm-tag.cm-bracket {
65 | color: #839496;
66 | }
67 | .cm-comment {
68 | color: #586e75;
69 | }
70 |
71 | @include editorStyles(
72 | #002b36,
73 | #77897e,
74 | rgba(#586e75, 0.6),
75 | lighten(#1a414a, 5%)
76 | );
77 |
78 | .powers {
79 | .mini-button {
80 | background: #092928;
81 | &:hover,
82 | &:focus {
83 | background: black;
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/styles/OLD-THEMES/solarized-light.scss:
--------------------------------------------------------------------------------
1 | @import 'cpstyles/colors';
2 | @import 'cpstyles/bits';
3 |
4 | @import 'editor/themes/theme-bits';
5 | @include light-theme-stuff;
6 |
7 | .cm-keyword {
8 | color: #268bd2;
9 | }
10 | .cm-atom {
11 | color: #859900;
12 | }
13 | .box-html .cm-atom {
14 | color: #cb4b16;
15 | }
16 | .cm-def {
17 | color: #b58900;
18 | }
19 | .cm-variable {
20 | color: #657b83;
21 | }
22 | .cm-variable-2 {
23 | color: #859900;
24 | }
25 | .cm-variable-3 {
26 | color: #586e75;
27 | }
28 | .cm-header {
29 | color: #cb4b16;
30 | }
31 | .cm-number {
32 | color: #2aa198;
33 | }
34 | .cm-property {
35 | color: #b58900;
36 | }
37 | .cm-attribute {
38 | color: #657b83;
39 | }
40 | .cm-builtin {
41 | color: #6c71c4;
42 | }
43 | .cm-qualifier {
44 | color: #268bd2;
45 | }
46 | .cm-operator {
47 | color: #859900;
48 | }
49 | .cm-meta {
50 | color: #268bd2;
51 | }
52 | .cm-string {
53 | color: #2aa198;
54 | }
55 | .cm-string-2 {
56 | color: #d33682;
57 | }
58 | .cm-tag {
59 | color: #268bd2;
60 | }
61 | .box-css .cm-tag {
62 | color: #859900;
63 | }
64 | .cm-tag.cm-bracket {
65 | color: #657b83;
66 | }
67 | .cm-comment {
68 | color: #93a1a1;
69 | }
70 |
71 | @include editorStyles(#fdf6e3, #657b83, #657b83, rgba(black, 0.05));
72 |
73 | .box-title {
74 | color: #7b868e;
75 | }
76 | .powers {
77 | .mini-button {
78 | background: rgba(black, 0.3);
79 | &:hover,
80 | &:focus {
81 | background: rgba(black, 0.5);
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/styles/OLD-THEMES/tomorrow-night.scss:
--------------------------------------------------------------------------------
1 | @import 'cpstyles/colors';
2 | @import 'cpstyles/bits';
3 |
4 | @import 'editor/themes/theme-bits';
5 | @include dark-theme-stuff;
6 |
7 | $midGray: #c3c6c4;
8 | $darkGray: $gray-dark-2;
9 | $orange: #dd925f;
10 | $purple: #ae94c0;
11 | $yellow: #efc371;
12 | $green: #b5bc67;
13 |
14 | .cm-keyword {
15 | color: $yellow;
16 | } // var
17 | .cm-atom {
18 | color: $yellow;
19 | } // #tag
20 | .box-html .cm-atom {
21 | color: $green;
22 | } // markdown blockquote
23 | .cm-number {
24 | color: $orange;
25 | } // 20, 20px
26 | .cm-unit {
27 | color: $orange;
28 | } // px
29 | .cm-def {
30 | color: $yellow;
31 | } // function([this])
32 | .cm-variable {
33 | color: $yellow;
34 | } // margin, coffeescript var
35 | .cm-variable-2 {
36 | color: $purple;
37 | } // for (key in [this]), markdown li, decimals witout 0 in front
38 | .cm-property {
39 | color: $purple;
40 | } // getElementById
41 | .cm-operator {
42 | color: $midGray;
43 | } // CoffeeScript ->
44 | .cm-comment {
45 | color: $darkGray;
46 | } // /* test */
47 | .cm-string {
48 | color: $green;
49 | } // href=["val"]
50 | .cm-string-2 {
51 | color: white;
52 | } // match([this])
53 | .cm-meta {
54 | color: $green;
55 | } // @font-face
56 | .cm-header {
57 | color: $orange;
58 | } //
59 | .cm-tag {
60 | color: $yellow;
61 | } // body
62 | .box-css .cm-tag {
63 | color: $yellow;
64 | } //
65 | .cm-attribute {
66 | color: $midGray;
67 | } // e.g. href
68 | .cm-strong {
69 | color: $yellow;
70 | } //
71 | .cm-em {
72 | color: $yellow;
73 | } //
74 | .cm-qualifier {
75 | color: $yellow;
76 | } // #id
77 | .cm-builtin {
78 | color: $yellow;
79 | } // .class
80 |
81 | @include editorStyles(#1d1f20, #c3c6c4, #444444, #666666);
82 |
--------------------------------------------------------------------------------
/styles/OLD-THEMES/twilight.scss:
--------------------------------------------------------------------------------
1 | @import 'cpstyles/colors';
2 | @import 'cpstyles/bits';
3 |
4 | @import 'editor/themes/theme-bits';
5 | @include dark-theme-stuff;
6 |
7 | $yellow: #ddca7e;
8 | $blue: #809bbd;
9 | $lightGray: #eee;
10 | $midGray: #ccc;
11 | $darkGray: $gray-dark-2;
12 | $purple: #9a8297;
13 | $brown: #a7925a;
14 | $orange: #ff6400;
15 | $burnt: #d0782a;
16 | $green: #96b38a;
17 | $white: white;
18 |
19 | .cm-keyword {
20 | color: $yellow;
21 | } // var
22 | .cm-atom {
23 | color: $yellow;
24 | } // #tag
25 | .box-html .cm-atom {
26 | color: $green;
27 | } // markdown blockquote
28 | .cm-number {
29 | color: $burnt;
30 | } // 20, 20px
31 | .cm-unit {
32 | color: $burnt;
33 | } // px
34 | .cm-def {
35 | color: $blue;
36 | } // function([this])
37 | .cm-variable {
38 | color: $yellow;
39 | } // margin, coffeescript var
40 | .cm-variable-2 {
41 | color: $blue;
42 | } // for (key in [this]), markdown li, decimals witout 0 in front
43 | .cm-property {
44 | color: $purple;
45 | } // getElementById
46 | .cm-operator {
47 | color: $midGray;
48 | } // CoffeeScript ->
49 | .cm-comment {
50 | color: $darkGray;
51 | } // /* test */
52 | .cm-string {
53 | color: $green;
54 | } // href=["val"]
55 | .cm-string-2 {
56 | color: $green;
57 | } // match([this])
58 | .cm-meta {
59 | color: $purple;
60 | } // @font-face
61 | .cm-header {
62 | color: $orange;
63 | } //
64 | .cm-tag {
65 | color: $brown;
66 | } // body
67 | .box-css .cm-tag {
68 | color: $yellow;
69 | } //
70 | .cm-attribute {
71 | color: $yellow;
72 | } // e.g. href
73 | .cm-strong {
74 | color: $yellow;
75 | } //
76 | .cm-em {
77 | color: $yellow;
78 | } //
79 | .cm-qualifier {
80 | color: $yellow;
81 | } // #id
82 | .cm-builtin {
83 | color: $yellow;
84 | } // .class
85 |
86 | @include editorStyles(#1d1e22, white, #34363e, #666b7a);
87 |
--------------------------------------------------------------------------------
/styles/OLD-THEMES/xq-light.scss:
--------------------------------------------------------------------------------
1 | @import 'cpstyles/colors';
2 | @import 'cpstyles/bits';
3 |
4 | @import 'editor/themes/theme-bits';
5 | @include light-theme-stuff;
6 |
7 | .cm-keyword {
8 | color: #5a5cad;
9 | line-height: 1em;
10 | font-weight: bold;
11 | }
12 |
13 | .cm-atom {
14 | color: #6c8cd5;
15 | }
16 |
17 | .cm-number {
18 | color: #164;
19 | }
20 |
21 | .cm-def {
22 | text-decoration: underline;
23 | }
24 |
25 | .cm-variable {
26 | color: black;
27 | }
28 |
29 | .cm-variable-2 {
30 | color: black;
31 | }
32 |
33 | .cm-variable-3 {
34 | color: black;
35 | }
36 |
37 | .cm-property {
38 | color: #999;
39 | }
40 |
41 | .cm-operator {
42 | color: #5a5cad;
43 | }
44 |
45 | .cm-comment {
46 | color: #0080ff;
47 | font-style: italic;
48 | }
49 |
50 | .cm-string {
51 | color: red;
52 | }
53 |
54 | .cm-meta {
55 | color: #0080ff;
56 | }
57 |
58 | .cm-qualifier {
59 | color: grey;
60 | }
61 |
62 | .cm-builtin {
63 | color: #7ea656;
64 | }
65 |
66 | .cm-bracket {
67 | color: #cc7;
68 | }
69 |
70 | .cm-tag {
71 | color: #3f7f7f;
72 | }
73 |
74 | .cm-attribute {
75 | color: #7f007f;
76 | }
77 |
78 | .cm-error {
79 | color: #f00;
80 | }
81 |
82 | @include editorStyles(white, black, #999, #999);
83 | .box-title {
84 | color: #555;
85 | }
86 |
87 | .powers {
88 | .mini-button {
89 | background: #999;
90 | &:hover,
91 | &:focus {
92 | background: #635c48;
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/styles/globals.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 | html,
5 | body {
6 | background: #131417;
7 | color: white;
8 | padding: 0;
9 | margin: 0;
10 | font-family: Lato, system-ui;
11 | }
12 |
13 | h1 {
14 | font-family: "Telefon Black", Sans-Serif;
15 | }
16 |
17 | a {
18 | color: inherit;
19 | }
20 |
21 | .cm-editor {
22 | padding: 0.5rem;
23 | height: 250px;
24 | }
25 | /* .cm-scroller {
26 | font-size: 13px;
27 | font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace !important;
28 | line-height: 1.5 !important;
29 | } */
30 |
31 | /* TODO: Styled Scrollbars */
32 |
33 | [data-supported] {
34 | padding: .75rem;
35 | border-radius: 8px;
36 | }
37 | [data-supported]::before {
38 | display: block;
39 | padding: 0 0 0.25rem;
40 | border-bottom: 3px solid;
41 | margin: 0 0 0.5rem 0;
42 | }
43 |
44 | [data-supported="SUPPORTED"] {
45 | background: linear-gradient(to bottom, #004700, transparent);
46 | }
47 |
48 | [data-supported="SUPPORTED"]::before {
49 | content: "✅ Supported";
50 | border-color: rgb(59, 250, 59);
51 | }
52 |
53 | [data-supported="NOT_SUPPORTED"] {
54 | background: linear-gradient(to bottom, #730000, transparent);
55 | }
56 | [data-supported="NOT_SUPPORTED"]::before {
57 | content: "❌ Not Supported";
58 | border-color: red;
59 | }
60 |
61 | [data-supported="PARTIAL_SUPPORT"] {
62 | background: linear-gradient(to bottom, #504d00, transparent);
63 | }
64 | [data-supported="PARTIAL_SUPPORT"]::before {
65 | content: "🤏 Partial Support";
66 | border-color: yellow;
67 | }
68 |
--------------------------------------------------------------------------------