render lint squigglies 4x faster

* turns out codemirror lint addon doesn't open an overall op,
  instead it creates an op for each marker.

* also, now there's no need to disable the lint option when initializing codemirror
This commit is contained in:
tophf 2017-12-01 03:49:09 +03:00
parent f5516db8f4
commit a6fbc9db11
3 changed files with 46 additions and 32 deletions

View File

@ -411,7 +411,6 @@ function setupCodeMirror(sectionDiv, code, index) {
$('.code-label', sectionDiv).insertAdjacentElement('afterend', wrapper);
}, {
value: code,
lint: null,
});
const wrapper = cm.display.wrapper;

View File

@ -1,26 +1,43 @@
/* global CodeMirror linterConfig */
'use strict';
CodeMirror.registerHelper('lint', 'csslint', code =>
linterConfig.invokeWorker({code, config: linterConfig.getCurrent()}).then(results =>
results.map(({line, col: ch, message, rule, type: severity}) => line && {
message,
from: {line: line - 1, ch: ch - 1},
to: {line: line - 1, ch},
rule: rule.id,
severity,
}).filter(Boolean)));
(() => {
CodeMirror.registerHelper('lint', 'csslint', invokeHelper);
CodeMirror.registerHelper('lint', 'stylelint', invokeHelper);
CodeMirror.registerHelper('lint', 'stylelint', code =>
linterConfig.invokeWorker({code, config: linterConfig.getCurrent()}).then(({results}) =>
!results[0] && [] ||
results[0].warnings.map(({line, column:ch, text, severity}) => ({
from: {line: line - 1, ch: ch - 1},
to: {line: line - 1, ch},
message: text
.replace('Unexpected ', '')
.replace(/^./, firstLetter => firstLetter.toUpperCase())
.replace(/\s*\([^(]+\)$/, ''), // strip the rule,
rule: text.replace(/^.*?\s*\(([^(]+)\)$/, '$1'),
severity,
}))));
const cookResults = {
csslint: results =>
results.map(({line, col: ch, message, rule, type: severity}) => line && {
message,
from: {line: line - 1, ch: ch - 1},
to: {line: line - 1, ch},
rule: rule.id,
severity,
}).filter(Boolean),
stylelint: ({results}) =>
!results[0] && [] ||
results[0].warnings.map(({line, column: ch, text, severity}) => ({
from: {line: line - 1, ch: ch - 1},
to: {line: line - 1, ch},
message: text
.replace('Unexpected ', '')
.replace(/^./, firstLetter => firstLetter.toUpperCase())
.replace(/\s*\([^(]+\)$/, ''), // strip the rule,
rule: text.replace(/^.*?\s*\(([^(]+)\)$/, '$1'),
severity,
})),
};
function invokeHelper(code, options, cm) {
const config = linterConfig.getCurrent();
return linterConfig.invokeWorker({code, config})
.then(cookResults[linterConfig.getName()])
.then(results => {
if (options && typeof options.preUpdateLinting === 'function') {
options.preUpdateLinting(cm);
}
return results;
});
}
})();

View File

@ -44,7 +44,11 @@ var linterConfig = {
return CodeMirror.lint && CodeMirror.lint[linter] ? {
getAnnotations: CodeMirror.lint[linter],
delay: prefs.get('editor.lintDelay'),
preUpdateLinting(cm) {
cm.startOperation();
},
onUpdateLinting(annotationsNotSorted, annotations, cm) {
cm.endOperation();
updateLintReport(cm, 0);
},
} : false;
@ -198,7 +202,9 @@ function updateLinter({immediately, linter = linterConfig.getName()} = {}) {
CodeMirror.defaults.lint = linterConfig.getForCodeMirror(linter);
const guttersOption = prepareGuttersOption();
editors.forEach(cm => {
cm.setOption('lint', CodeMirror.defaults.lint);
if (cm.options.lint !== CodeMirror.defaults.lint) {
cm.setOption('lint', CodeMirror.defaults.lint);
}
if (guttersOption) {
cm.setOption('guttersOption', guttersOption);
updateGutters(cm, guttersOption);
@ -235,14 +241,6 @@ function updateLinter({immediately, linter = linterConfig.getName()} = {}) {
}
function updateLintReport(cm, delay) {
if (cm && !cm.options.lint) {
// add 'lint' option back to the freshly created section
setTimeout(() => {
if (!cm.options.lint) {
cm.setOption('lint', linterConfig.getForCodeMirror());
}
});
}
const state = cm && cm.state && cm.state.lint || {};
if (delay === 0) {
// immediately show pending csslint/stylelint messages in onbeforeunload and save