@Override
    public void setHighlights(final List<TextRange> highlights) {
        Scheduler.get().scheduleDeferred(() -> {
            if (highlights != null && highlights.size() > 0) {
                // Find our first from location
                final Location minLocation = highlights.stream()
                        .map(TextRange::getFrom)
                        .min(Location::compareTo)
                        .orElse(DefaultLocation.beginning());

                final List<Marker> markers = highlights.stream()
                        .map(highlightStr -> {
                            // Location is all one based and exclusive, AceRange is a mix
                            return AceRange.create(
                                    highlightStr.getFrom().getLineNo() - firstLineNumber,
                                    highlightStr.getFrom().getColNo() - 1, // zero-based & inclusive
                                    highlightStr.getTo().getLineNo() - firstLineNumber,
                                    highlightStr.getTo().getColNo()); // zero-based & exclusive so no need to change
                        })
                        .map(aceRange ->
                                new Marker(aceRange, "hl", AceMarkerType.TEXT, false))
                        .collect(Collectors.toList());

                editor.setMarkers(markers);
                // Move the cursor location so the highlight is in view.  Line and col as we
                // could be dealing with single line data with the highlight at col 500 for example.
                editor.gotoLocation(
                        minLocation.getLineNo() - firstLineNumber + 1,
                        minLocation.getColNo());
            } else {
                editor.setMarkers(null);
            }
        });
    }
This is a widget that can be used to edit text. It provides useful
functionality such as formatting, styling, line numbers and warning/error
markers.
stroom-core-client-widget/src/main/java/stroom/editor/client/view/EditorViewImpl.java