Add support for String Terminator to be ESC \ (#855)

This fixes support to properly identify the end of
OSC control sequences which can be terminated
with a BEL or ESC \.

Fixes https://github.com/eclipse-cdt/cdt/issues/831

(cherry picked from commit 229c55c9e2)

Co-authored-by: Jonah Graham <jonah@kichwacoders.com>
This commit is contained in:
github-actions[bot] 2024-07-02 16:03:36 -04:00 committed by GitHub
parent 81989fa4c4
commit 2b69e9845d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 55 additions and 3 deletions

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.tm.terminal.control; singleton:=true
Bundle-Version: 5.5.300.qualifier
Bundle-Version: 5.5.301.qualifier
Bundle-Activator: org.eclipse.tm.internal.terminal.control.impl.TerminalPlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin

View file

@ -97,6 +97,12 @@ public class VT100Emulator implements ControlListener {
*/
private static final int ANSISTATE_EXPECTING_CHARSET_DESIGNATION = 5;
/**
* For cases where the OSC (OS Command) ends with a multi-byte ST (i.e. ESC \)
* we use this extra state.
*/
private static final int ANSISTATE_EXPECTING_OS_COMMAND_END = 6;
/**
* This field holds the current state of the Finite TerminalState Automaton (FSA)
* that recognizes ANSI escape sequences.
@ -428,16 +434,27 @@ public class VT100Emulator implements ControlListener {
break;
case ANSISTATE_EXPECTING_OS_COMMAND:
// A BEL (\u0007) character marks the end of the OSC sequence.
// A BEL (\u0007) or ESC \ ('\e\\') character marks the end of the OSC sequence.
if (character == '\u0007') {
ansiState = ANSISTATE_INITIAL;
processAnsiOsCommand();
} else if (character == '\u001b') {
ansiState = ANSISTATE_EXPECTING_OS_COMMAND_END;
} else {
ansiOsCommand.append(character);
}
break;
case ANSISTATE_EXPECTING_OS_COMMAND_END:
ansiState = ANSISTATE_INITIAL;
if (character == '\\') {
processAnsiOsCommand();
} else {
Logger.log("Unsupported escape sequence: escape '" + ansiOsCommand + " \\e" + character + "'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
break;
case ANSISTATE_EXPECTING_DEC_PRIVATE_COMMAND:
// Parameters can appear after the '[?' in an escape sequence, but they
// are optional.

View file

@ -37,10 +37,18 @@ public class VT100EmulatorTest {
private static final String CLEAR_ENTIRE_SCREEN = "\033[2J";
private static final String SCROLL_REVERSE = "\033M";
private static String TITLE(String title) {
private static String TITLE_ST_BEL(String title) {
return "\033]0;" + title + "\007";
}
private static String TITLE_ST_ESC_BACKSLASH(String title) {
return "\033]0;" + title + "\033\\";
}
private static String TITLE(String title) {
return TITLE_ST_BEL(title);
}
private static String SCROLL_REGION(int startRow, int endRow) {
return "\033[" + startRow + ";" + endRow + "r";
}
@ -340,4 +348,31 @@ public class VT100EmulatorTest {
assertAll(() -> assertCursorLocation(2, expected.get(2).length()), () -> assertTextEquals(expected));
}
@Test
public void testStringTerminator() {
run( //
TITLE_ST_BEL("TITLE1"), //
"HELLO1", //
TITLE_ST_ESC_BACKSLASH("TITLE2"), //
"HELLO2", //
TITLE_ST_BEL("TITLE3"), //
"HELLO3", //
TITLE_ST_ESC_BACKSLASH("TITLE4") //
);
assertAll(() -> assertTextEquals("HELLO1HELLO2HELLO3"),
() -> assertEquals(List.of("TITLE1", "TITLE2", "TITLE3", "TITLE4"), control.getAllTitles()));
}
@Test
public void testMalformedStringTerminator() {
run( //
TITLE_ST_ESC_BACKSLASH("TITLE1"), //
"\033]0;" + "TITLE1" + "\033X", //
TITLE_ST_ESC_BACKSLASH("TITLE2"), //
"HELLO" //
);
assertAll(() -> assertTextEquals("HELLO"),
() -> assertEquals(List.of("TITLE1", "TITLE2"), control.getAllTitles()));
}
}