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); $('.code-label', sectionDiv).insertAdjacentElement('afterend', wrapper);
}, { }, {
value: code, value: code,
lint: null,
}); });
const wrapper = cm.display.wrapper; const wrapper = cm.display.wrapper;

View File

@ -1,26 +1,43 @@
/* global CodeMirror linterConfig */ /* global CodeMirror linterConfig */
'use strict'; 'use strict';
CodeMirror.registerHelper('lint', 'csslint', code => (() => {
linterConfig.invokeWorker({code, config: linterConfig.getCurrent()}).then(results => CodeMirror.registerHelper('lint', 'csslint', invokeHelper);
results.map(({line, col: ch, message, rule, type: severity}) => line && { CodeMirror.registerHelper('lint', 'stylelint', invokeHelper);
message,
from: {line: line - 1, ch: ch - 1},
to: {line: line - 1, ch},
rule: rule.id,
severity,
}).filter(Boolean)));
CodeMirror.registerHelper('lint', 'stylelint', code => const cookResults = {
linterConfig.invokeWorker({code, config: linterConfig.getCurrent()}).then(({results}) => csslint: results =>
!results[0] && [] || results.map(({line, col: ch, message, rule, type: severity}) => line && {
results[0].warnings.map(({line, column:ch, text, severity}) => ({ message,
from: {line: line - 1, ch: ch - 1}, from: {line: line - 1, ch: ch - 1},
to: {line: line - 1, ch}, to: {line: line - 1, ch},
message: text rule: rule.id,
.replace('Unexpected ', '') severity,
.replace(/^./, firstLetter => firstLetter.toUpperCase()) }).filter(Boolean),
.replace(/\s*\([^(]+\)$/, ''), // strip the rule,
rule: text.replace(/^.*?\s*\(([^(]+)\)$/, '$1'), stylelint: ({results}) =>
severity, !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] ? { return CodeMirror.lint && CodeMirror.lint[linter] ? {
getAnnotations: CodeMirror.lint[linter], getAnnotations: CodeMirror.lint[linter],
delay: prefs.get('editor.lintDelay'), delay: prefs.get('editor.lintDelay'),
preUpdateLinting(cm) {
cm.startOperation();
},
onUpdateLinting(annotationsNotSorted, annotations, cm) { onUpdateLinting(annotationsNotSorted, annotations, cm) {
cm.endOperation();
updateLintReport(cm, 0); updateLintReport(cm, 0);
}, },
} : false; } : false;
@ -198,7 +202,9 @@ function updateLinter({immediately, linter = linterConfig.getName()} = {}) {
CodeMirror.defaults.lint = linterConfig.getForCodeMirror(linter); CodeMirror.defaults.lint = linterConfig.getForCodeMirror(linter);
const guttersOption = prepareGuttersOption(); const guttersOption = prepareGuttersOption();
editors.forEach(cm => { editors.forEach(cm => {
cm.setOption('lint', CodeMirror.defaults.lint); if (cm.options.lint !== CodeMirror.defaults.lint) {
cm.setOption('lint', CodeMirror.defaults.lint);
}
if (guttersOption) { if (guttersOption) {
cm.setOption('guttersOption', guttersOption); cm.setOption('guttersOption', guttersOption);
updateGutters(cm, guttersOption); updateGutters(cm, guttersOption);
@ -235,14 +241,6 @@ function updateLinter({immediately, linter = linterConfig.getName()} = {}) {
} }
function updateLintReport(cm, delay) { 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 || {}; const state = cm && cm.state && cm.state.lint || {};
if (delay === 0) { if (delay === 0) {
// immediately show pending csslint/stylelint messages in onbeforeunload and save // immediately show pending csslint/stylelint messages in onbeforeunload and save