eclipse-langium/langium

The AbstractFormatter.avoidOverlappingEdits does not filter properly overlapping edits

Closed this issue · 0 comments

Discussed in #1624

Originally posted by ydaveluy August 13, 2024
Hello,

I have some formatting issues with my dsl.

Before calling AbstractFormatter.avoidOverlappingEdits I have the following edits:

  newText:'', start:'1:1', end:'1:1'
  newText:' ', start:'1:10', end:'1:11'
  newText:'', start:'2:1', end:'2:2'
  newText:'', start:'3:1', end:'3:1'
  newText:'', start:'2:1', end:'2:2'
  newText:'', start:'3:1', end:'3:1'

and after:

  newText:'', start:'1:1', end:'1:1'
  newText:' ', start:'1:10', end:'1:11'
  newText:'', start:'2:1', end:'2:2'
  newText:'', start:'2:1', end:'2:2'
  newText:'', start:'3:1', end:'3:1'

The newText:'', start:'2:1', end:'2:2' edit is duplicated which prevent from formatting the whole file.

As a workaround I overrode the avoidOverlappingEdits method:

    protected override avoidOverlappingEdits(textDocument: TextDocument, textEdits: TextEdit[]): TextEdit[] {
        const edits: TextEdit[] = [];
        for (const edit of textEdits) {
            let last = edits[edits.length - 1];
            while (last) {
                const currentStart = textDocument.offsetAt(edit.range.start);
                const lastEnd = textDocument.offsetAt(last.range.end);
                if (currentStart < lastEnd) {
                    edits.pop();
                    last = edits[edits.length - 1];
                }
                else {
                    break;
                }
            }
            edits.push(edit);
        }
        return edits;
    }

Is it an issue in AbstractFormatter.avoidOverlappingEdits or somewhere else ?