Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/maddyhome/idea/vim/helper/EditorHelper.java


1   package com.maddyhome.idea.vim.helper;
2   
3   /*
4    * IdeaVim - A Vim emulator plugin for IntelliJ Idea
5    * Copyright (C) 2003 Rick Maddy
6    *
7    * This program is free software; you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation; either version 2
10   * of the License, or (at your option) any later version.
11   *
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Public License for more details.
16   *
17   * You should have received a copy of the GNU General Public License
18   * along with this program; if not, write to the Free Software
19   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20   */
21  
22  import com.intellij.openapi.editor.Editor;
23  import com.intellij.openapi.editor.LogicalPosition;
24  import com.intellij.openapi.editor.VisualPosition;
25  import com.intellij.openapi.fileEditor.FileEditor;
26  import com.intellij.openapi.fileEditor.FileEditorManager;
27  import com.intellij.openapi.fileEditor.TextEditor;
28  import com.intellij.openapi.vfs.VirtualFile;
29  import com.maddyhome.idea.vim.common.CharacterPosition;
30  import java.awt.Point;
31  import java.awt.Rectangle;
32  import java.nio.CharBuffer;
33  
34  /**
35   * This is a set of helper methods for working with editors. All line and column values are zero based.
36   */
37  public class EditorHelper
38  {
39      /**
40       * Gets the visual line number the cursor is on
41       * @param editor The editor
42       * @return The cursor's visual line number
43       */
44      public static int getCurrentVisualLine(Editor editor)
45      {
46          return editor.getCaretModel().getVisualPosition().line;
47      }
48  
49      /**
50       * Gets the visual column number the cursor is on
51       * @param editor The editor
52       * @return The cursor's visual column number
53       */
54      public static int getCurrentVisualColumn(Editor editor)
55      {
56          return editor.getCaretModel().getVisualPosition().column;
57      }
58  
59      /**
60       * Gets the logical line number the cursor is on
61       * @param editor The editor
62       * @return The cursor's logical line number
63       */
64      public static int getCurrentLogicalLine(Editor editor)
65      {
66          return editor.getCaretModel().getLogicalPosition().line;
67      }
68  
69      /**
70       * Gets the logical column number the cursor is on
71       * @param editor The editor
72       * @return The cursor's logical column number
73       */
74      public static int getCurrentLogicalColumn(Editor editor)
75      {
76          return editor.getCaretModel().getLogicalPosition().column;
77      }
78  
79      /**
80       * Gets the number of characters on the current line. This will be different than the number of visual
81       * characters if there are "real" tabs in the line.
82       * @param editor The editor
83       * @return The number of characters in the current line
84       */
85      public static int getLineLength(Editor editor)
86      {
87          int lline = getCurrentLogicalLine(editor);
88  
89          return getLineLength(editor, lline);
90      }
91  
92      /**
93       * Gets the number of characters on the specified logical line. This will be different than the number of visual
94       * characters if there are "real" tabs in the line.
95       * @param editor The editor
96       * @param lline The logical line within the file
97       * @return The number of characters in the specified line
98       */
99      public static int getLineLength(Editor editor, int lline)
100     {
101         return Math.max(0, editor.offsetToLogicalPosition(editor.getDocument().getLineEndOffset(lline)).column);
102     }
103 
104     /**
105      * Gets the number of characters on the specified visual line. This will be different than the number of visual
106      * characters if there are "real" tabs in the line.
107      * @param editor The editor
108      * @param vline The visual line within the file
109      * @return The number of characters in the specified line
110      */
111     public static int getVisualLineLength(Editor editor, int vline)
112     {
113         int lline = visualLineToLogicalLine(editor, vline);
114         return getLineLength(editor, lline);
115     }
116 
117     /**
118      * Gets the number of visible lines in the editor. This will less then the actual number of lines in the file
119      * if there are any collapsed folds.
120      * @param editor The editor
121      * @return The number of visible lines in the file
122      */
123     public static int getVisualLineCount(Editor editor)
124     {
125         int count = getLineCount(editor);
126         return count == 0 ? 0 : logicalLineToVisualLine(editor, count - 1) + 1;
127     }
128 
129     /**
130      * Gets the number of actual lines in the file
131      * @param editor The editor
132      * @return The file line count
133      */
134     public static int getLineCount(Editor editor)
135     {
136         int len = editor.getDocument().getLineCount();
137         if (editor.getDocument().getTextLength() > 0 &&
138             editor.getDocument().getChars()[editor.getDocument().getTextLength() - 1] == '\n')
139         {
140             len--;
141         }
142 
143         return len;
144     }
145 
146     /**
147      * Gets the actual number of characters in the file
148      * @param editor The editor
149      * @return The file's character count
150      */
151     public static int getFileSize(Editor editor)
152     {
153         int len = editor.getDocument().getTextLength();
154         if (len >= 1 && editor.getDocument().getChars()[len - 1] == '\n')
155         {
156             len--;
157         }
158 
159         return len;
160     }
161 
162     /**
163      * Gets the number of lines than can be displayed on the screen at one time. This is rounded down to the
164      * nearest whole line if there is a parial line visible at the bottom of the screen.
165      * @param editor The editor
166      * @return The number of screen lines
167      */
168     public static int getScreenHeight(Editor editor)
169     {
170         return editor.getScrollingModel().getVisibleArea().height / editor.getLineHeight();
171     }
172 
173     /**
174      * Gets the number of characters that are visible on a screen line
175      * @param editor The editor
176      * @return The number of screen columns
177      */
178     public static int getScreenWidth(Editor editor)
179     {
180         Rectangle rect = editor.getScrollingModel().getVisibleArea();
181         Point pt = new Point(rect.width, 0);
182         VisualPosition vp = editor.xyToVisualPosition(pt);
183 
184         return vp.column;
185     }
186 
187     /**
188      * Converts a visual line number to a logical line number.
189      * @param editor The editor
190      * @param vline The visual line number to convert
191      * @return The logical line number
192      */
193     public static int visualLineToLogicalLine(Editor editor, int vline)
194     {
195         return editor.visualToLogicalPosition(new VisualPosition(vline, 0)).line;
196     }
197 
198     /**
199      * Converts a logical line number to a visual line number. Several logical lines can map to the same
200      * visual line when there are collapsed fold regions.
201      * @param editor The editor
202      * @param lline The logical line number to convert
203      * @return The visual line number
204      */
205     public static int logicalLineToVisualLine(Editor editor, int lline)
206     {
207         return editor.logicalToVisualPosition(new LogicalPosition(lline, 0)).line;
208     }
209 
210     /**
211      * Returns the offset of the start of the requested line.
212      * @param editor The editor
213      * @param lline The logical line to get the start offset for.
214      * @return 0 if line is &lt 0, file size of line is bigger than file, else the start offset for the line
215      */
216     public static int getLineStartOffset(Editor editor, int lline)
217     {
218         if (lline < 0)
219         {
220             return 0;
221         }
222         else if (lline >= getLineCount(editor))
223         {
224             return getFileSize(editor);
225         }
226         else
227         {
228             return editor.getDocument().getLineStartOffset(lline);
229         }
230     }
231 
232     /**
233      * Returns the offset of the end of the requested line.
234      * @param editor The editor
235      * @param lline The logical line to get the end offset for.
236      * @return 0 if line is &lt 0, file size of line is bigger than file, else the end offset for the line
237      */
238     public static int getLineEndOffset(Editor editor, int lline, boolean incEnd)
239     {
240         if (lline < 0)
241         {
242             return 0;
243         }
244         else if (lline >= getLineCount(editor))
245         {
246             return getFileSize(editor);
247         }
248         else
249         {
250             return editor.getDocument().getLineEndOffset(lline) - (incEnd ? 0 : 1);
251         }
252     }
253 
254     /**
255      * Ensures that the supplied visual line is within the range 0 (incl) and the number of visual lines in the file
256      * (excl).
257      * @param editor The editor
258      * @param vline The visual line number to normalize
259      * @return The normalized visual line number
260      */
261     public static int normalizeVisualLine(Editor editor, int vline)
262     {
263         vline = Math.min(Math.max(0, vline), getVisualLineCount(editor) - 1);
264 
265         return vline;
266     }
267 
268     /**
269      * Ensures that the supplied logical line is within the range 0 (incl) and the number of logical lines in the file
270      * (excl).
271      * @param editor The editor
272      * @param lline The logical line number to normalize
273      * @return The normalized logical line number
274      */
275     public static int normalizeLine(Editor editor, int lline)
276     {
277         lline = Math.max(0, Math.min(lline, getLineCount(editor) - 1));
278 
279         return lline;
280     }
281 
282     /**
283      * Ensures that the supplied column number for the given visual line is within the range 0 (incl) and the
284      * number of columns in the line (excl).
285      * @param editor The editor
286      * @param vline The visual line number
287      * @param col The column number to normalize
288      * @return The normalized column number
289      */
290     public static int normalizeVisualColumn(Editor editor, int vline, int col)
291     {
292         col = Math.min(Math.max(0, col), getVisualLineLength(editor, vline) - 1);
293 
294         return col;
295     }
296 
297     /**
298      * Ensures that the supplied column number for the given logical line is within the range 0 (incl) and the
299      * number of columns in the line (excl).
300      * @param editor The editor
301      * @param lline The logical line number
302      * @param col The column number to normalize
303      * @return The normalized column number
304      */
305     public static int normalizeColumn(Editor editor, int lline, int col)
306     {
307         col = Math.min(Math.max(0, getLineLength(editor, lline) - 1), col);
308 
309         return col;
310     }
311 
312     /**
313      * Ensures that the supplied offset for the given logical line is within the range for the line. If allowEnd
314      * is true, the range will allow for the offset to be one past the last character on the line.
315      * @param editor The editor
316      * @param lline The logical line number
317      * @param offset The offset to normalize
318      * @param allowEnd true if the offset can be one past the last character on the line, false if not
319      * @return The normalized column number
320      */
321     public static int normalizeOffset(Editor editor, int lline, int offset, boolean allowEnd)
322     {
323         if (getFileSize(editor) == 0)
324         {
325             return 0;
326         }
327 
328         int min = getLineStartOffset(editor, lline);
329         int max = getLineEndOffset(editor, lline, allowEnd);;
330         offset = Math.max(Math.min(offset, max), min);
331 
332         return offset;
333     }
334 
335     public static int normalizeOffset(Editor editor, int offset, boolean allowEnd)
336     {
337         int lline = editor.offsetToLogicalPosition(offset).line;
338         
339         return normalizeOffset(editor, lline, offset, allowEnd);
340     }
341 
342     /**
343      * Gets the editor for the virtual file within the editor mananger.
344      * @param manager The file editor manager
345      * @param file The virtual file get the editor for
346      * @return The matching editor or null if no match was found
347      */
348     public static Editor getEditor(FileEditorManager manager, VirtualFile file)
349     {
350         FileEditor[] editors = manager.getEditors(file);
351         if (editors.length > 0 && editors[0] instanceof TextEditor)
352         {
353             return ((TextEditor)editors[0]).getEditor();
354         }
355 
356         return null;
357     }
358 
359     /**
360      * Converts a visual position to a file offset
361      * @param editor The editor
362      * @param pos The visual position to convert
363      * @return The file offset of the visual position
364      */
365     public static int visualPostionToOffset(Editor editor, VisualPosition pos)
366     {
367         return editor.logicalPositionToOffset(editor.visualToLogicalPosition(pos));
368     }
369 
370     /**
371      * Gets a string representation of the file for the supplied offset range
372      * @param editor The editor
373      * @param start The starting offset (inclusive)
374      * @param end The ending offset (exclusive)
375      * @return The string, never null but empty if start == end
376      */
377     public static String getText(Editor editor, int start, int end)
378     {
379         return new String(editor.getDocument().getChars(), start, end - start);
380     }
381 
382     /**
383      * Gets the offset of the start of the line containing the supplied offset
384      * @param editor The editor
385      * @param offset The offset within the line
386      * @return The offset of the line start
387      */
388     public static int getLineStartForOffset(Editor editor, int offset)
389     {
390         LogicalPosition pos = editor.offsetToLogicalPosition(offset);
391         return editor.getDocument().getLineStartOffset(pos.line);
392     }
393 
394     /**
395      * Gets the offset of the end of the line containing the supplied offset
396      * @param editor The editor
397      * @param offset The offset within the line
398      * @return The offset of the line end
399      */
400     public static int getLineEndForOffset(Editor editor, int offset)
401     {
402         LogicalPosition pos = editor.offsetToLogicalPosition(offset);
403         return editor.getDocument().getLineEndOffset(pos.line);
404     }
405 
406     public static int getLineCharCount(Editor editor, int lline)
407     {
408         return getLineEndOffset(editor, lline, true) - getLineStartOffset(editor, lline);
409     }
410 
411     /**
412      * Returns the text of the requested logical line
413      * @param editor The editor
414      * @param lline The logical line to get the text for
415      * @return The requested line
416      */
417     public static String getLineText(Editor editor, int lline)
418     {
419         return getText(editor, getLineStartOffset(editor, lline), getLineEndOffset(editor, lline, true));
420     }
421 
422     public static CharacterPosition offsetToCharacterPosition(Editor editor, int offset)
423     {
424         int line = editor.getDocument().getLineNumber(offset);
425         int col = offset - editor.getDocument().getLineStartOffset(line);
426 
427         return new CharacterPosition(line, col);
428     }
429 
430     public static int characterPositionToOffset(Editor editor, CharacterPosition pos)
431     {
432         return editor.getDocument().getLineStartOffset(pos.line) + pos.column;
433     }
434 
435     public static CharBuffer getLineBuffer(Editor editor, int lline)
436     {
437         return CharBuffer.wrap(editor.getDocument().getChars(), getLineStartOffset(editor, lline),
438             getLineCharCount(editor, lline));
439     }
440 }