message: feat(ruff): include endLine and endColumn in diagnostics
  Fixes
diff: @@ -3,18 +3,31 @@ import { CancellationToken, OutputChannel, TextDocument, Uri, workspace } from '
  import { ILinterInfo, ILintMessage, LintMessageSeverity } from '../../types';
  import { BaseLinter } from './baseLinter';
  -const REGEX = '(?<file>.*.py):(?<line>\\d+):(?<column>\\d+): (?<code>[\\w-]+) (?<message>.*)\\r?(\\n|$)';
  const COLUMN_OFF_SET = 1;
  +interface IRuffLocation {
  + row: number;
  + column: number;
  +}
  +
  +interface IRuffLintMessage {
  + kind: string | { [key: string]: any[] };
  + code: string;
  + message: string;
  + location: IRuffLocation;
  + end_location: IRuffLocation;
  + filename: string;
  +}
  +
  export class Ruff extends BaseLinter {
  constructor(info: ILinterInfo, outputChannel: OutputChannel) {
  super(info, outputChannel, COLUMN_OFF_SET);
  }
  - protected async runLinter(document: TextDocument, cancellation: CancellationToken): Promise<ILintMessage[]> {
  + protected async runLinter(document: TextDocument, _cancellation: CancellationToken): Promise<ILintMessage[]> {
  if (!this.info.isEnabled(Uri.parse(document.uri))) return [];
  - const args = [...this.info.linterArgs(), Uri.parse(document.uri).fsPath];
  + const args = [...this.info.linterArgs(), '--format=json', Uri.parse(document.uri).fsPath];
  const bin = this.info.pathName();
  try {
  @@ -28,9 +41,19 @@ export class Ruff extends BaseLinter {
  this.outputChannel.append(result.stdout);
  this.outputChannel.appendLine('');
  - const messages = await super.parseMessages(result.stdout, document, cancellation, REGEX);
  - messages.forEach((msg) => {
  - msg.severity = LintMessageSeverity.Warning;
  + const messages: ILintMessage[] = JSON.parse(result.stdout).map((msg: IRuffLintMessage) => {
  + return {
  + line: msg.location.row,
  + column: msg.location.column - COLUMN_OFF_SET,
  + endLine: msg.end_location.row,
  + endColumn: msg.end_location.column,
  + code: msg.code,
  + message: msg.message,
  + type: '',
  + severity: LintMessageSeverity.Warning, // https://github.com/charliermarsh/ruff/issues/645
  + provider: this.info.id,
  + file: msg.filename,
  + };
  });
  return messages;
  