Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added Codemirror 6 legacy mode support (#2035)
Implemented the codemirror.next legacy mode support for graphql mode. This only covers syntax highlighting. Autocomplete, jump and info extensions still need to be implemented to have feature parity with Codemirror v5. From #2022
- Loading branch information
Showing
15 changed files
with
534 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
'codemirror-graphql': minor | ||
'example-cm6-graphql-parcel': patch | ||
--- | ||
|
||
Added Codemirror 6 legacy support |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.cache/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
## Codemirror 6 Parcel Example | ||
|
||
This example demonstrates how to transpile your own custom ES6 Codemirror 6 GraphQL implementation with parcel bundler. | ||
|
||
### Setup | ||
|
||
1. `yarn` and `yarn build` at the root of this repository, if you have not already. | ||
1. `yarn start` from this folder to start parcel dev mode. | ||
1. `yarn build` to find production ready files. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
{ | ||
"name": "example-cm6-graphql-parcel", | ||
"version": "1.1.10-alpha.8", | ||
"license": "MIT", | ||
"description": "GraphiQL Parcel Example", | ||
"main": "index.js", | ||
"private": true, | ||
"scripts": { | ||
"start": "parcel src/index.html -p 8080", | ||
"build": "parcel build src/index.html --public-url /" | ||
}, | ||
"browserslist": { | ||
"production": [ | ||
">0.2%", | ||
"not dead", | ||
"not op_mini all" | ||
], | ||
"development": [ | ||
"last 1 chrome version", | ||
"last 1 firefox version", | ||
"last 1 safari version" | ||
] | ||
}, | ||
"dependencies": { | ||
"@codemirror/basic-setup": "^0.19.0", | ||
"@codemirror/stream-parser": "^0.19.2", | ||
"codemirror-graphql": "^1.1.0", | ||
"graphql": "16.0.0-experimental-stream-defer.5", | ||
"typescript": "^3.4.4" | ||
}, | ||
"devDependencies": { | ||
"parcel-bundler": "^1.12.4", | ||
"worker-loader": "^2.0.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<html lang="en"> | ||
<head> | ||
<style> | ||
body { | ||
padding: 0; | ||
margin: 0; | ||
min-height: 100vh; | ||
} | ||
#root { | ||
height: 100vh; | ||
} | ||
</style> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> | ||
<title>CM6 GraphQL Editor Example</title> | ||
</head> | ||
|
||
<body> | ||
<div id="editor"></div> | ||
<script src="./index.ts"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { EditorState, EditorView, basicSetup } from '@codemirror/basic-setup'; | ||
import { StreamLanguage } from '@codemirror/stream-parser'; | ||
import { graphql } from 'codemirror-graphql/cm6-legacy/mode'; | ||
import query from './sample-query'; | ||
|
||
const state = EditorState.create({ | ||
doc: query, | ||
extensions: [ | ||
basicSetup, | ||
StreamLanguage.define(graphql), | ||
// javascript(), | ||
], | ||
}); | ||
|
||
const view = new EditorView({ | ||
state, | ||
parent: document.querySelector('#editor')!, | ||
}); | ||
|
||
// Hot Module Replacement | ||
if (module.hot) { | ||
module.hot.accept(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
const query = /* GraphQL */ ` | ||
# Copyright (c) 2021 GraphQL Contributors | ||
# All rights reserved. | ||
# | ||
# This source code is licensed under the BSD-style license found in the | ||
# LICENSE file in the root directory of this source tree. An additional grant | ||
# of patent rights can be found in the PATENTS file in the same directory. | ||
query queryName($foo: TestInput, $site: TestEnum = RED) { | ||
testAlias: hasArgs(string: "testString") | ||
... on Test { | ||
hasArgs( | ||
listEnum: [RED, GREEN, BLUE] | ||
int: 1 | ||
listFloat: [1.23, 1.3e-1, -1.35384e+3] | ||
boolean: true | ||
id: 123 | ||
object: $foo | ||
enum: $site | ||
) | ||
} | ||
test @include(if: true) { | ||
union { | ||
__typename | ||
} | ||
} | ||
...frag | ||
... @skip(if: false) { | ||
id | ||
} | ||
... { | ||
id | ||
} | ||
} | ||
mutation mutationName { | ||
setString(value: "newString") | ||
} | ||
subscription subscriptionName { | ||
subscribeToTest(id: "anId") { | ||
... on Test { | ||
id | ||
} | ||
} | ||
} | ||
fragment frag on Test { | ||
test @include(if: true) { | ||
union { | ||
__typename | ||
} | ||
} | ||
} | ||
`; | ||
|
||
export default query; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "es5", | ||
"lib": ["dom", "dom.iterable", "esnext"], | ||
"allowJs": true, | ||
"skipLibCheck": true, | ||
"esModuleInterop": true, | ||
"allowSyntheticDefaultImports": true, | ||
"strict": true, | ||
"forceConsistentCasingInFileNames": true, | ||
"module": "esnext", | ||
"sourceMap": true, | ||
"moduleResolution": "node", | ||
"resolveJsonModule": true, | ||
"isolatedModules": true, | ||
"noEmit": true, | ||
"jsx": "react" | ||
}, | ||
"include": ["src"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,4 +10,5 @@ coverage/ | |
/utils | ||
/variables | ||
/results | ||
/cm6-legacy | ||
/__tests__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import type { StreamParser } from '@codemirror/stream-parser'; | ||
import graphqlModeFactory from '../utils/mode-factory'; | ||
|
||
// Types of property 'token' are incompatible. | ||
// Type '((stream: StringStream, state: any) => string | null) | undefined' is not comparable to type '(stream: StringStream, state: any) => string | null'. | ||
export const graphql = (graphqlModeFactory({}) as unknown) as StreamParser<any>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/** | ||
* Copyright (c) 2021 GraphQL Contributors | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
*/ | ||
|
||
import CodeMirror from 'codemirror'; | ||
import { | ||
LexRules, | ||
ParseRules, | ||
isIgnored, | ||
onlineParser, | ||
} from 'graphql-language-service-parser'; | ||
import indent from './mode-indent'; | ||
|
||
/** | ||
* The GraphQL mode is defined as a tokenizer along with a list of rules, each | ||
* of which is either a function or an array. | ||
* | ||
* * Function: Provided a token and the stream, returns an expected next step. | ||
* * Array: A list of steps to take in order. | ||
* | ||
* A step is either another rule, or a terminal description of a token. If it | ||
* is a rule, that rule is pushed onto the stack and the parsing continues from | ||
* that point. | ||
* | ||
* If it is a terminal description, the token is checked against it using a | ||
* `match` function. If the match is successful, the token is colored and the | ||
* rule is stepped forward. If the match is unsuccessful, the remainder of the | ||
* rule is skipped and the previous rule is advanced. | ||
* | ||
* This parsing algorithm allows for incremental online parsing within various | ||
* levels of the syntax tree and results in a structured `state` linked-list | ||
* which contains the relevant information to produce valuable typeaheads. | ||
*/ | ||
const graphqlModeFactory: CodeMirror.ModeFactory<any> = config => { | ||
const parser = onlineParser({ | ||
eatWhitespace: stream => stream.eatWhile(isIgnored), | ||
lexRules: LexRules, | ||
parseRules: ParseRules, | ||
editorConfig: { tabSize: config.tabSize }, | ||
}); | ||
|
||
return { | ||
config, | ||
startState: parser.startState, | ||
token: (parser.token as unknown) as NonNullable< | ||
CodeMirror.Mode<any>['token'] | ||
>, // TODO: Check if the types are indeed compatible | ||
indent, | ||
electricInput: /^\s*[})\]]/, | ||
fold: 'brace', | ||
lineComment: '#', | ||
closeBrackets: { | ||
pairs: '()[]{}""', | ||
explode: '()[]{}', | ||
}, | ||
}; | ||
}; | ||
|
||
export default graphqlModeFactory; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/** | ||
* Copyright (c) 2021 GraphQL Contributors | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
*/ | ||
|
||
import CodeMirror from 'codemirror'; | ||
import { State } from 'graphql-language-service-parser'; | ||
|
||
// Seems the electricInput type in @types/codemirror is wrong (i.e it is written as electricinput instead of electricInput) | ||
export default function indent( | ||
this: CodeMirror.Mode<any> & { | ||
electricInput?: RegExp; | ||
config?: CodeMirror.EditorConfiguration; | ||
}, | ||
state: State, | ||
textAfter: string, | ||
) { | ||
const levels = state.levels; | ||
// If there is no stack of levels, use the current level. | ||
// Otherwise, use the top level, pre-emptively dedenting for close braces. | ||
const level = | ||
!levels || levels.length === 0 | ||
? state.indentLevel | ||
: levels[levels.length - 1] - | ||
(this.electricInput?.test(textAfter) ? 1 : 0); | ||
return (level || 0) * (this.config?.indentUnit || 0); | ||
} |
Oops, something went wrong.
d0c22c4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉 Published on https://monaco-graphql.netlify.app as production
🚀 Deployed on https://619d1d6c2406492a9810d98a--monaco-graphql.netlify.app
d0c22c4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉 Published on https://graphiql-test.netlify.app as production
🚀 Deployed on https://619d1d9f3a63d43b9ca53938--graphiql-test.netlify.app