--- a/editor.actions/src/org/netbeans/modules/editor/actions/AddCaretAction.java
+++ a/editor.actions/src/org/netbeans/modules/editor/actions/AddCaretAction.java
@@ -115,7 +115,7 @@
}
});
- editorCaret.addCarets(dots);
+ editorCaret.addCarets(dots, null); // TODO handle biases
}
});
}
--- a/editor.lib2/apichanges.xml
+++ a/editor.lib2/apichanges.xml
@@ -107,6 +107,21 @@
+
+ Position.Bias support added to EditorCaret
+
+
+
+
+
+
+ CaretInfo.getDotBias() and CaretInfo.getMarkBias() added together
+ with other methods and parameters for bias manipulation to properly handle bidirectional text.
+
+
+
+
+
EditorUtilities.addCaretUndoableEdit added
--- a/editor.lib2/manifest.mf
+++ a/editor.lib2/manifest.mf
@@ -1,6 +1,6 @@
Manifest-Version: 1.0
OpenIDE-Module: org.netbeans.modules.editor.lib2/1
-OpenIDE-Module-Implementation-Version: 47
+OpenIDE-Module-Implementation-Version: 48
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/editor/lib2/Bundle.properties
OpenIDE-Module-Layer: org/netbeans/modules/editor/lib2/resources/layer.xml
OpenIDE-Module-Needs: org.netbeans.modules.editor.actions
--- a/editor.lib2/nbproject/project.properties
+++ a/editor.lib2/nbproject/project.properties
@@ -43,7 +43,7 @@
is.autoload=true
javac.source=1.7
javac.compilerargs=-Xlint:unchecked
-spec.version.base=2.11.0
+spec.version.base=2.12.0
javadoc.arch=${basedir}/arch.xml
javadoc.apichanges=${basedir}/apichanges.xml
--- a/editor.lib2/src/org/netbeans/api/editor/caret/CaretInfo.java
+++ a/editor.lib2/src/org/netbeans/api/editor/caret/CaretInfo.java
@@ -45,6 +45,7 @@
import java.util.logging.Logger;
import javax.swing.text.Position;
import org.netbeans.api.annotations.common.CheckForNull;
+import org.netbeans.api.annotations.common.NonNull;
/**
* Immutable info about a single caret used in caret API - see {@link EditorCaret}.
@@ -67,15 +68,21 @@
private final CaretItem caretItem;
private final Position dotPos;
+
+ private final Position.Bias dotBias;
private final Position markPos;
+
+ private final Position.Bias markBias;
private final Point magicCaretPosition;
CaretInfo(CaretItem caretItem) {
this.caretItem = caretItem;
this.dotPos = caretItem.getDotPosition();
+ this.dotBias = caretItem.getDotBias();
this.markPos = caretItem.getMarkPosition();
+ this.markBias = caretItem.getMarkBias();
this.magicCaretPosition = caretItem.getMagicCaretPosition();
}
@@ -90,6 +97,20 @@
}
/**
+ * Get a bias of the dot position which is either
+ * {@link Position.Bias.Forward} or {@link Position.Bias.Backward} depending
+ * on whether the caret biases towards the next character or previous one.
+ * The bias is always forward for non bidirectional text.
+ *
+ * @return either forward or backward bias.
+ * @since 2.12
+ */
+ @NonNull
+ public Position.Bias getDotBias() {
+ return dotBias;
+ }
+
+ /**
* Return either the same object like {@link #getDotPosition()} if there's no selection
* or return position denoting the other end of an existing selection (which is either before
* or after the dot position depending of how the selection was created).
@@ -102,6 +123,20 @@
}
/**
+ * Get a bias of the mark position which is either
+ * {@link Position.Bias.Forward} or {@link Position.Bias.Backward} depending
+ * on whether the caret biases towards the next character or previous one.
+ * The bias is always forward for non bidirectional text.
+ *
+ * @return either forward or backward bias.
+ * @since 2.12
+ */
+ @NonNull
+ public Position.Bias getMarkBias() {
+ return markBias;
+ }
+
+ /**
* Fetches the current position of the caret.
*
* @return the position >=0
--- a/editor.lib2/src/org/netbeans/api/editor/caret/CaretItem.java
+++ a/editor.lib2/src/org/netbeans/api/editor/caret/CaretItem.java
@@ -47,6 +47,7 @@
import javax.swing.text.JTextComponent;
import javax.swing.text.Position;
import org.netbeans.api.annotations.common.CheckForNull;
+import org.netbeans.api.annotations.common.NonNull;
/**
* A single caret inside {@link EditorCaret} handled internally by EditorCaret.
@@ -75,8 +76,12 @@
private Position dotPos;
+ private Position.Bias dotBias;
+
private Position markPos;
+ private Position.Bias markBias;
+
private Point magicCaretPosition;
/**
@@ -96,10 +101,12 @@
*/
private int statusBits;
- CaretItem(EditorCaret editorCaret, Position dotPos, Position markPos) {
+ CaretItem(EditorCaret editorCaret, Position dotPos, Position.Bias dotBias, Position markPos, Position.Bias markBias) {
this.editorCaret = editorCaret;
this.dotPos = dotPos;
+ this.dotBias = dotBias;
this.markPos = markPos;
+ this.markBias = markBias;
this.statusBits = UPDATE_CARET_BOUNDS; // Request visual bounds updating automatically
}
@@ -146,6 +153,16 @@
Position getDotPosition() {
return dotPos;
}
+
+ /**
+ * Get the bias of the dot either forward or backward bias.
+ *
+ * @return either forward or backward bias.
+ */
+ @NonNull
+ Position.Bias getDotBias() {
+ return dotBias;
+ }
/**
* Return either the same object like {@link #getDotPosition()} if there's
@@ -161,6 +178,16 @@
return markPos;
}
+ /**
+ * Get the bias of the mark either forward or backward bias.
+ *
+ * @return either forward or backward bias.
+ */
+ @NonNull
+ Position.Bias getMarkBias() {
+ return markBias;
+ }
+
int getDot() {
return (dotPos != null) ? dotPos.getOffset() : 0;
}
--- a/editor.lib2/src/org/netbeans/api/editor/caret/CaretTransaction.java
+++ a/editor.lib2/src/org/netbeans/api/editor/caret/CaretTransaction.java
@@ -562,7 +562,9 @@
}
}
- static CaretItem[] asCaretItems(EditorCaret caret, @NonNull List dotAndSelectionStartPosPairs) {
+ static CaretItem[] asCaretItems(EditorCaret caret, @NonNull List dotAndSelectionStartPosPairs,
+ List dotAndMarkBiases)
+ {
int size = dotAndSelectionStartPosPairs.size();
if ((size & 1) != 0) {
throw new IllegalStateException("Passed list has size=" + size + " which is not an even number.");
@@ -570,9 +572,13 @@
CaretItem[] addedCarets = new CaretItem[size >> 1];
int listIndex = 0;
for (int j = 0; j < addedCarets.length; j++) {
+ Position.Bias dotBias = (dotAndMarkBiases != null) ? dotAndMarkBiases.get(listIndex) : Position.Bias.Forward;
Position dotPos = dotAndSelectionStartPosPairs.get(listIndex++);
+
+ Position.Bias markBias = (dotAndMarkBiases != null) ? dotAndMarkBiases.get(listIndex) : Position.Bias.Forward;
Position selectionStartPos = dotAndSelectionStartPosPairs.get(listIndex++);
- CaretItem caretItem = new CaretItem(caret, dotPos, selectionStartPos);
+
+ CaretItem caretItem = new CaretItem(caret, dotPos, dotBias, selectionStartPos, markBias);
addedCarets[j] = caretItem;
}
return addedCarets;
--- a/editor.lib2/src/org/netbeans/api/editor/caret/EditorCaret.java
+++ a/editor.lib2/src/org/netbeans/api/editor/caret/EditorCaret.java
@@ -401,7 +401,7 @@
public EditorCaret() {
caretItems = new GapList<>();
sortedCaretItems = new GapList<>();
- CaretItem singleCaret = new CaretItem(this, null, null);
+ CaretItem singleCaret = new CaretItem(this, null, Position.Bias.Forward, null, Position.Bias.Forward);
caretItems.add(singleCaret);
sortedCaretItems.add(singleCaret);
@@ -418,6 +418,20 @@
public int getDot() {
return getLastCaret().getDot();
}
+
+ /**
+ * Get a bias of the dot position which is either
+ * {@link Position.Bias.Forward} or {@link Position.Bias.Backward} depending
+ * on whether the caret biases towards the next character or previous one.
+ * The bias is always forward for non bidirectional text document.
+ *
+ * @return either forward or backward bias.
+ * @since 2.12
+ */
+ @NonNull
+ public Position.Bias getDotBias() {
+ return getLastCaret().getDotBias();
+ }
/**
* Get mark offset of the last created caret in the underlying document.
@@ -431,6 +445,20 @@
}
/**
+ * Get a bias of the mark position which is either
+ * {@link Position.Bias.Forward} or {@link Position.Bias.Backward} depending
+ * on whether the caret biases towards the next character or previous one.
+ * The bias is always forward for non bidirectional text document.
+ *
+ * @return either forward or backward bias.
+ * @since 2.12
+ */
+ @NonNull
+ public Position.Bias getMarkBias() {
+ return getLastCaret().getMarkBias();
+ }
+
+ /**
* Get information about all existing carets in the order they were created.
*
* The list always has at least one item. The last caret (last item of the list)
@@ -530,7 +558,7 @@
* @see Caret#setDot(int)
*/
public @Override void setDot(final int offset) {
- setDot(offset, MoveCaretsOrigin.DEFAULT);
+ setDot(offset, Position.Bias.Forward, MoveCaretsOrigin.DEFAULT);
}
/**
@@ -547,11 +575,14 @@
* actions (pg up, pg down, left, right, ...).
*
* @param offset new offset for the caret
+ * @param bias new bias for the caret. Use either {@link Position.Bias.Forward}
+ * or {@link Position.Bias.Backward} depending on whether the caret should bias
+ * towards the next character or previous one. Use forward bias for non-bidirectional text document.
* @param orig specifies the operation which caused the caret to move.
* @see #setDot(int)
* @since 2.10
*/
- public void setDot(final int offset, MoveCaretsOrigin orig) {
+ public void setDot(final int offset, Position.Bias bias, MoveCaretsOrigin orig) {
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("setDot: offset=" + offset); //NOI18N
if (LOG.isLoggable(Level.FINEST)) {
@@ -585,7 +616,7 @@
* @see Caret#moveDot(int)
*/
public @Override void moveDot(final int offset) {
- moveDot(offset, MoveCaretsOrigin.DEFAULT);
+ moveDot(offset, Position.Bias.Forward, MoveCaretsOrigin.DEFAULT);
}
/**
@@ -603,11 +634,14 @@
*
*
* @param offset new offset for the caret
+ * @param bias new bias for the caret. Use either {@link Position.Bias.Forward}
+ * or {@link Position.Bias.Backward} depending on whether the caret should bias
+ * towards the next character or previous one. Use forward bias for non-bidirectional text document.
* @param orig specifies the operation which caused the caret to move.
* @see #moveDot(int)
* @since 2.10
*/
- public void moveDot(final int offset, MoveCaretsOrigin orig) {
+ public void moveDot(final int offset, Position.Bias bias, MoveCaretsOrigin orig) {
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("moveDot: offset=" + offset); //NOI18N
}
@@ -719,18 +753,26 @@
*
*
* @param dotPos position of the newly created caret.
+ * @param dotBias bias of the new caret. Use either {@link Position.Bias.Forward}
+ * or {@link Position.Bias.Backward} depending on whether the caret should bias
+ * towards the next character or previous one. Use forward bias for non-bidirectional text document.
* @param markPos beginning of the selection (the other end is dotPos) or the same position like dotPos for no selection.
* The markPos may have higher offset than dotPos to select in a backward direction.
+ * @param markBias bias of the begining of the selection. Use either {@link Position.Bias.Forward}
+ * or {@link Position.Bias.Backward} depending on whether the caret should bias
+ * towards the next character or previous one. Use forward bias for non-bidirectional text document.
* @return difference between current count of carets and the number of carets when the operation started.
- * Returns Integer.MIN_VALUE if the operation was cancelled due to the caret not being installed in any text component
+ * Returns Integer.MIN_VALUE if the operation was canceled due to the caret not being installed in any text component
* or no document installed in the text component.
*
* Note that adding a new caret to offset where another caret is already located may lead
* or no document installed in the text component.
*/
- public int addCaret(@NonNull Position dotPos, @NonNull Position markPos) {
+ public int addCaret(@NonNull Position dotPos, @NonNull Position.Bias dotBias,
+ @NonNull Position markPos, @NonNull Position.Bias markBias)
+ {
return runTransaction(CaretTransaction.RemoveType.NO_REMOVE, 0,
- new CaretItem[] { new CaretItem(this, dotPos, markPos) }, null);
+ new CaretItem[] { new CaretItem(this, dotPos, dotBias, markPos, markBias) }, null);
}
/**
@@ -758,13 +800,16 @@
* @param dotAndMarkPosPairs list of position pairs consisting of dot position
* and mark position (selection start position) which may be the same position like the dot
* if the particular caret has no selection. The list must have even size.
+ * @param dotAndMarkBiases list of position biases (corresponding to the dot and mark positions
+ * in the previous parameter) or null may be passed if all dotAndMarkPosPairs positions should have a forward bias.
* @return difference between current count of carets and the number of carets when the operation started.
- * Returns Integer.MIN_VALUE if the operation was cancelled due to the caret not being installed in any text component
+ * Returns Integer.MIN_VALUE if the operation was canceled due to the caret not being installed in any text component
* or no document installed in the text component.
+ * @see #addCaret(javax.swing.text.Position, javax.swing.text.Position.Bias, javax.swing.text.Position, javax.swing.text.Position.Bias)
*/
- public int addCarets(@NonNull List dotAndMarkPosPairs) {
+ public int addCarets(@NonNull List dotAndMarkPosPairs, List dotAndMarkBiases) {
return runTransaction(CaretTransaction.RemoveType.NO_REMOVE, 0,
- CaretTransaction.asCaretItems(this, dotAndMarkPosPairs), null);
+ CaretTransaction.asCaretItems(this, dotAndMarkPosPairs, dotAndMarkBiases), null);
}
/**
@@ -776,15 +821,17 @@
* @param dotAndMarkPosPairs list of position pairs consisting of dot position
* and mark position (selection start position) which may be the same position like dot
* if the particular caret has no selection. The list must have even size.
+ * @param dotAndMarkBiases list of position biases (corresponding to the dot and mark positions
+ * in the previous parameter) or null may be passed if all dotAndMarkPosPairs positions should have a forward bias.
* @return difference between current count of carets and the number of carets when the operation started.
* Returns Integer.MIN_VALUE if the operation was cancelled due to the caret not being installed in any text component
* or no document installed in the text component.
*/
- public int replaceCarets(@NonNull List dotAndMarkPosPairs) {
+ public int replaceCarets(@NonNull List dotAndMarkPosPairs, List dotAndMarkBiases) {
if (dotAndMarkPosPairs.isEmpty()) {
throw new IllegalArgumentException("dotAndSelectionStartPosPairs list must not be empty");
}
- CaretItem[] addedItems = CaretTransaction.asCaretItems(this, dotAndMarkPosPairs);
+ CaretItem[] addedItems = CaretTransaction.asCaretItems(this, dotAndMarkPosPairs, dotAndMarkBiases);
return runTransaction(CaretTransaction.RemoveType.REMOVE_ALL_CARETS, 0, addedItems, null);
}
@@ -1784,7 +1831,8 @@
// Set caret to zero position upon document change (DefaultCaret impl does this too)
runTransaction(CaretTransaction.RemoveType.REMOVE_ALL_CARETS, 0,
- new CaretItem[] { new CaretItem(this, newDoc.getStartPosition(), null) }, null);
+ new CaretItem[] { new CaretItem(this, newDoc.getStartPosition(), Position.Bias.Forward,
+ null, Position.Bias.Forward ) }, null);
// Leave caretPos and markPos null => offset==0
prefs = (mimeType != null) ? MimeLookup.getLookup(mimeType).lookup(Preferences.class) : null;
@@ -2576,7 +2624,8 @@
try {
Position pos = doc.createPosition(offset);
runTransaction(CaretTransaction.RemoveType.NO_REMOVE, 0,
- new CaretItem[] { new CaretItem(EditorCaret.this, pos, pos) }, null);
+ new CaretItem[] { new CaretItem(EditorCaret.this, pos, Position.Bias.Forward,
+ pos, Position.Bias.Forward) }, null);
} catch (BadLocationException ex) {
// Do nothing
}
--- a/editor.lib2/src/org/netbeans/modules/editor/lib2/CaretUndoEdit.java
+++ a/editor.lib2/src/org/netbeans/modules/editor/lib2/CaretUndoEdit.java
@@ -66,7 +66,7 @@
final Document doc; // (16=super)+4=20 bytes
/**
- * Offset of the dot to restore and last bit is a marker for undo/redo
+ * Offset of the dot to restore and last bit is a marker for position bias - TODO
*/
private int dotOffset; // 24 bytes
@@ -116,7 +116,7 @@
protected void restoreEditorCaret(EditorCaret caret) throws BadLocationException {
Position dotPos = doc.createPosition(getDotOffset());
- caret.replaceCarets(Arrays.asList(dotPos, dotPos));
+ caret.replaceCarets(Arrays.asList(dotPos, dotPos), null); // TODO handle biases
}
protected void restoreLegacyCaret(Caret caret) {
@@ -177,7 +177,7 @@
splitOffset = extraDotAndMarkOffsets[i++];
}
}
- caret.replaceCarets(dotAndMarkPosPairs);
+ caret.replaceCarets(dotAndMarkPosPairs, null); // TODO handle biases
}
@Override
--- a/editor.search/src/org/netbeans/modules/editor/search/EditorFindSupport.java
+++ a/editor.search/src/org/netbeans/modules/editor/search/EditorFindSupport.java
@@ -451,7 +451,8 @@
if (eCaret instanceof EditorCaret) {
EditorCaret caret = (EditorCaret) eCaret;
try {
- caret.addCaret(c.getDocument().createPosition(end), c.getDocument().createPosition(start));
+ caret.addCaret(c.getDocument().createPosition(end), Position.Bias.Forward,
+ c.getDocument().createPosition(start), Position.Bias.Forward);
} catch (BadLocationException ex) {
Exceptions.printStackTrace(ex);
}
--- a/editor.search/src/org/netbeans/modules/editor/search/SearchBar.java
+++ a/editor.search/src/org/netbeans/modules/editor/search/SearchBar.java
@@ -947,7 +947,7 @@
newCarets.add(startPos);
}
- editorCaret.replaceCarets(newCarets);
+ editorCaret.replaceCarets(newCarets, null); // TODO handle biases
textComponent.requestFocusInWindow();
}
--- a/editor.search/src/org/netbeans/modules/editor/search/actions/AddCaretSelectAllAction.java
+++ a/editor.search/src/org/netbeans/modules/editor/search/actions/AddCaretSelectAllAction.java
@@ -130,7 +130,7 @@
newCarets.add(startPos);
}
- editorCaret.replaceCarets(newCarets);
+ editorCaret.replaceCarets(newCarets, null); // TODO handle biases
}
} catch (BadLocationException ex) {
Exceptions.printStackTrace(ex);