mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-09 18:56:02 +02:00
Bug 458402 - [terminal] Add support for scroll up/down and scroll region
Change-Id: If3c955663f664d34d01ada0763de2eec7b36b7d4 Signed-off-by: Anton Leherbauer <anton.leherbauer@windriver.com>
This commit is contained in:
parent
7ff9715a55
commit
53c5808e00
5 changed files with 257 additions and 12 deletions
|
@ -10,6 +10,7 @@
|
|||
* Martin Oberhuber (Wind River) - [168197] Fix Terminal for CDC-1.1/Foundation-1.1
|
||||
* Anton Leherbauer (Wind River) - [453393] Add support for copying wrapped lines without line break
|
||||
* Anton Leherbauer (Wind River) - [458218] Add support for ANSI insert mode
|
||||
* Anton Leherbauer (Wind River) - [458402] Add support for scroll up/down and scroll region
|
||||
*******************************************************************************/
|
||||
package org.eclipse.tm.internal.terminal.emulator;
|
||||
|
||||
|
@ -1307,4 +1308,74 @@ public class VT100EmulatorBackendTest extends TestCase {
|
|||
assertEquals("abc123", new String(term.getChars(0)));
|
||||
}
|
||||
|
||||
public void testScrollRegion() {
|
||||
ITerminalTextData term=makeITerminalTextData();
|
||||
IVT100EmulatorBackend vt100=makeBakend(term);
|
||||
term.setMaxHeight(10);
|
||||
vt100.setDimensions(8, 6);
|
||||
vt100.appendString("123");
|
||||
vt100.setCursorColumn(0);
|
||||
vt100.processNewline();
|
||||
vt100.appendString("456");
|
||||
vt100.setCursorColumn(0);
|
||||
vt100.processNewline();
|
||||
vt100.appendString("789");
|
||||
vt100.setCursorColumn(0);
|
||||
vt100.processNewline();
|
||||
vt100.appendString("abc");
|
||||
vt100.setCursorColumn(0);
|
||||
vt100.processNewline();
|
||||
vt100.appendString("def");
|
||||
vt100.setCursorColumn(0);
|
||||
vt100.processNewline();
|
||||
vt100.appendString("ghi");
|
||||
|
||||
// test scroll within region
|
||||
vt100.setCursorLine(1);
|
||||
vt100.setScrollRegion(1, 4);
|
||||
vt100.scrollUp(1);
|
||||
assertEquals("123", new String(term.getChars(0)));
|
||||
assertEquals("789", new String(term.getChars(1)));
|
||||
assertEquals("abc", new String(term.getChars(2)));
|
||||
assertEquals("def", new String(term.getChars(3)));
|
||||
assertNull(term.getChars(4));
|
||||
assertEquals("ghi", new String(term.getChars(5)));
|
||||
vt100.scrollDown(1);
|
||||
assertEquals("123", new String(term.getChars(0)));
|
||||
assertNull(term.getChars(1));
|
||||
assertEquals("789", new String(term.getChars(2)));
|
||||
assertEquals("abc", new String(term.getChars(3)));
|
||||
assertEquals("def", new String(term.getChars(4)));
|
||||
assertEquals("ghi", new String(term.getChars(5)));
|
||||
|
||||
// test scroll without region
|
||||
vt100.setScrollRegion(-1, -1);
|
||||
vt100.scrollDown(1);
|
||||
assertNull(term.getChars(0));
|
||||
assertEquals("123", new String(term.getChars(1)));
|
||||
assertNull(term.getChars(2));
|
||||
assertEquals("789", new String(term.getChars(3)));
|
||||
assertEquals("abc", new String(term.getChars(4)));
|
||||
assertEquals("def", new String(term.getChars(5)));
|
||||
assertEquals("ghi", new String(term.getChars(6)));
|
||||
vt100.scrollUp(1);
|
||||
assertEquals("123", new String(term.getChars(0)));
|
||||
assertNull(term.getChars(1));
|
||||
assertEquals("789", new String(term.getChars(2)));
|
||||
assertEquals("abc", new String(term.getChars(3)));
|
||||
assertEquals("def", new String(term.getChars(4)));
|
||||
assertEquals("ghi", new String(term.getChars(5)));
|
||||
|
||||
// test scroll by newline
|
||||
vt100.setScrollRegion(1, 4);
|
||||
vt100.setCursorLine(4);
|
||||
vt100.processNewline();
|
||||
assertEquals("123", new String(term.getChars(0)));
|
||||
assertEquals("789", new String(term.getChars(1)));
|
||||
assertEquals("abc", new String(term.getChars(2)));
|
||||
assertEquals("def", new String(term.getChars(3)));
|
||||
assertNull(term.getChars(4));
|
||||
assertEquals("ghi", new String(term.getChars(5)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,13 +9,13 @@
|
|||
* Michael Scharf (Wind River) - initial API and implementation
|
||||
* Anton Leherbauer (Wind River) - [433751] Add option to enable VT100 line wrapping mode
|
||||
* Anton Leherbauer (Wind River) - [458218] Add support for ANSI insert mode
|
||||
* Anton Leherbauer (Wind River) - [458402] Add support for scroll up/down and scroll region
|
||||
*******************************************************************************/
|
||||
package org.eclipse.tm.internal.terminal.emulator;
|
||||
|
||||
import org.eclipse.tm.terminal.model.Style;
|
||||
|
||||
/**
|
||||
* @author toni
|
||||
*
|
||||
*/
|
||||
public interface IVT100EmulatorBackend {
|
||||
|
@ -197,4 +197,26 @@ public interface IVT100EmulatorBackend {
|
|||
* @param enable whether to enable insert mode
|
||||
*/
|
||||
void setInsertMode(boolean enable);
|
||||
|
||||
/**
|
||||
* Set scrolling region. Negative values reset the scroll region.
|
||||
*
|
||||
* @param top top line of scroll region
|
||||
* @param bottom bottom line of scroll region
|
||||
*/
|
||||
void setScrollRegion(int top, int bottom);
|
||||
|
||||
/**
|
||||
* Scroll text upwards.
|
||||
*
|
||||
* @param lines number of lines to scroll
|
||||
*/
|
||||
void scrollUp(int lines);
|
||||
|
||||
/**
|
||||
* Scroll text downwards.
|
||||
*
|
||||
* @param lines number of lines to scroll
|
||||
*/
|
||||
void scrollDown(int lines);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
* Michael Scharf (Wind River) - initial API and implementation
|
||||
* Anton Leherbauer (Wind River) - [433751] Add option to enable VT100 line wrapping mode
|
||||
* Anton Leherbauer (Wind River) - [458218] Add support for ANSI insert mode
|
||||
* Anton Leherbauer (Wind River) - [458402] Add support for scroll up/down and scroll region
|
||||
*******************************************************************************/
|
||||
package org.eclipse.tm.internal.terminal.emulator;
|
||||
|
||||
|
@ -157,4 +158,19 @@ public class VT100BackendTraceDecorator implements IVT100EmulatorBackend {
|
|||
fBackend.setInsertMode(enable);
|
||||
}
|
||||
|
||||
public void setScrollRegion(int top, int bottom) {
|
||||
fWriter.println("setScrollRegion("+top+','+bottom+")"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
fBackend.setScrollRegion(top, bottom);
|
||||
}
|
||||
|
||||
public void scrollUp(int lines) {
|
||||
fWriter.println("scrollUp("+lines+")"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
fBackend.scrollUp(lines);
|
||||
}
|
||||
|
||||
public void scrollDown(int lines) {
|
||||
fWriter.println("scrollDown("+lines+")"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
fBackend.scrollDown(lines);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
* Anton Leherbauer (Wind River) - [433751] Add option to enable VT100 line wrapping mode
|
||||
* Anton Leherbauer (Wind River) - [458218] Add support for ANSI insert mode
|
||||
* Anton Leherbauer (Wind River) - [458398] Add support for normal/application cursor keys mode
|
||||
* Anton Leherbauer (Wind River) - [458402] Add support for scroll up/down and scroll region
|
||||
*******************************************************************************/
|
||||
package org.eclipse.tm.internal.terminal.emulator;
|
||||
|
||||
|
@ -77,6 +78,12 @@ public class VT100Emulator implements ControlListener {
|
|||
*/
|
||||
private static final int ANSISTATE_EXPECTING_DEC_PRIVATE_COMMAND = 4;
|
||||
|
||||
/**
|
||||
* This is a character processing state: We've seen one of ()*+-./ after an escape
|
||||
* character. Expecting a character set designation character.
|
||||
*/
|
||||
private static final int ANSISTATE_EXPECTING_CHARSET_DESIGNATION = 5;
|
||||
|
||||
|
||||
/**
|
||||
* This field holds the current state of the Finite TerminalState Automaton (FSA)
|
||||
|
@ -341,6 +348,16 @@ public class VT100Emulator implements ControlListener {
|
|||
ansiOsCommand.delete(0, ansiOsCommand.length());
|
||||
break;
|
||||
|
||||
case ')':
|
||||
case '(':
|
||||
case '*':
|
||||
case '+':
|
||||
case '-':
|
||||
case '.':
|
||||
case '/':
|
||||
ansiState = ANSISTATE_EXPECTING_CHARSET_DESIGNATION;
|
||||
break;
|
||||
|
||||
case '7':
|
||||
// Save cursor position and character attributes
|
||||
|
||||
|
@ -413,6 +430,12 @@ public class VT100Emulator implements ControlListener {
|
|||
}
|
||||
break;
|
||||
|
||||
case ANSISTATE_EXPECTING_CHARSET_DESIGNATION:
|
||||
if (character != '%')
|
||||
ansiState = ANSISTATE_INITIAL;
|
||||
// Character set designation commands are ignored
|
||||
break;
|
||||
|
||||
default:
|
||||
// This should never happen! If it does happen, it means there is a
|
||||
// bug in the FSA. For robustness, we return to the initial
|
||||
|
@ -483,6 +506,11 @@ public class VT100Emulator implements ControlListener {
|
|||
processAnsiCommand_D();
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
// Line Position Absolute [row] (default = [1,column]) (VPA).
|
||||
processAnsiCommand_d();
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
// Move cursor to first column of Nth next line (default 1).
|
||||
processAnsiCommand_E();
|
||||
|
@ -548,16 +576,19 @@ public class VT100Emulator implements ControlListener {
|
|||
processAnsiCommand_P();
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
// Set Scrolling Region.
|
||||
processAnsiCommand_r();
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
// Scroll up.
|
||||
// Emacs, vi, and GNU readline don't seem to use this command, so we ignore
|
||||
// it for now.
|
||||
processAnsiCommand_S();
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
// Scroll down.
|
||||
// Emacs, vi, and GNU readline don't seem to use this command, so we ignore
|
||||
// it for now.
|
||||
processAnsiCommand_T();
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
|
@ -646,6 +677,14 @@ public class VT100Emulator implements ControlListener {
|
|||
moveCursorBackward(getAnsiParameter(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method moves the cursor to a specific row.
|
||||
*/
|
||||
private void processAnsiCommand_d() {
|
||||
// Line Position Absolute [row] (default = [1,column]) (VPA).
|
||||
text.setCursorLine(getAnsiParameter(0) - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method moves the cursor to the first column of the Nth next line,
|
||||
* where N is specified by the ANSI parameter (default 1).
|
||||
|
@ -967,17 +1006,63 @@ public class VT100Emulator implements ControlListener {
|
|||
text.deleteCharacters(getAnsiParameter(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Scrolling Region [top;bottom] (default = full size of window) (DECSTBM).
|
||||
*/
|
||||
private void processAnsiCommand_r() {
|
||||
int top = 0;
|
||||
int bottom = 0;
|
||||
if (ansiParameters[0].length() > 0 && ansiParameters[1].length() > 0) {
|
||||
top = getAnsiParameter(0);
|
||||
bottom = getAnsiParameter(1);
|
||||
}
|
||||
text.setScrollRegion(top-1, bottom-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scroll up n lines (default = 1 line).
|
||||
*/
|
||||
private void processAnsiCommand_S() {
|
||||
text.scrollUp(getAnsiParameter(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Scroll down n lines (default = 1 line).
|
||||
*/
|
||||
private void processAnsiCommand_T() {
|
||||
text.scrollDown(getAnsiParameter(0));
|
||||
}
|
||||
|
||||
private void processDecPrivateCommand_h() {
|
||||
if (getAnsiParameter(0) == 1) {
|
||||
int param = getAnsiParameter(0);
|
||||
switch (param) {
|
||||
case 1:
|
||||
// Enable Application Cursor Keys (DECCKM)
|
||||
terminal.enableApplicationCursorKeys(true);
|
||||
break;
|
||||
case 47:
|
||||
// Use Alternate Screen Buffer (ignored).
|
||||
break;
|
||||
default:
|
||||
Logger.log("Unsupported command parameter: CSI ?" + param + 'h'); //$NON-NLS-1$
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void processDecPrivateCommand_l() {
|
||||
if (getAnsiParameter(0) == 1) {
|
||||
int param = getAnsiParameter(0);
|
||||
switch (param) {
|
||||
case 1:
|
||||
// Enable Normal Cursor Keys (DECCKM)
|
||||
terminal.enableApplicationCursorKeys(false);
|
||||
break;
|
||||
case 47:
|
||||
// Use Normal Screen Buffer (ignored, but reset scroll region).
|
||||
text.setScrollRegion(-1, -1);
|
||||
break;
|
||||
default:
|
||||
Logger.log("Unsupported command parameter: CSI ?" + param + 'l'); //$NON-NLS-1$
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
* Anton Leherbauer (Wind River) - [206329] Changing terminal size right after connect does not scroll properly
|
||||
* Anton Leherbauer (Wind River) - [433751] Add option to enable VT100 line wrapping mode
|
||||
* Anton Leherbauer (Wind River) - [458218] Add support for ANSI insert mode
|
||||
* Anton Leherbauer (Wind River) - [458402] Add support for scroll up/down and scroll region
|
||||
*******************************************************************************/
|
||||
package org.eclipse.tm.internal.terminal.emulator;
|
||||
|
||||
|
@ -21,6 +22,28 @@ import org.eclipse.tm.terminal.model.Style;
|
|||
*/
|
||||
public class VT100EmulatorBackend implements IVT100EmulatorBackend {
|
||||
|
||||
private static class ScrollRegion {
|
||||
static final ScrollRegion FULL_WINDOW = new ScrollRegion(0, Integer.MAX_VALUE-1);
|
||||
private final int fTop;
|
||||
private final int fBottom;
|
||||
ScrollRegion(int top, int bottom) {
|
||||
fTop = top;
|
||||
fBottom = bottom;
|
||||
}
|
||||
boolean contains(int line) {
|
||||
return line >= fTop && line <= fBottom;
|
||||
}
|
||||
int getTopLine() {
|
||||
return fTop;
|
||||
}
|
||||
int getBottomLine() {
|
||||
return fBottom;
|
||||
}
|
||||
int getHeight() {
|
||||
return fBottom - fTop + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This field holds the number of the column in which the cursor is
|
||||
* logically positioned. The leftmost column on the screen is column 0, and
|
||||
|
@ -62,6 +85,8 @@ public class VT100EmulatorBackend implements IVT100EmulatorBackend {
|
|||
int fColumns;
|
||||
final private ITerminalTextData fTerminal;
|
||||
private boolean fVT100LineWrapping;
|
||||
private ScrollRegion fScrollRegion = ScrollRegion.FULL_WINDOW;
|
||||
|
||||
public VT100EmulatorBackend(ITerminalTextData terminal) {
|
||||
fTerminal=terminal;
|
||||
}
|
||||
|
@ -210,7 +235,7 @@ public class VT100EmulatorBackend implements IVT100EmulatorBackend {
|
|||
return;
|
||||
assert n>0;
|
||||
int line=toAbsoluteLine(fCursorLine);
|
||||
int nLines=fTerminal.getHeight()-line;
|
||||
int nLines=Math.min(fTerminal.getHeight()-line, fScrollRegion.getBottomLine()-fCursorLine+1);
|
||||
fTerminal.scroll(line, nLines, n);
|
||||
}
|
||||
}
|
||||
|
@ -240,13 +265,12 @@ public class VT100EmulatorBackend implements IVT100EmulatorBackend {
|
|||
return;
|
||||
assert n>0;
|
||||
int line=toAbsoluteLine(fCursorLine);
|
||||
int nLines=fTerminal.getHeight()-line;
|
||||
int nLines=Math.min(fTerminal.getHeight()-line, fScrollRegion.getBottomLine()-fCursorLine+1);
|
||||
fTerminal.scroll(line, nLines, -n);
|
||||
}
|
||||
}
|
||||
private boolean isCusorInScrollingRegion() {
|
||||
// TODO Auto-generated method stub
|
||||
return true;
|
||||
return fScrollRegion.contains(fCursorLine);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -333,7 +357,9 @@ public class VT100EmulatorBackend implements IVT100EmulatorBackend {
|
|||
* MUST be called from a synchronized block!
|
||||
*/
|
||||
private void doNewline() {
|
||||
if(fCursorLine+1>=fLines) {
|
||||
if (fCursorLine == fScrollRegion.getBottomLine())
|
||||
scrollUp(1);
|
||||
else if (fCursorLine+1>=fLines) {
|
||||
int h=fTerminal.getHeight();
|
||||
fTerminal.addLine();
|
||||
if(h!=fTerminal.getHeight())
|
||||
|
@ -440,4 +466,29 @@ public class VT100EmulatorBackend implements IVT100EmulatorBackend {
|
|||
public void setInsertMode(boolean enable) {
|
||||
fInsertMode = enable;
|
||||
}
|
||||
|
||||
public void setScrollRegion(int top, int bottom) {
|
||||
if (top < 0 || bottom < 0)
|
||||
fScrollRegion = ScrollRegion.FULL_WINDOW;
|
||||
else if (top < bottom)
|
||||
fScrollRegion = new ScrollRegion(top, bottom);
|
||||
}
|
||||
|
||||
public void scrollUp(int n) {
|
||||
assert n>0;
|
||||
synchronized (fTerminal) {
|
||||
int line = toAbsoluteLine(fScrollRegion.getTopLine());
|
||||
int nLines = Math.min(fTerminal.getHeight()-line, fScrollRegion.getHeight());
|
||||
fTerminal.scroll(line, nLines, -n);
|
||||
}
|
||||
}
|
||||
|
||||
public void scrollDown(int n) {
|
||||
assert n>0;
|
||||
synchronized (fTerminal) {
|
||||
int line = toAbsoluteLine(fScrollRegion.getTopLine());
|
||||
int nLines = Math.min(fTerminal.getHeight()-line, fScrollRegion.getHeight());
|
||||
fTerminal.scroll(line, nLines, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue