void (final int masterIndex, int[] startLines, int[] endLines, final boolean animate, boolean forceSyncVerticalScroll) { final List<? extends Editor> editors = getEditors(); final List<? extends ScrollHelper> helpers = getScrollHelpers(); final int count = editors.size(); assert startLines.length == count; assert endLines.length == count; final int[] offsets = getTargetOffsets(editors.toArray(Editor.EMPTY_ARRAY), startLines, endLines, -1); final int[] startOffsets = new int[count]; for (int i = 0; i < count; i++) { startOffsets[i] = editors.get(i).getScrollingModel().getVisibleArea().y; } final Editor masterEditor = editors.get(masterIndex); final int masterOffset = offsets[masterIndex]; final int masterStartOffset = startOffsets[masterIndex]; if (forceSyncVerticalScroll) { doScrollVertically(masterEditor, masterOffset, true); return; } for (ScrollHelper helper : helpers) { helper.setAnchor(startOffsets[helper.getMasterIndex()], offsets[helper.getMasterIndex()], startOffsets[helper.getSlaveIndex()], offsets[helper.getSlaveIndex()]); } doScrollHorizontally(masterEditor, 0, false); // animation will be canceled by "scroll vertically" anyway doScrollVertically(masterEditor, masterOffset, animate); masterEditor.getScrollingModel().runActionOnScrollingFinished(() -> { for (ScrollHelper helper : helpers) { helper.removeAnchor(); } int masterFinalOffset = masterEditor.getScrollingModel().getVisibleArea().y; boolean animateSlaves = animate && masterFinalOffset == masterStartOffset; for (int i = 0; i < count; i++) { if (i == masterIndex) continue; Editor editor = editors.get(i); int finalOffset = editor.getScrollingModel().getVisibleArea().y; if (finalOffset != offsets[i]) { enterDisableScrollSection(); doScrollVertically(editor, offsets[i], animateSlaves); editor.getScrollingModel().runActionOnScrollingFinished(this::exitDisableScrollSection); } } }); }