Skip to content

Instantly share code, notes, and snippets.

@zhoukekestar
Last active March 6, 2017 03:39
Show Gist options
  • Save zhoukekestar/fc9d70a032a7edd456a50853a2d834fa to your computer and use it in GitHub Desktop.
Save zhoukekestar/fc9d70a032a7edd456a50853a2d834fa to your computer and use it in GitHub Desktop.
ESlint any files (include: pug, jade, html, js, weex file, we, jsx etc) for Atom.
const { BufferedProcess, Point } = require('atom');
const fs = require('fs')
const DEBUG_ESLINT = false;
// execute shell command
const executeCommand = function executeCommand (command, callback) {
command = command.split(' ');
const args = command.slice(1);
command = command[0];
let result = '';
const process = new BufferedProcess({
command,
args,
options: {
},
stdout(output) {
result += output;
},
stderr(output) {
result += output;
},
exit(code) {
if (code === 0) {
callback(null, result)
} else {
callback(code, result)
}
}
})
}
// Get current file's project home
const getProjectHome = function getProjectHome(editor) {
return atom.project.relativizePath(editor.getPath())[0]
}
// show & hide popup message-box
let messageBox = document.createElement('div');
messageBox.classList.add('eslint-gutter-all-hover-message');
document.body.appendChild(messageBox);
const showMessage = function showMessage(e) {
messageBox.innerHTML = `
<b>${e.target.getAttribute('ruleId')}</b> :
${e.target.getAttribute('message')}`;
messageBox.style.left = e.pageX + 'px';
messageBox.style.top = e.pageY + 'px';
messageBox.style.display = 'block';
}
const hideMessage = function hideMessage(e) {
messageBox.style.display = 'none';
}
// mark red point
const ESLINT_GUTTER_NAME = 'eslint-gutter-all';
const markArray = function(arr) {
const editor = atom.workspace.getActiveTextEditor();
let gutter = editor.gutterWithName(ESLINT_GUTTER_NAME);
if (!gutter)
gutter = editor.addGutter({name: ESLINT_GUTTER_NAME, priority: 101});
var markers = editor[ESLINT_GUTTER_NAME] && editor[ESLINT_GUTTER_NAME].markers || [];
for (var i = 0; i < markers.length; i++) {
markers[i].destroy();
}
markers = [];
for (var i = 0; i < arr.length; i++) {
let marker = editor.markBufferPosition(new Point(arr[i].line, 0), {invalidate: 'inside'});
let item = document.createElement('span');
item.classList.add('eslint-gutter-all-message');
item.classList.add('severity-' + arr[i].severity);
item.setAttribute('ruleId', arr[i].ruleId);
item.setAttribute('message', arr[i].message);
item.onmouseover = showMessage;
item.onmouseleave = hideMessage;
gutter.decorateMarker(marker, {type: 'overlay', class: ESLINT_GUTTER_NAME, item: item});
markers.push(marker)
}
editor[ESLINT_GUTTER_NAME] = {
markers: markers
}
}
// should lint or not
// const shouldLint = function shouldLint() {
// const editor = atom.workspace.getActiveTextEditor();
// const path = editor.getPath();
// if (/\.js/.test(path) && /public/.test(path)) {
// // Hide Atom Eslint if needed
// const atomEslint = document.querySelector('.gutter[gutter-name=linter]');
// if (atomEslint) {
// atomEslint.style.display = 'none';
// }
// return true;
// }
// return /\.pug|\.jade|\.html/.test(path);
// }
const isFileExist = function isFileExist(path) {
try {
fs.statSync(path)
} catch (e) {
if (e.code === 'ENOENT'){
return false;
} else {
console.log(e)
return false;
}
}
return true;
}
// get Eslint config
const getESLintConfig = function getESLintConfig() {
const editor = atom.workspace.getActiveTextEditor();
const project = getProjectHome(editor);
const filePath = editor.getPath();
if (!isFileExist(`${project}/node_modules/.bin/eslint`)) {
return false;
}
if (/(\.jade|\.pug|public|\.html)/.test(filePath) && isFileExist(`${project}/html.eslintrc`)) {
return `${project}/html.eslintrc`;
} else if (/\.js/.test(filePath) && isFileExist(`${project}/.eslintrc`)) {
return `${project}/.eslintrc`;
}
return false;
}
const eslintCurrentFile = function (fix) {
const editor = atom.workspace.getActiveTextEditor();
const project = getProjectHome(editor);
const config = getESLintConfig();
if (project && config) {
const command =`${project}/node_modules/.bin/eslint --config ${config} --no-eslintrc --format json ${fix ? '--fix ' : ''}${editor.getPath()}`;
DEBUG_ESLINT && console.log(command)
executeCommand(command, (err, res) => {
try {
res = JSON.parse(res);
markArray(res[0].messages);
} catch (e) {
console.log(res);
}
})
} else {
DEBUG_ESLINT && console.log(`ESLint ignored: ${editor.getPath()}`)
}
}
// init script
module.exports = (atom, window) => {
atom.workspace.observeTextEditors(editor => {
editor.onDidSave(() => {
eslintCurrentFile(false);
});
});
// atom.commands.add('atom-text-editor', 'atom-eslint: eslint', () => {
// eslintCurrentFile(false);
// });
atom.commands.add('atom-text-editor', 'atom-eslint: eslint --fix', () => {
eslintCurrentFile(true);
});
}
// ------------------------------------------------------- CSS ------------------------------------------------------
// insert css style
const insertCSS = function insertCSS() {
const css = `
.custom-decorations .eslint-gutter-all .eslint-gutter-all-message {
width: 8px;
height: 8px !important;
content: '';
border-radius: 50%;
left: 0;
top: -13px;
position: absolute;
}
.custom-decorations .eslint-gutter-all .eslint-gutter-all-message.severity-1 {
background: #ffc20d;
}
.custom-decorations .eslint-gutter-all .eslint-gutter-all-message.severity-2 {
background: #f00;
}
.eslint-gutter-all-hover-message {
position: fixed;
background: rgba(0, 0, 0, 0.78);
z-index: 1999;
padding: 10px;
border-radius: 4px;
color: #fff;
margin-left: 10px;
}
`
const style = document.createElement('style');
style.innerHTML = css;
document.body.appendChild(style);
}
insertCSS();
// ------------------------------------------------------- CSS ------------------------------------------------------
# Atom init script
# You can find it in menu (file).
eslint = require 'C:/Users/Administrator/atom-eslint.js' // Your atom-eslint.js file path
eslint(atom, window);
@zhoukekestar
Copy link
Author

Atom Version: 1.14.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment