org.crsh.console.Editor Maven / Gradle / Ivy
The newest version!
/*
* Copyright (C) 2012 eXo Platform SAS.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.crsh.console;
import org.crsh.cli.impl.line.LineParser;
import org.crsh.cli.impl.line.MultiLineVisitor;
import org.crsh.text.Style;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
/**
* An editor state machine.
*
* todo:
* - undo
* - optimize operation with an improvement of {@link org.crsh.console.EditorBuffer}
*
* @author Julien Viet
*/
class Editor extends Plugin {
/** . */
final Console console;
/** . */
final EditorBuffer buffer;
/** . */
final MultiLineVisitor visitor;
/** The line parser : updated on enter key. */
final LineParser lineParser;
/** . */
final LinkedList history;
/** . */
private Mode mode;
/** . */
int historyCursor;
/** . */
String historyBuffer;
/** The buffer that holds what we kill. */
final StringBuilder killBuffer;
/** . */
private final ArrayList modeListeners;
Editor(Console console) {
this(console, true);
}
Editor(Console console, boolean echo) {
//
EditorBuffer buffer = new EditorBuffer(echo ? console.driver : NULL);
//
this.console = console;
this.buffer = buffer;
this.visitor = new MultiLineVisitor();
this.lineParser = new LineParser(visitor);
this.history = new LinkedList();
this.historyCursor = -1;
this.historyBuffer = null;
this.killBuffer = new StringBuilder();
this.mode = Mode.EMACS;
this.modeListeners = new ArrayList();
}
Mode getMode() {
return mode;
}
void setMode(Mode mode) {
this.mode = mode;
for (Runnable listener : modeListeners) {
listener.run();
}
}
void addModeListener(Runnable runnable) {
modeListeners.add(runnable);
}
void addToHistory(String line) {
history.addFirst(line);
}
/**
* Returns the right cursor bound depending on the current mode.
*
* @return the current bound
*/
int getCursorBound() {
if (console.getMode() == Mode.EMACS) {
return buffer.getSize();
} else {
return Math.max(0, buffer.getSize() - 1);
}
}
String getKillBuffer() {
return killBuffer.toString();
}
void setKillBuffer(CharSequence s) {
if (s == null) {
throw new NullPointerException("No null buffer content");
}
killBuffer.setLength(0);
killBuffer.append(s);
}
boolean isEmpty() {
return buffer.getSize() == 0 && buffer.getLines().size() == 1;
}
String getCurrentLine() {
return buffer.getLine();
}
int getCurrentPosition() {
return buffer.getCursor();
}
String append(EditorAction action, int[] sequence) {
try {
return action.execute(this, buffer, sequence, true);
}
catch (IOException e) {
AssertionError ae = new AssertionError("Not yet supported");
ae.initCause(e);
throw ae;
}
}
void reset() {
lineParser.reset();
buffer.reset();
historyCursor = -1;
}
// Null impl for echo
private static final ConsoleDriver NULL = new ConsoleDriver() {
@Override public int getWidth() { return 80; }
@Override public int getHeight() { return 40; }
@Override public String getProperty(String name) { return null; }
@Override public boolean takeAlternateBuffer() throws IOException { return false; }
@Override public boolean releaseAlternateBuffer() throws IOException { return false; }
@Override public void flush() throws IOException { }
@Override public void write(CharSequence s) throws IOException { }
@Override public void write(CharSequence s, int start, int end) throws IOException { }
@Override public void write(char c) throws IOException { }
@Override public void write(Style d) throws IOException { }
@Override public void writeDel() throws IOException { }
@Override public void writeCRLF() throws IOException { }
@Override public void cls() throws IOException { }
@Override public boolean moveRight(char c) throws IOException { return true; }
@Override public boolean moveLeft() throws IOException { return true; }
@Override public void close() throws IOException { }
};
}