private boolean computeDiffAndRenderOnEditor()

in plugin/src/software/aws/toolkits/eclipse/amazonq/inlineChat/InlineChatDiffManager.java [95:189]


    private boolean computeDiffAndRenderOnEditor(final String newCode) throws Exception {

        // Annotation model provides highlighting for the diff additions/deletions
        IAnnotationModel annotationModel = task.getEditor().getDocumentProvider().getAnnotationModel(task.getEditor().getEditorInput());
        var document = task.getEditor().getDocumentProvider().getDocument(task.getEditor().getEditorInput());

        // Clear existing diff annotations prior to starting new diff
        clearDiffAnnotations(annotationModel);

        // Split original and new code into lines for diff comparison
        String[] originalLines = (task.hasActiveSelection()) ? task.getOriginalCode().lines().toArray(String[]::new) : new String[0];
        String[] newLines = newCode.lines().toArray(String[]::new);

        // Diff generation --> returns Patch object which contains deltas for each line
        Patch<String> patch = DiffUtils.diff(Arrays.asList(originalLines), Arrays.asList(newLines));

        StringBuilder resultText = new StringBuilder();
        currentDiffs.clear(); // Clear previous diffs
        int currentPos = 0;
        int currentLine = 0;
        int deletedLines = 0;
        int insertedLines = 0;

        for (AbstractDelta<String> delta : patch.getDeltas()) {

            // Count deletion and addition lines for telemetry
            if (delta.getType() == DeltaType.DELETE || delta.getType() == DeltaType.CHANGE) {
                deletedLines += delta.getSource().getLines().size();
            }
            if (delta.getType() == DeltaType.INSERT || delta.getType() == DeltaType.CHANGE) {
                insertedLines += delta.getTarget().getLines().size();
            }

            // Continuously copy unchanged lines until we hit a diff
            while (currentLine < delta.getSource().getPosition()) {
                resultText.append(originalLines[currentLine]).append("\n");
                currentPos += originalLines[currentLine].length() + 1;
                currentLine++;
            }

            List<String> originalChangedLines = delta.getSource().getLines();
            List<String> newChangedLines = delta.getTarget().getLines();

            // Handle deleted lines and mark position
            for (String line : originalChangedLines) {
                resultText.append(line).append("\n");
                currentDiffs.add(new TextDiff(task.getSelectionOffset() + currentPos, line.length(), true));
                currentPos += line.length() + 1;
            }

            // Handle added lines and mark position
            for (String line : newChangedLines) {
                resultText.append(line).append("\n");
                currentDiffs.add(new TextDiff(task.getSelectionOffset() + currentPos, line.length(), false));
                currentPos += line.length() + 1;
            }

            currentLine = delta.getSource().getPosition() + delta.getSource().size();
        }
        // Loop through remaining unchanged lines
        while (currentLine < originalLines.length) {
            resultText.append(originalLines[currentLine]).append("\n");
            currentPos += originalLines[currentLine].length() + 1;
            currentLine++;
        }

        var originalEndsInNewLine = task.getOriginalCode().endsWith("\n");
        var diffEndsInNewLine = resultText.length() > 0 && resultText.charAt(resultText.length() - 1) == '\n';

        if (!originalEndsInNewLine && diffEndsInNewLine) {
            resultText.setLength(resultText.length() - 1);
        }
        final String finalText = resultText.toString();

        // Clear existing annotations in the affected range
        clearAnnotationsInRange(annotationModel, task.getSelectionOffset(), task.getSelectionOffset() + task.getOriginalCode().length());

        // Apply new diff text
        document.replace(task.getSelectionOffset(), task.getPreviousDisplayLength(), finalText);

        // Add all annotations after text modifications are complete
        for (TextDiff diff : currentDiffs) {
            Position position = new Position(diff.offset(), diff.length());
            String annotationType = diff.isDeletion() ? annotationDeleted : annotationAdded;
            String annotationText = diff.isDeletion() ? "Deleted Code" : "Added Code";
            annotationModel.addAnnotation(new Annotation(annotationType, false, annotationText), position);
        }

        // Store rendered text length for proper clearing next iteration
        task.setPreviousDisplayLength(finalText.length());
        task.setPreviousPartialResponse(newCode);
        task.setNumDeletedLines(deletedLines);
        task.setNumAddedLines(insertedLines);
        return true;
    }