| 1 | export class SlashCommandParserError extends Error { |
| 2 | /**@type {String}*/ text; |
| 3 | /**@type {Number}*/ index; |
| 4 | |
| 5 | get line() { |
| 6 | return this.text.slice(0, this.index).replace(/[^\n]/g, '').length; |
| 7 | } |
| 8 | get column() { |
| 9 | return this.text.slice(0, this.index).split('\n').pop().length; |
| 10 | } |
| 11 | get hint() { |
| 12 | let lineOffset = this.line.toString().length; |
| 13 | let lineStart = this.index; |
| 14 | let start = this.index; |
| 15 | let end = this.index; |
| 16 | let offset = 0; |
| 17 | let lineCount = 0; |
| 18 | while (offset < 10000 && lineCount < 3 && start >= 0) { |
| 19 | if (this.text[start] == '\n') lineCount++; |
| 20 | if (lineCount == 0) lineStart--; |
| 21 | offset++; |
| 22 | start--; |
| 23 | } |
| 24 | if (this.text[start + 1] == '\n') start++; |
| 25 | offset = 0; |
| 26 | while (offset < 10000 && this.text[end] != '\n') { |
| 27 | offset++; |
| 28 | end++; |
| 29 | } |
| 30 | let hint = []; |
| 31 | let lines = this.text.slice(start + 1, end - 1).split('\n'); |
| 32 | let lineNum = this.line - lines.length + 1; |
| 33 | let tabOffset = 0; |
| 34 | for (const line of lines) { |
| 35 | const num = `${' '.repeat(lineOffset - lineNum.toString().length)}${lineNum}`; |
| 36 | lineNum++; |
| 37 | const untabbedLine = line.replace(/\t/g, ' '.repeat(4)); |
| 38 | tabOffset = untabbedLine.length - line.length; |
| 39 | hint.push(`${num}: ${untabbedLine}`); |
| 40 | } |
| 41 | hint.push(`${' '.repeat(this.index - lineStart + lineOffset + 1 + tabOffset)}^^^^^`); |
| 42 | return hint.join('\n'); |
| 43 | } |
| 44 | |
| 45 | constructor(message, text, index) { |
| 46 | super(message); |
| 47 | this.text = text; |
| 48 | this.index = index; |
| 49 | } |
| 50 | } |