Added Python lint checker to the editor

This commit is contained in:
Syrus Akbary 2015-11-28 14:32:16 -08:00
parent f3d7eedafd
commit 3c308b90fa
2 changed files with 50 additions and 6 deletions

View File

@ -31,7 +31,7 @@
.cm-def .cm-def
.cm-variable + .cm-keyword // lambda .cm-variable + .cm-keyword // lambda
&:not(.CodeMirror-lint-mark-error)
transition all .3s ease-in-out transition all .3s ease-in-out
background transparent background transparent

View File

@ -8,6 +8,7 @@ import schema from './schema';
import pypyjs_vm from 'pypyjs'; import pypyjs_vm from 'pypyjs';
import 'codemirror/mode/python/python'; import 'codemirror/mode/python/python';
import 'codemirror/addon/lint/lint';
import '../css/playground.styl'; import '../css/playground.styl';
if (typeof PUBLIC_PATH === "undefined") { if (typeof PUBLIC_PATH === "undefined") {
@ -32,6 +33,23 @@ class Query(graphene.ObjectType):
schema = graphene.Schema(query=Query) schema = graphene.Schema(query=Query)
`; `;
CodeMirror.registerHelper('lint', 'python', function (text, options, editor) {
return (options.errors || []).map((error) => {
var tokens = editor.getLineTokens(error.line - 1);
tokens = tokens.filter((token, pos) => {
return !!token.type || token.string.trim().length > 0;
});
if (!tokens) return [];
return {
message: `${error.name}: ${error.message}`,
severity: 'error',
type: 'syntax',
from: CodeMirror.Pos(error.line - 1, tokens[0].start),
to: CodeMirror.Pos(error.line - 1, tokens[tokens.length-1].end),
};
});
});
// function graphQLFetcher(graphQLParams) { // function graphQLFetcher(graphQLParams) {
// return fetch('http://swapi.graphene-python.org/graphql', { // return fetch('http://swapi.graphene-python.org/graphql', {
// method: 'post', // method: 'post',
@ -113,10 +131,13 @@ __graphene_executor = Executor([TrackResolver()], map_type=OrderedDict)
value: baseCode, value: baseCode,
mode: "python", mode: "python",
theme: "graphene", theme: "graphene",
// lineNumbers: true, lineNumbers: true,
tabSize: 4, tabSize: 4,
indentUnit: 4, indentUnit: 4,
gutters: ["CodeMirror-linenumbers", "breakpoints"] gutters: ["CodeMirror-linenumbers", "breakpoints"],
lint: {
errors: [],
},
}); });
this.editor.on("change", this.onEditorChange.bind(this)); this.editor.on("change", this.onEditorChange.bind(this));
} }
@ -132,6 +153,7 @@ __graphene_executor = Executor([TrackResolver()], map_type=OrderedDict)
this.createSchema(this.editor.getValue()); this.createSchema(this.editor.getValue());
} }
createSchema(code) { createSchema(code) {
if (this.previousCode == code) return;
console.log('createSchema'); console.log('createSchema');
this.validSchema = null; this.validSchema = null;
this.pypyjs.then(() => { this.pypyjs.then(() => {
@ -142,12 +164,16 @@ assert schema, 'You have to define a schema'
`) `)
}).then(() => { }).then(() => {
console.log('NO ERRORS'); console.log('NO ERRORS');
this.removeErrors();
this.validSchema = true; this.validSchema = true;
}, (err) => { }, (err) => {
console.log('ERROR', err); this.editor.options.lint.errors = [];
console.log('ERRORS', err);
this.logError(err);
this.validSchema = false; this.validSchema = false;
// this.editor.setGutterMarker(5, "breakpoints", syntaxError()); // this.editor.setGutterMarker(5, "breakpoints", syntaxError());
}).then(this.updateGraphiQL.bind(this)); }).then(this.updateGraphiQL.bind(this));
this.previousCode = code;
} }
updateGraphiQL() { updateGraphiQL() {
if (this.validSchema) { if (this.validSchema) {
@ -157,6 +183,24 @@ assert schema, 'You have to define a schema'
this.refs.graphiql.refs.docExplorer.forceUpdate(); this.refs.graphiql.refs.docExplorer.forceUpdate();
} }
} }
logError(error) {
var lines = error.trace.split('\n');
var file_errors = lines.map((errorLine) => {
return errorLine.match(/File "<string>", line (\d+)/);
}).filter((x) => !! x);
if (!file_errors.length) return;
var line = parseInt(file_errors[file_errors.length-1][1]);
error.line = line-2;
if (error.name == "ImportError" && error.message == "No module named django") {
error.message = "Django is not supported yet in Playground editor";
}
this.editor.options.lint.errors.push(error);
CodeMirror.signal(this.editor, 'change', this.editor);
}
removeErrors() {
this.editor.options.lint.errors = [];
CodeMirror.signal(this.editor, 'change', this.editor);
}
fetcher (graphQLParams) { fetcher (graphQLParams) {
if (!this.validSchema) { if (!this.validSchema) {
return graphQLFetcher(arguments); return graphQLFetcher(arguments);