Skip to content

Error message always shows last 5 lines of buffer #183

Description

@drbild

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.

Activity

drbild commented on Dec 19, 2022

@drbild
Author

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?

tjvr commented on Jan 8, 2023

@tjvr
Collaborator

Oh dear! That's definitely not expected.

We might have to revert that PR 😞

oguimbal commented on May 16, 2023

@oguimbal

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
}
added a commit that references this issue on May 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions