moo
moo copied to clipboard
Error message always shows last 5 lines of buffer
Error messages seem to always show the last 5 lines of the buffer, even when the error occurs earlier in the buffer.
This line seems to always grab the last N lines from buffer, not considering the actual position of the error within the buffer.
CC @airportyh Looks like the lastNLines changes were from your PR that merged in May. Perhaps I'm misunderstanding how that is supposed to work?
Oh dear! That's definitely not expected.
We might have to revert that PR :disappointed:
For those interested, here is a workaround (which could work as a fix, btw):
myLexer.formatError = function (token, message) {
if (token == null) {
// An undefined token indicates EOF
var text = this.buffer.slice(this.index)
token = {
value: '',
text: text,
offset: this.index,
lineBreaks: text.indexOf('\n') === -1 ? 0 : 1,
line: this.line,
col: this.col,
}
}
const numLinesAround = 2
const firstDisplayedLine = Math.max(token.line - numLinesAround, 1)
const lastDisplayedLine = token.line + numLinesAround
const lastLineDigits = String(lastDisplayedLine).length
const displayedLines = nLines(
this.buffer,
firstDisplayedLine,
lastDisplayedLine,
)
.slice(0, 5)
const errorLines = []
errorLines.push(message + " at line " + token.line + " col " + token.col + ":")
errorLines.push("")
for (let i = 0; i < displayedLines.length; i++) {
var line = displayedLines[i]
var lineNo = firstDisplayedLine + i
errorLines.push(pad(String(lineNo), lastLineDigits) + " " + line);
if (lineNo === token.line) {
errorLines.push(pad("", lastLineDigits + token.col + 1) + "^")
}
}
return errorLines.join("\n")
}
function nLines(string, from, to) {
const reg = new RegExp(`^([^\\n]*\\n){${from - 1}}(([^\\n]*\\n){${to - from}})`);
const res = reg.exec(string);
return res?.[2]?.split('\n') ?? [];
}
function pad(s, length) {
if (s.length > length) {
return s
}
return Array(length - s.length + 1).join(" ") + s
}