Skip to content

Commit 2b69e98

Browse files
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 #831 (cherry picked from commit 229c55c) Co-authored-by: Jonah Graham <[email protected]>
1 parent 81989fa commit 2b69e98

File tree

3 files changed

+55
-3
lines changed

3 files changed

+55
-3
lines changed

terminal/plugins/org.eclipse.tm.terminal.control/META-INF/MANIFEST.MF

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
22
Bundle-ManifestVersion: 2
33
Bundle-Name: %pluginName
44
Bundle-SymbolicName: org.eclipse.tm.terminal.control; singleton:=true
5-
Bundle-Version: 5.5.300.qualifier
5+
Bundle-Version: 5.5.301.qualifier
66
Bundle-Activator: org.eclipse.tm.internal.terminal.control.impl.TerminalPlugin
77
Bundle-Vendor: %providerName
88
Bundle-Localization: plugin

terminal/plugins/org.eclipse.tm.terminal.control/src/org/eclipse/tm/internal/terminal/emulator/VT100Emulator.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ public class VT100Emulator implements ControlListener {
9797
*/
9898
private static final int ANSISTATE_EXPECTING_CHARSET_DESIGNATION = 5;
9999

100+
/**
101+
* For cases where the OSC (OS Command) ends with a multi-byte ST (i.e. ESC \)
102+
* we use this extra state.
103+
*/
104+
private static final int ANSISTATE_EXPECTING_OS_COMMAND_END = 6;
105+
100106
/**
101107
* This field holds the current state of the Finite TerminalState Automaton (FSA)
102108
* that recognizes ANSI escape sequences.
@@ -428,16 +434,27 @@ private void processNewText() throws IOException {
428434
break;
429435

430436
case ANSISTATE_EXPECTING_OS_COMMAND:
431-
// A BEL (\u0007) character marks the end of the OSC sequence.
437+
// A BEL (\u0007) or ESC \ ('\e\\') character marks the end of the OSC sequence.
432438

433439
if (character == '\u0007') {
434440
ansiState = ANSISTATE_INITIAL;
435441
processAnsiOsCommand();
442+
} else if (character == '\u001b') {
443+
ansiState = ANSISTATE_EXPECTING_OS_COMMAND_END;
436444
} else {
437445
ansiOsCommand.append(character);
438446
}
439447
break;
440448

449+
case ANSISTATE_EXPECTING_OS_COMMAND_END:
450+
ansiState = ANSISTATE_INITIAL;
451+
if (character == '\\') {
452+
processAnsiOsCommand();
453+
} else {
454+
Logger.log("Unsupported escape sequence: escape '" + ansiOsCommand + " \\e" + character + "'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
455+
}
456+
break;
457+
441458
case ANSISTATE_EXPECTING_DEC_PRIVATE_COMMAND:
442459
// Parameters can appear after the '[?' in an escape sequence, but they
443460
// are optional.

terminal/plugins/org.eclipse.tm.terminal.test/src/org/eclipse/tm/internal/terminal/emulator/VT100EmulatorTest.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,18 @@ public class VT100EmulatorTest {
3737
private static final String CLEAR_ENTIRE_SCREEN = "\033[2J";
3838
private static final String SCROLL_REVERSE = "\033M";
3939

40-
private static String TITLE(String title) {
40+
private static String TITLE_ST_BEL(String title) {
4141
return "\033]0;" + title + "\007";
4242
}
4343

44+
private static String TITLE_ST_ESC_BACKSLASH(String title) {
45+
return "\033]0;" + title + "\033\\";
46+
}
47+
48+
private static String TITLE(String title) {
49+
return TITLE_ST_BEL(title);
50+
}
51+
4452
private static String SCROLL_REGION(int startRow, int endRow) {
4553
return "\033[" + startRow + ";" + endRow + "r";
4654
}
@@ -340,4 +348,31 @@ public void testScrollReverseScrollingRegion() {
340348
assertAll(() -> assertCursorLocation(2, expected.get(2).length()), () -> assertTextEquals(expected));
341349
}
342350

351+
@Test
352+
public void testStringTerminator() {
353+
run( //
354+
TITLE_ST_BEL("TITLE1"), //
355+
"HELLO1", //
356+
TITLE_ST_ESC_BACKSLASH("TITLE2"), //
357+
"HELLO2", //
358+
TITLE_ST_BEL("TITLE3"), //
359+
"HELLO3", //
360+
TITLE_ST_ESC_BACKSLASH("TITLE4") //
361+
);
362+
assertAll(() -> assertTextEquals("HELLO1HELLO2HELLO3"),
363+
() -> assertEquals(List.of("TITLE1", "TITLE2", "TITLE3", "TITLE4"), control.getAllTitles()));
364+
}
365+
366+
@Test
367+
public void testMalformedStringTerminator() {
368+
run( //
369+
TITLE_ST_ESC_BACKSLASH("TITLE1"), //
370+
"\033]0;" + "TITLE1" + "\033X", //
371+
TITLE_ST_ESC_BACKSLASH("TITLE2"), //
372+
"HELLO" //
373+
);
374+
assertAll(() -> assertTextEquals("HELLO"),
375+
() -> assertEquals(List.of("TITLE1", "TITLE2"), control.getAllTitles()));
376+
}
377+
343378
}

0 commit comments

Comments
 (0)