diff --git a/cli.js b/cli.js index 5deb3f2..41d5215 100755 --- a/cli.js +++ b/cli.js @@ -18,6 +18,7 @@ const argv = require('yargs') }).argv; const glob = require('globby').sync; const read = require('read-input'); +const chalk = require('chalk'); const ejsLint = require('./index.js'); const opts = { @@ -33,6 +34,7 @@ read(glob(argv._)) errored = true; let message = `${err.message} (${err.line}:${err.column})`; if (file.name) message += ` in ${file.name}`; + message += `\n${errorContext(err, file)}`; console.error(message); } }); @@ -42,3 +44,24 @@ read(glob(argv._)) console.error(err); process.exit(1); }); + +function errorContext(err, file) { + const lines = file.data.split(/\r?\n/); + const lineText = lines[err.line - 1]; + const before = lineText.substr(0, err.column - 1); + const duringText = lineText.substr(err.column - 1, 1); + const during = chalk.bgRed(duringText); + const after = lineText.substr(err.column); + const caret = '^'; + const lineBreak = '\n'; + const caretLine = addSpaces(err.column - 1) + caret; + return before + during + after + lineBreak + caretLine; +} + +function addSpaces(n) { + let str = ''; + for (let i = 0; i < n; i++) { + str += ' '; + } + return str; +} diff --git a/package.json b/package.json index cb83c13..42b1d3f 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "unit": "nyc --check-coverage mocha --ui tdd --check-leaks" }, "dependencies": { + "chalk": "^4.0.0", "ejs": "3.0.1", "ejs-include-regex": "^1.0.0", "globby": "^11.0.0", diff --git a/test/cli.js b/test/cli.js index 1996e15..ff85970 100644 --- a/test/cli.js +++ b/test/cli.js @@ -15,10 +15,11 @@ suite('cli', () => { }); test('invalid input', (done) => { execFile(ejslint, ['test/fixtures/invalid.ejs'], (err, stdout, stderr) => { + const expectedContext = `\n<% ] %>\n ^`; assert.equal(err.code, 1, 'expected exit code of 1'); assert.equal( stderr.trim(), - 'Unexpected token (3:4) in test/fixtures/invalid.ejs', + `Unexpected token (3:4) in test/fixtures/invalid.ejs${expectedContext}`, ); done(); });