2 * Jexer - Java Text User Interface
4 * The MIT License (MIT)
6 * Copyright (C) 2017 Kevin Lamonte
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
26 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
29 package jexer
.teditor
;
31 import java
.util
.ArrayList
;
32 import java
.util
.List
;
34 import jexer
.bits
.CellAttributes
;
37 * A Document represents a text file, as a collection of lines.
39 public class Document
{
44 private ArrayList
<Line
> lines
= new ArrayList
<Line
>();
47 * The current line number being edited. Note that this is 0-based, the
48 * first line is line number 0.
50 private int lineNumber
= 0;
53 * The overwrite flag. When true, characters overwrite data.
55 private boolean overwrite
= false;
58 * The default color for the TEditor class.
60 private CellAttributes defaultColor
= null;
63 * The text highlighter to use.
65 private Highlighter highlighter
= new Highlighter();
68 * Get the overwrite flag.
70 * @return true if addChar() overwrites data, false if it inserts
72 public boolean getOverwrite() {
77 * Set the overwrite flag.
79 * @param overwrite true if addChar() should overwrite data, false if it
82 public void setOverwrite(final boolean overwrite
) {
83 this.overwrite
= overwrite
;
87 * Get the current line number being edited.
89 * @return the line number. Note that this is 0-based: 0 is the first
92 public int getLineNumber() {
97 * Get the current editing line.
101 public Line
getCurrentLine() {
102 return lines
.get(lineNumber
);
106 * Get a specific line by number.
108 * @param lineNumber the line number. Note that this is 0-based: 0 is
112 public Line
getLine(final int lineNumber
) {
113 return lines
.get(lineNumber
);
117 * Set the current line number being edited.
119 * @param n the line number. Note that this is 0-based: 0 is the first
122 public void setLineNumber(final int n
) {
123 if ((n
< 0) || (n
> lines
.size())) {
124 throw new IndexOutOfBoundsException("Lines array size is " +
125 lines
.size() + ", requested index " + n
);
131 * Get the current cursor position of the editing line.
133 * @return the cursor position
135 public int getCursor() {
136 return lines
.get(lineNumber
).getCursor();
140 * Construct a new Document from an existing text string.
142 * @param str the text string
143 * @param defaultColor the color for unhighlighted text
145 public Document(final String str
, final CellAttributes defaultColor
) {
146 this.defaultColor
= defaultColor
;
148 // TODO: set different colors based on file extension
149 highlighter
.setJavaColors();
151 String
[] rawLines
= str
.split("\n");
152 for (int i
= 0; i
< rawLines
.length
; i
++) {
153 lines
.add(new Line(rawLines
[i
], this.defaultColor
, highlighter
));
158 * Increment the line number by one. If at the last line, do nothing.
160 * @return true if the editing line changed
162 public boolean down() {
163 if (lineNumber
< lines
.size() - 1) {
164 int x
= lines
.get(lineNumber
).getCursor();
166 if (x
> lines
.get(lineNumber
).getDisplayLength()) {
167 lines
.get(lineNumber
).end();
169 lines
.get(lineNumber
).setCursor(x
);
177 * Increment the line number by n. If n would go past the last line,
178 * increment only to the last line.
180 * @param n the number of lines to increment by
181 * @return true if the editing line changed
183 public boolean down(final int n
) {
184 if (lineNumber
< lines
.size() - 1) {
185 int x
= lines
.get(lineNumber
).getCursor();
187 if (lineNumber
> lines
.size() - 1) {
188 lineNumber
= lines
.size() - 1;
190 if (x
> lines
.get(lineNumber
).getDisplayLength()) {
191 lines
.get(lineNumber
).end();
193 lines
.get(lineNumber
).setCursor(x
);
201 * Decrement the line number by one. If at the first line, do nothing.
203 * @return true if the editing line changed
205 public boolean up() {
206 if (lineNumber
> 0) {
207 int x
= lines
.get(lineNumber
).getCursor();
209 if (x
> lines
.get(lineNumber
).getDisplayLength()) {
210 lines
.get(lineNumber
).end();
212 lines
.get(lineNumber
).setCursor(x
);
220 * Decrement the line number by n. If n would go past the first line,
221 * decrement only to the first line.
223 * @param n the number of lines to decrement by
224 * @return true if the editing line changed
226 public boolean up(final int n
) {
227 if (lineNumber
> 0) {
228 int x
= lines
.get(lineNumber
).getCursor();
230 if (lineNumber
< 0) {
233 if (x
> lines
.get(lineNumber
).getDisplayLength()) {
234 lines
.get(lineNumber
).end();
236 lines
.get(lineNumber
).setCursor(x
);
244 * Decrement the cursor by one. If at the first column, do nothing.
246 * @return true if the cursor position changed
248 public boolean left() {
249 return lines
.get(lineNumber
).left();
253 * Increment the cursor by one. If at the last column, do nothing.
255 * @return true if the cursor position changed
257 public boolean right() {
258 return lines
.get(lineNumber
).right();
262 * Go to the first column of this line.
264 * @return true if the cursor position changed
266 public boolean home() {
267 return lines
.get(lineNumber
).home();
271 * Go to the last column of this line.
273 * @return true if the cursor position changed
275 public boolean end() {
276 return lines
.get(lineNumber
).end();
280 * Delete the character under the cursor.
283 lines
.get(lineNumber
).del();
287 * Delete the character immediately preceeding the cursor.
289 public void backspace() {
290 lines
.get(lineNumber
).backspace();
294 * Replace or insert a character at the cursor, depending on overwrite
297 * @param ch the character to replace or insert
299 public void addChar(final char ch
) {
301 lines
.get(lineNumber
).replaceChar(ch
);
303 lines
.get(lineNumber
).addChar(ch
);
308 * Get a (shallow) copy of the list of lines.
310 * @return the list of lines
312 public List
<Line
> getLines() {
313 return new ArrayList
<Line
>(lines
);
317 * Get the number of lines.
319 * @return the number of lines
321 public int getLineCount() {
326 * Compute the maximum line length for this document.
328 * @return the number of cells needed to display the longest line
330 public int getLineLengthMax() {
332 for (Line line
: lines
) {
333 if (line
.getDisplayLength() > n
) {
334 n
= line
.getDisplayLength();