mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-27 05:13:10 +00:00
Fix up OSC / iTerm2 escape code parsing as part of #1565
This commit is contained in:
parent
9f59cf1468
commit
35ba97cbdf
2 changed files with 16 additions and 57 deletions
|
@ -1211,12 +1211,10 @@ static void test_escape_sequences(void)
|
||||||
if (escape_code_length(L"\x1b@") != 2) err(L"test_escape_sequences failed on line %d\n", __LINE__);
|
if (escape_code_length(L"\x1b@") != 2) err(L"test_escape_sequences failed on line %d\n", __LINE__);
|
||||||
|
|
||||||
// iTerm2 escape sequences
|
// iTerm2 escape sequences
|
||||||
if (escape_code_length(L"\x1b]50;CurrentDir=/tmp/foo\x07NOT_PART_OF_SEQUENCE") != 24) err(L"test_escape_sequences failed on line %d\n", __LINE__);
|
if (escape_code_length(L"\x1b]50;CurrentDir=/tmp/foo\x07NOT_PART_OF_SEQUENCE") != 25) err(L"test_escape_sequences failed on line %d\n", __LINE__);
|
||||||
if (escape_code_length(L"\x1b]50;SetMark\x07NOT_PART_OF_SEQUENCE") != 12) err(L"test_escape_sequences failed on line %d\n", __LINE__);
|
if (escape_code_length(L"\x1b]50;SetMark\x07NOT_PART_OF_SEQUENCE") != 13) err(L"test_escape_sequences failed on line %d\n", __LINE__);
|
||||||
if (escape_code_length(L"\x1b" L"]6;1;bg;red;brightness;255\x07NOT_PART_OF_SEQUENCE") != 27) err(L"test_escape_sequences failed on line %d\n", __LINE__);
|
if (escape_code_length(L"\x1b" L"]6;1;bg;red;brightness;255\x07NOT_PART_OF_SEQUENCE") != 28) err(L"test_escape_sequences failed on line %d\n", __LINE__);
|
||||||
if (escape_code_length(L"\x1b]Pg4040ff\x1b\\NOT_PART_OF_SEQUENCE") != 10) err(L"test_escape_sequences failed on line %d\n", __LINE__);
|
if (escape_code_length(L"\x1b]Pg4040ff\x1b\\NOT_PART_OF_SEQUENCE") != 12) err(L"test_escape_sequences failed on line %d\n", __LINE__);
|
||||||
|
|
||||||
// OSC codes
|
|
||||||
if (escape_code_length(L"\x1b]blahblahblah\x1b\\") != 16) err(L"test_escape_sequences failed on line %d\n", __LINE__);
|
if (escape_code_length(L"\x1b]blahblahblah\x1b\\") != 16) err(L"test_escape_sequences failed on line %d\n", __LINE__);
|
||||||
if (escape_code_length(L"\x1b]blahblahblah\x07") != 15) err(L"test_escape_sequences failed on line %d\n", __LINE__);
|
if (escape_code_length(L"\x1b]blahblahblah\x07") != 15) err(L"test_escape_sequences failed on line %d\n", __LINE__);
|
||||||
}
|
}
|
||||||
|
|
63
screen.cpp
63
screen.cpp
|
@ -255,26 +255,23 @@ size_t escape_code_length(const wchar_t *code)
|
||||||
|
|
||||||
if (! found)
|
if (! found)
|
||||||
{
|
{
|
||||||
/* iTerm2 escape codes: CSI followed by ], terminated by either BEL or - see https://code.google.com/p/iterm2/wiki/ProprietaryEscapeCodes */
|
/* iTerm2 escape codes: CSI followed by ], terminated by either BEL or escape + backslash. See https://code.google.com/p/iterm2/wiki/ProprietaryEscapeCodes */
|
||||||
if (code[1] == ']')
|
if (code[1] == ']')
|
||||||
{
|
{
|
||||||
/* A sequence of characters terminated by either 'ESC backslash' or BEL */
|
// Start at 2 to skip over <esc>]
|
||||||
const wchar_t * const end1_sentinel = L"\x1b\\";
|
size_t cursor = 2;
|
||||||
const wchar_t * const end2_sentinel = L"\a";
|
for (; code[cursor] != L'\0'; cursor++)
|
||||||
const wchar_t *end1 = wcsstr(&code[2], end1_sentinel);
|
|
||||||
const wchar_t *end2 = wcsstr(&code[2], end2_sentinel);
|
|
||||||
|
|
||||||
// Use the non-null end, or if both are null, use the earlier end
|
|
||||||
const wchar_t *end = end1;
|
|
||||||
if (end == NULL || (end2 != NULL && end2 < end))
|
|
||||||
{
|
{
|
||||||
end = end2;
|
/* Consume a sequence of characters up to <esc>\ or <bel> */
|
||||||
}
|
if (code[cursor] == '\x07' || (code[cursor] == '\\' && code[cursor - 1] == '\x1b'))
|
||||||
if (end != NULL)
|
|
||||||
{
|
{
|
||||||
assert(end > code);
|
|
||||||
resulting_length = (end - code);
|
|
||||||
found = true;
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
resulting_length = cursor + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -318,42 +315,6 @@ size_t escape_code_length(const wchar_t *code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (! found)
|
if (! found)
|
||||||
{
|
|
||||||
/* OSC code, terminated by <esc>\ or <bel> */
|
|
||||||
if (code[1] == L']')
|
|
||||||
{
|
|
||||||
// Start at 2 to skip over <esc>]
|
|
||||||
size_t cursor = 2;
|
|
||||||
bool backslash_ends = false;
|
|
||||||
for (; code[cursor] != L'\0'; cursor++)
|
|
||||||
{
|
|
||||||
/* Consume a sequence of characters up to <esc>\ or <bel> */
|
|
||||||
wchar_t c = code[cursor];
|
|
||||||
if (c == L'\x1b') {
|
|
||||||
backslash_ends = true;
|
|
||||||
}
|
|
||||||
else if (c == L'\\' && backslash_ends)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
backslash_ends = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == L'\x07') {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (found)
|
|
||||||
{
|
|
||||||
resulting_length = cursor + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (! found)
|
|
||||||
{
|
{
|
||||||
/* Generic VT100 two byte sequence: <esc> followed by something in the range @ through _ */
|
/* Generic VT100 two byte sequence: <esc> followed by something in the range @ through _ */
|
||||||
if (code[1] >= L'@' && code[1] <= L'_')
|
if (code[1] >= L'@' && code[1] <= L'_')
|
||||||
|
|
Loading…
Reference in a new issue