improvements for multi-caret implementation of column mode (IDEA-80056)
[idea/community.git] / platform / editor-ui-api / src / com / intellij / openapi / editor / Caret.java
1 /*
2  * Copyright 2000-2014 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.openapi.editor;
17
18 import com.intellij.openapi.Disposable;
19 import com.intellij.openapi.util.UserDataHolderEx;
20 import org.jetbrains.annotations.NotNull;
21 import org.jetbrains.annotations.Nullable;
22
23 /**
24  * Represents a specific caret instance in the editor when it support multiple carets (see {@link CaretModel#supportsMultipleCarets()}.
25  * Provides methods to query and modify caret position and caret's associated selection.
26  */
27 public interface Caret extends UserDataHolderEx, Disposable {
28   /**
29    * Returns an instance of CaretModel, current caret is associated with.
30    */
31   @NotNull
32   CaretModel getCaretModel();
33
34   /**
35    * Tells whether this caret is valid, i.e. recognized by the caret model currently. Caret is valid since its creation till its
36    * removal from caret model.
37    *
38    * @see com.intellij.openapi.editor.CaretModel#addCaret(VisualPosition)
39    * @see com.intellij.openapi.editor.CaretModel#removeCaret(Caret)
40    */
41   boolean isValid();
42
43   /**
44    * Moves the caret by the specified number of lines and/or columns.
45    *
46    * @param columnShift    the number of columns to move the caret by.
47    * @param lineShift      the number of lines to move the caret by.
48    * @param withSelection  if true, the caret move should extend the selection in the document.
49    * @param scrollToCaret  if true, the document should be scrolled so that the caret is visible after the move.
50    */
51   void moveCaretRelatively(int columnShift,
52                            int lineShift,
53                            boolean withSelection,
54                            boolean scrollToCaret);
55
56   /**
57    * Moves the caret to the specified logical position.
58    * If corresponding position is in the folded region currently, the region will be expanded.
59    *
60    * @param pos the position to move to.
61    */
62   void moveToLogicalPosition(@NotNull LogicalPosition pos);
63
64   /**
65    * Moves the caret to the specified visual position.
66    *
67    * @param pos the position to move to.
68    */
69   void moveToVisualPosition(@NotNull VisualPosition pos);
70
71   /**
72    * Short hand for calling {@link #moveToOffset(int, boolean)} with <code>'false'</code> as a second argument.
73    *
74    * @param offset      the offset to move to
75    */
76   void moveToOffset(int offset);
77
78   /**
79    * Moves the caret to the specified offset in the document.
80    * If corresponding position is in the folded region currently, the region will be expanded.
81    *
82    * @param offset                  the offset to move to.
83    * @param locateBeforeSoftWrap    there is a possible case that there is a soft wrap at the given offset, hence, the same offset
84    *                                corresponds to two different visual positions - just before soft wrap and just after soft wrap.
85    *                                We may want to clearly indicate where to put the caret then. Given parameter allows to do that.
86    *                                <b>Note:</b> it's ignored if there is no soft wrap at the given offset
87    */
88   void moveToOffset(int offset, boolean locateBeforeSoftWrap);
89
90   /**
91    * Caret position may be updated on document change (e.g. consider that user updates from VCS that causes addition of text
92    * before caret. Caret offset, visual and logical positions should be updated then). So, there is a possible case
93    * that caret model in in the process of caret position update now.
94    * <p/>
95    * Current method allows to check that.
96    *
97    * @return    <code>true</code> if caret position is up-to-date for now; <code>false</code> otherwise
98    */
99   boolean isUpToDate();
100
101   /**
102    * Returns the logical position of the caret.
103    *
104    * @return the caret position.
105    */
106   @NotNull
107   LogicalPosition getLogicalPosition();
108
109   /**
110    * Returns the visual position of the caret.
111    *
112    * @return the caret position.
113    */
114   @NotNull
115   VisualPosition getVisualPosition();
116
117   /**
118    * Returns the offset of the caret in the document.
119    *
120    * @return the caret offset.
121    */
122   int getOffset();
123
124   /**
125    * @return    document offset for the start of the logical line where caret is located
126    */
127   int getVisualLineStart();
128
129   /**
130    * @return    document offset that points to the first symbol shown at the next visual line after the one with caret on it
131    */
132   int getVisualLineEnd();
133
134   /**
135    * Returns the start offset in the document of the selected text range, or the caret
136    * position if there is currently no selection.
137    *
138    * @return the selection start offset.
139    */
140   int getSelectionStart();
141
142   /**
143    * @return    object that encapsulates information about visual position of selected text start if any
144    */
145   @NotNull
146   VisualPosition getSelectionStartPosition();
147
148   /**
149    * Returns the end offset in the document of the selected text range, or the caret
150    * position if there is currently no selection.
151    *
152    * @return the selection end offset.
153    */
154   int getSelectionEnd();
155
156   /**
157    * @return    object that encapsulates information about visual position of selected text end if any;
158    */
159   @NotNull
160   VisualPosition getSelectionEndPosition();
161
162   /**
163    * Returns the text selected in the editor.
164    *
165    * @return the selected text, or null if there is currently no selection.
166    */
167   @Nullable
168   String getSelectedText();
169
170   /**
171    * Returns the offset from which the user started to extend the selection (the selection start
172    * if the selection was extended in forward direction, or the selection end if it was
173    * extended backward).
174    *
175    * @return the offset from which the selection was started, or the caret offset if there is
176    *         currently no selection.
177    */
178   int getLeadSelectionOffset();
179
180   /**
181    * @return    object that encapsulates information about visual position from which the user started to extend the selection if any
182    */
183   @NotNull
184   VisualPosition getLeadSelectionPosition();
185
186   /**
187    * Checks if a range of text is currently selected.
188    *
189    * @return true if a range of text is selected, false otherwise.
190    */
191   boolean hasSelection();
192
193   /**
194    * Selects the specified range of text.
195    *
196    * @param startOffset the start offset of the text range to select.
197    * @param endOffset   the end offset of the text range to select.
198    */
199   void setSelection(int startOffset, int endOffset);
200
201   /**
202    * Selects target range providing information about visual boundary of selection end.
203    * <p/>
204    * That is the case for soft wraps-aware processing where the whole soft wraps virtual space is matched to the same offset.
205    * <p/>
206    * Also, in column mode this method allows to create selection spanning virtual space after the line end.
207    *
208    * @param startOffset     start selection offset
209    * @param endPosition     end visual position of the text range to select (<code>null</code> argument means that
210    *                        no specific visual position should be used)
211    * @param endOffset       end selection offset
212    */
213   void setSelection(int startOffset, @Nullable VisualPosition endPosition, int endOffset);
214
215   /**
216    * Selects target range based on its visual boundaries.
217    * <p/>
218    * That is the case for soft wraps-aware processing where the whole soft wraps virtual space is matched to the same offset.
219    * <p/>
220    * Also, in column mode this method allows to create selection spanning virtual space after the line end.
221    *
222    * @param startPosition   start visual position of the text range to select (<code>null</code> argument means that
223    *                        no specific visual position should be used)
224    * @param endPosition     end visual position of the text range to select (<code>null</code> argument means that
225    *                        no specific visual position should be used)
226    * @param startOffset     start selection offset
227    * @param endOffset       end selection offset
228    */
229   void setSelection(@Nullable VisualPosition startPosition, int startOffset, @Nullable VisualPosition endPosition, int endOffset);
230
231   /**
232    * Removes the selection in the editor.
233    */
234   void removeSelection();
235
236   /**
237    * Selects the entire line of text at the caret position.
238    */
239   void selectLineAtCaret();
240
241   /**
242    * Selects the entire word at the caret position, optionally using camel-case rules to
243    * determine word boundaries.
244    *
245    * @param honorCamelWordsSettings if true and "Use CamelHumps words" is enabled,
246    *                                upper-case letters within the word are considered as
247    *                                boundaries for the range of text to select.
248    */
249   void selectWordAtCaret(boolean honorCamelWordsSettings);
250
251   /**
252    * Clones the current caret and positions the new one right above or below the current one. If current caret has selection, corresponding
253    * selection will be set for the new caret.
254    *
255    * @param above if <code>true</code>, new caret will be created at the previous line, if <code>false</code> - on the next line
256    * @return newly created caret instance, or <code>null</code> if the caret cannot be created because it already exists at the new location
257    * or caret model doesn't support multiple carets.
258    */
259   @Nullable
260   Caret clone(boolean above);
261 }