void (final @NotNull List<? extends CaretState> caretStates, final boolean updateSystemSelection) { if (caretStates.isEmpty()) { throw new IllegalArgumentException("At least one caret should exist"); } int maxCaretCount = getMaxCaretCount(); List<? extends CaretState> states; if (caretStates.size() <= maxCaretCount) { states = caretStates; } else { states = caretStates.subList(0, maxCaretCount); EditorUtil.notifyMaxCarets(myEditor); } doWithCaretMerging(() -> { int index = 0; int oldCaretCount = myCarets.size(); Iterator<CaretImpl> caretIterator = myCarets.iterator(); IntCollection selectionStartsBefore = null; IntCollection selectionStartsAfter = null; IntCollection selectionEndsBefore = null; IntCollection selectionEndsAfter = null; for (CaretState caretState : states) { CaretImpl caret; if (index++ < oldCaretCount) { caret = caretIterator.next(); if (caretState != null && caretState.getCaretPosition() != null) { caret.moveToLogicalPosition(caretState.getCaretPosition()); } } else { caret = new CaretImpl(myEditor, this); if (caretState != null && caretState.getCaretPosition() != null) { caret.moveToLogicalPosition(caretState.getCaretPosition(), false, null, false, false); } synchronized (myCarets) { myCarets.add(caret); myPrimaryCaret = caret; } fireCaretAdded(caret); } if (caretState != null && caretState.getCaretPosition() != null && caretState.getVisualColumnAdjustment() != 0) { caret.myVisualColumnAdjustment = caretState.getVisualColumnAdjustment(); caret.updateVisualPosition(); } if (caretState != null && caretState.getSelectionStart() != null && caretState.getSelectionEnd() != null) { if (selectionStartsBefore == null) { int capacity = states.size(); selectionStartsBefore = new IntArrayList(capacity); selectionStartsAfter = new IntArrayList(capacity); selectionEndsBefore = new IntArrayList(capacity); selectionEndsAfter = new IntArrayList(capacity); } selectionStartsBefore.add(caret.getSelectionStart()); selectionEndsBefore.add(caret.getSelectionEnd()); caret.doSetSelection(myEditor.logicalToVisualPosition(caretState.getSelectionStart()), myEditor.logicalPositionToOffset(caretState.getSelectionStart()), myEditor.logicalToVisualPosition(caretState.getSelectionEnd()), myEditor.logicalPositionToOffset(caretState.getSelectionEnd()), true, false, false); selectionStartsAfter.add(caret.getSelectionStart()); selectionEndsAfter.add(caret.getSelectionEnd()); } } int caretsToRemove = myCarets.size() - states.size(); for (int i = 0; i < caretsToRemove; i++) { CaretImpl caret; synchronized (myCarets) { caret = myCarets.removeLast(); myPrimaryCaret = myCarets.getLast(); } fireCaretRemoved(caret); Disposer.dispose(caret); } if (updateSystemSelection) { updateSystemSelection(); } if (selectionStartsBefore != null) { SelectionEvent event = new SelectionEvent(myEditor, selectionStartsBefore.toIntArray(), selectionEndsBefore.toIntArray(), selectionStartsAfter.toIntArray(), selectionEndsAfter.toIntArray()); myEditor.getSelectionModel().fireSelectionChanged(event); } }); }