Skip to content

Commit 3c308b9

Browse files
committed
Added Python lint checker to the editor
1 parent f3d7eed commit 3c308b9

File tree

2 files changed

+50
-6
lines changed

2 files changed

+50
-6
lines changed

docs/css/playground.styl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@
3131

3232
.cm-def
3333
.cm-variable + .cm-keyword // lambda
34-
35-
transition all .3s ease-in-out
36-
background transparent
34+
&:not(.CodeMirror-lint-mark-error)
35+
transition all .3s ease-in-out
36+
background transparent
3737

3838
.activeline
3939
.cm-def

docs/playground/page.js

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import schema from './schema';
88
import pypyjs_vm from 'pypyjs';
99

1010
import 'codemirror/mode/python/python';
11+
import 'codemirror/addon/lint/lint';
1112
import '../css/playground.styl';
1213

1314
if (typeof PUBLIC_PATH === "undefined") {
@@ -32,6 +33,23 @@ class Query(graphene.ObjectType):
3233
schema = graphene.Schema(query=Query)
3334
`;
3435

36+
CodeMirror.registerHelper('lint', 'python', function (text, options, editor) {
37+
return (options.errors || []).map((error) => {
38+
var tokens = editor.getLineTokens(error.line - 1);
39+
tokens = tokens.filter((token, pos) => {
40+
return !!token.type || token.string.trim().length > 0;
41+
});
42+
if (!tokens) return [];
43+
return {
44+
message: `${error.name}: ${error.message}`,
45+
severity: 'error',
46+
type: 'syntax',
47+
from: CodeMirror.Pos(error.line - 1, tokens[0].start),
48+
to: CodeMirror.Pos(error.line - 1, tokens[tokens.length-1].end),
49+
};
50+
});
51+
});
52+
3553
// function graphQLFetcher(graphQLParams) {
3654
// return fetch('http://swapi.graphene-python.org/graphql', {
3755
// method: 'post',
@@ -113,10 +131,13 @@ __graphene_executor = Executor([TrackResolver()], map_type=OrderedDict)
113131
value: baseCode,
114132
mode: "python",
115133
theme: "graphene",
116-
// lineNumbers: true,
134+
lineNumbers: true,
117135
tabSize: 4,
118136
indentUnit: 4,
119-
gutters: ["CodeMirror-linenumbers", "breakpoints"]
137+
gutters: ["CodeMirror-linenumbers", "breakpoints"],
138+
lint: {
139+
errors: [],
140+
},
120141
});
121142
this.editor.on("change", this.onEditorChange.bind(this));
122143
}
@@ -132,6 +153,7 @@ __graphene_executor = Executor([TrackResolver()], map_type=OrderedDict)
132153
this.createSchema(this.editor.getValue());
133154
}
134155
createSchema(code) {
156+
if (this.previousCode == code) return;
135157
console.log('createSchema');
136158
this.validSchema = null;
137159
this.pypyjs.then(() => {
@@ -142,12 +164,16 @@ assert schema, 'You have to define a schema'
142164
`)
143165
}).then(() => {
144166
console.log('NO ERRORS');
167+
this.removeErrors();
145168
this.validSchema = true;
146169
}, (err) => {
147-
console.log('ERROR', err);
170+
this.editor.options.lint.errors = [];
171+
console.log('ERRORS', err);
172+
this.logError(err);
148173
this.validSchema = false;
149174
// this.editor.setGutterMarker(5, "breakpoints", syntaxError());
150175
}).then(this.updateGraphiQL.bind(this));
176+
this.previousCode = code;
151177
}
152178
updateGraphiQL() {
153179
if (this.validSchema) {
@@ -157,6 +183,24 @@ assert schema, 'You have to define a schema'
157183
this.refs.graphiql.refs.docExplorer.forceUpdate();
158184
}
159185
}
186+
logError(error) {
187+
var lines = error.trace.split('\n');
188+
var file_errors = lines.map((errorLine) => {
189+
return errorLine.match(/File "<string>", line (\d+)/);
190+
}).filter((x) => !! x);
191+
if (!file_errors.length) return;
192+
var line = parseInt(file_errors[file_errors.length-1][1]);
193+
error.line = line-2;
194+
if (error.name == "ImportError" && error.message == "No module named django") {
195+
error.message = "Django is not supported yet in Playground editor";
196+
}
197+
this.editor.options.lint.errors.push(error);
198+
CodeMirror.signal(this.editor, 'change', this.editor);
199+
}
200+
removeErrors() {
201+
this.editor.options.lint.errors = [];
202+
CodeMirror.signal(this.editor, 'change', this.editor);
203+
}
160204
fetcher (graphQLParams) {
161205
if (!this.validSchema) {
162206
return graphQLFetcher(arguments);

0 commit comments

Comments
 (0)