X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2Fteditor%2FDocument.java;h=2abfef6635f3c1877fc733ee36ea8c67d01160b6;hb=12b90437b5f22c2ae6e9b9b14c3b62b60f6143e5;hp=c84c20787e6453e987db5fcec7f01911b356e959;hpb=fe0770f988e64fc0ccafd3d3b086b4a0eb559d3b;p=nikiroo-utils.git diff --git a/src/jexer/teditor/Document.java b/src/jexer/teditor/Document.java index c84c207..2abfef6 100644 --- a/src/jexer/teditor/Document.java +++ b/src/jexer/teditor/Document.java @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (C) 2017 Kevin Lamonte + * Copyright (C) 2019 Kevin Lamonte * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -41,6 +41,10 @@ import jexer.bits.CellAttributes; */ public class Document { + // ------------------------------------------------------------------------ + // Variables -------------------------------------------------------------- + // ------------------------------------------------------------------------ + /** * The list of lines. */ @@ -72,6 +76,32 @@ public class Document { */ private Highlighter highlighter = new Highlighter(); + // ------------------------------------------------------------------------ + // Constructors ----------------------------------------------------------- + // ------------------------------------------------------------------------ + + /** + * Construct a new Document from an existing text string. + * + * @param str the text string + * @param defaultColor the color for unhighlighted text + */ + public Document(final String str, final CellAttributes defaultColor) { + this.defaultColor = defaultColor; + + // TODO: set different colors based on file extension + highlighter.setJavaColors(); + + String [] rawLines = str.split("\n"); + for (int i = 0; i < rawLines.length; i++) { + lines.add(new Line(rawLines[i], this.defaultColor, highlighter)); + } + } + + // ------------------------------------------------------------------------ + // Document --------------------------------------------------------------- + // ------------------------------------------------------------------------ + /** * Get the overwrite flag. * @@ -180,29 +210,24 @@ public class Document { } /** - * Set the current cursor position of the editing line. 0-based. + * Get the character at the current cursor position in the text. * - * @param cursor the new cursor position + * @return the character, or -1 if the cursor is at the end of the line */ - public void setCursor(final int cursor) { - lines.get(lineNumber).setCursor(cursor); + public int getChar() { + return lines.get(lineNumber).getChar(); } /** - * Construct a new Document from an existing text string. + * Set the current cursor position of the editing line. 0-based. * - * @param str the text string - * @param defaultColor the color for unhighlighted text + * @param cursor the new cursor position */ - public Document(final String str, final CellAttributes defaultColor) { - this.defaultColor = defaultColor; - - // TODO: set different colors based on file extension - highlighter.setJavaColors(); - - String [] rawLines = str.split("\n"); - for (int i = 0; i < rawLines.length; i++) { - lines.add(new Line(rawLines[i], this.defaultColor, highlighter)); + public void setCursor(final int cursor) { + if (cursor >= lines.get(lineNumber).getDisplayLength()) { + lines.get(lineNumber).end(); + } else { + lines.get(lineNumber).setCursor(cursor); } } @@ -215,7 +240,7 @@ public class Document { if (lineNumber < lines.size() - 1) { int x = lines.get(lineNumber).getCursor(); lineNumber++; - if (x > lines.get(lineNumber).getDisplayLength()) { + if (x >= lines.get(lineNumber).getDisplayLength()) { lines.get(lineNumber).end(); } else { lines.get(lineNumber).setCursor(x); @@ -239,7 +264,7 @@ public class Document { if (lineNumber > lines.size() - 1) { lineNumber = lines.size() - 1; } - if (x > lines.get(lineNumber).getDisplayLength()) { + if (x >= lines.get(lineNumber).getDisplayLength()) { lines.get(lineNumber).end(); } else { lines.get(lineNumber).setCursor(x); @@ -258,7 +283,7 @@ public class Document { if (lineNumber > 0) { int x = lines.get(lineNumber).getCursor(); lineNumber--; - if (x > lines.get(lineNumber).getDisplayLength()) { + if (x >= lines.get(lineNumber).getDisplayLength()) { lines.get(lineNumber).end(); } else { lines.get(lineNumber).setCursor(x); @@ -282,7 +307,7 @@ public class Document { if (lineNumber < 0) { lineNumber = 0; } - if (x > lines.get(lineNumber).getDisplayLength()) { + if (x >= lines.get(lineNumber).getDisplayLength()) { lines.get(lineNumber).end(); } else { lines.get(lineNumber).setCursor(x); @@ -293,7 +318,8 @@ public class Document { } /** - * Decrement the cursor by one. If at the first column, do nothing. + * Decrement the cursor by one. If at the first column on the first + * line, do nothing. * * @return true if the cursor position changed */ @@ -310,7 +336,8 @@ public class Document { } /** - * Increment the cursor by one. If at the last column, do nothing. + * Increment the cursor by one. If at the last column on the last line, + * do nothing. * * @return true if the cursor position changed */ @@ -326,6 +353,151 @@ public class Document { return true; } + /** + * Go back to the beginning of this word if in the middle, or the + * beginning of the previous word. + */ + public void backwardsWord() { + + // If at the beginning of a word already, push past it. + if ((getChar() != -1) + && (getRawLine().length() > 0) + && !Character.isSpace((char) getChar()) + ) { + left(); + } + + // int line = lineNumber; + while ((getChar() == -1) + || (getRawLine().length() == 0) + || Character.isSpace((char) getChar()) + ) { + if (left() == false) { + return; + } + } + + + assert (getChar() != -1); + + if (!Character.isSpace((char) getChar()) + && (getRawLine().length() > 0) + ) { + // Advance until at the beginning of the document or a whitespace + // is encountered. + while (!Character.isSpace((char) getChar())) { + int line = lineNumber; + if (left() == false) { + // End of document, bail out. + return; + } + if (lineNumber != line) { + // We wrapped a line. Here that counts as whitespace. + right(); + return; + } + } + } + + // We went one past the word, push back to the first character of + // that word. + right(); + return; + } + + /** + * Go to the beginning of the next word. + */ + public void forwardsWord() { + int line = lineNumber; + while ((getChar() == -1) + || (getRawLine().length() == 0) + ) { + if (right() == false) { + return; + } + if (lineNumber != line) { + // We wrapped a line. Here that counts as whitespace. + if (!Character.isSpace((char) getChar())) { + // We found a character immediately after the line. + // Done! + return; + } + // Still looking... + line = lineNumber; + } + } + assert (getChar() != -1); + + if (!Character.isSpace((char) getChar()) + && (getRawLine().length() > 0) + ) { + // Advance until at the end of the document or a whitespace is + // encountered. + while (!Character.isSpace((char) getChar())) { + line = lineNumber; + if (right() == false) { + // End of document, bail out. + return; + } + if (lineNumber != line) { + // We wrapped a line. Here that counts as whitespace. + if (!Character.isSpace((char) getChar()) + && (getRawLine().length() > 0) + ) { + // We found a character immediately after the line. + // Done! + return; + } + break; + } + } + } + + while ((getChar() == -1) + || (getRawLine().length() == 0) + ) { + if (right() == false) { + return; + } + if (lineNumber != line) { + // We wrapped a line. Here that counts as whitespace. + if (!Character.isSpace((char) getChar())) { + // We found a character immediately after the line. + // Done! + return; + } + // Still looking... + line = lineNumber; + } + } + assert (getChar() != -1); + + if (Character.isSpace((char) getChar())) { + // Advance until at the end of the document or a non-whitespace + // is encountered. + while (Character.isSpace((char) getChar())) { + if (right() == false) { + // End of document, bail out. + return; + } + } + return; + } + + // We wrapped the line to get here. + return; + } + + /** + * Get the raw string that matches this line. + * + * @return the string + */ + public String getRawLine() { + return lines.get(lineNumber).getRawString(); + } + /** * Go to the first column of this line. * @@ -397,7 +569,7 @@ public class Document { */ public void enter() { dirty = true; - int cursor = lines.get(lineNumber).getCursor(); + int cursor = lines.get(lineNumber).getRawCursor(); String original = lines.get(lineNumber).getRawString(); String firstLine = original.substring(0, cursor); String secondLine = original.substring(cursor); @@ -414,7 +586,7 @@ public class Document { * * @param ch the character to replace or insert */ - public void addChar(final char ch) { + public void addChar(final int ch) { dirty = true; if (overwrite) { lines.get(lineNumber).replaceChar(ch);