recognize USO-variables /*[[foo]]*/ and provide autocomplete hints
This commit is contained in:
parent
3152a7ebfe
commit
80547aef70
|
@ -31,3 +31,6 @@
|
||||||
.CodeMirror-search-hint {
|
.CodeMirror-search-hint {
|
||||||
color: #888;
|
color: #888;
|
||||||
}
|
}
|
||||||
|
.cm-uso-variable {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global CodeMirror prefs loadScript */
|
/* global CodeMirror prefs loadScript editor */
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
@ -132,3 +132,65 @@
|
||||||
return isBlank;
|
return isBlank;
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
(() => {
|
||||||
|
const USO_VAR = 'uso-variable';
|
||||||
|
const USO_VALID_VAR = 'variable-3 ' + USO_VAR;
|
||||||
|
const USO_INVALID_VAR = 'error ' + USO_VAR;
|
||||||
|
|
||||||
|
CodeMirror.registerHelper('hint', 'css', function (cm) {
|
||||||
|
const {line, ch} = cm.getCursor();
|
||||||
|
const {styles, text} = cm.getLineHandle(line);
|
||||||
|
if (!styles || !editor) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let prev = 0;
|
||||||
|
for (let i = 1; i < styles.length; i += 2) {
|
||||||
|
let end = styles[i];
|
||||||
|
if (prev <= ch && ch <= end &&
|
||||||
|
(styles[i + 1] || '').includes(USO_VAR)) {
|
||||||
|
const adjust = text[prev] === '/' ? 4 : 0;
|
||||||
|
prev += adjust;
|
||||||
|
end -= adjust;
|
||||||
|
const leftPart = text.slice(prev, ch);
|
||||||
|
const list = Object.keys(editor.getStyle().usercssData.vars)
|
||||||
|
.filter(name => name.startsWith(leftPart));
|
||||||
|
console.log(leftPart, ...list);
|
||||||
|
return {
|
||||||
|
list,
|
||||||
|
from: {line, ch: prev},
|
||||||
|
to: {line, ch: end},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
prev = end;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const hooks = CodeMirror.mimeModes['text/css'].tokenHooks;
|
||||||
|
const originalCommentHook = hooks['/'];
|
||||||
|
hooks['/'] = tokenizeUsoVariables;
|
||||||
|
|
||||||
|
function tokenizeUsoVariables(stream) {
|
||||||
|
const token = originalCommentHook.apply(this, arguments);
|
||||||
|
if (token[1] !== 'comment') {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
const {string, start, pos} = stream;
|
||||||
|
// /*[[install-key]]*/
|
||||||
|
// 01234 43210
|
||||||
|
if (string[start + 2] === '[' &&
|
||||||
|
string[start + 3] === '[' &&
|
||||||
|
string[pos - 3] === ']' &&
|
||||||
|
string[pos - 4] === ']') {
|
||||||
|
if (editor &&
|
||||||
|
Object.hasOwnProperty.call(
|
||||||
|
editor.getStyle().usercssData.vars,
|
||||||
|
string.slice(start + 4, pos - 4))) {
|
||||||
|
token[0] = USO_VALID_VAR;
|
||||||
|
} else {
|
||||||
|
token[0] = USO_INVALID_VAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
|
@ -1,16 +1,38 @@
|
||||||
/* global CodeMirror CSSLint stylelint linterConfig */
|
/* global CodeMirror CSSLint parserlib stylelint linterConfig */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
CodeMirror.registerHelper('lint', 'csslint', code =>
|
CodeMirror.registerHelper('lint', 'csslint', code => {
|
||||||
CSSLint.verify(code, deepCopy(linterConfig.getCurrent('csslint')))
|
if (!CSSLint.suppressUsoVarError) {
|
||||||
.messages.map(message => ({
|
CSSLint.suppressUsoVarError = true;
|
||||||
from: CodeMirror.Pos(message.line - 1, message.col - 1),
|
parserlib.css.Tokens[parserlib.css.Tokens.COMMENT].hide = false;
|
||||||
to: CodeMirror.Pos(message.line - 1, message.col),
|
const isUsoVar = ({value}) => value.startsWith('/*[[') && value.endsWith(']]*/');
|
||||||
message: message.message,
|
CSSLint.addRule({
|
||||||
rule: message.rule.id,
|
id: 'uso-vars',
|
||||||
severity : message.type
|
init(parser, reporter) {
|
||||||
}))
|
parser.addListener('error', function ({message, line, col}) {
|
||||||
);
|
if (!isUsoVar(this._tokenStream._token)) {
|
||||||
|
const {_lt, _ltIndex: i} = this._tokenStream;
|
||||||
|
if (i < 2 || !_lt.slice(0, i - 1).reverse().some(isUsoVar)) {
|
||||||
|
reporter.error(message, line, col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const rules = deepCopy(linterConfig.getCurrent('csslint'));
|
||||||
|
Object.defineProperty(rules, 'errors', {get: () => 0, set: () => 0});
|
||||||
|
rules['uso-vars'] = 1;
|
||||||
|
return CSSLint.verify(code, rules).messages
|
||||||
|
.map(({line, col, message, rule, type}) => line && {
|
||||||
|
message,
|
||||||
|
from: {line: line - 1, ch: col - 1},
|
||||||
|
to: {line: line - 1, ch: col},
|
||||||
|
rule: rule.id,
|
||||||
|
severity: type
|
||||||
|
})
|
||||||
|
.filter(Boolean);
|
||||||
|
});
|
||||||
|
|
||||||
CodeMirror.registerHelper('lint', 'stylelint', code =>
|
CodeMirror.registerHelper('lint', 'stylelint', code =>
|
||||||
stylelint.lint({
|
stylelint.lint({
|
||||||
|
|
Loading…
Reference in New Issue
Block a user