mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-28 05:43:11 +00:00
f285e85b0c
Some terminals send the focus-in sequences ("^[I") whenever focus reporting is enabled. We enable focus reporting whenever we are finished running a command. If we run two commands without reading in between, the focus sequences will show up on the terminal. Fix this by enabling focus-reporting as late as possible. This fixes the problem with `^[I` showing up when running "cat" in gnome-terminal https://github.com/fish-shell/fish-shell/issues/10411. This begs the question if we should do the same for CSI u and bracketed paste. It's difficult to answer that; let's hope we find motivating test cases. If we enable CSI u too late, we might misinterpret key presses, so for now we still enable those as early as possible. Also, since we now read immediately after enabling focus events, we can get rid of the hack where we defer enabling them until after the first prompt. When I start a fresh terminal, the ^[I no longer shows up.
160 lines
3.6 KiB
Python
160 lines
3.6 KiB
Python
#!/usr/bin/env python3
|
|
from pexpect_helper import SpawnedProc
|
|
|
|
sp = SpawnedProc()
|
|
send, sendline, sleep, expect_prompt, expect_re, expect_str = (
|
|
sp.send,
|
|
sp.sendline,
|
|
sp.sleep,
|
|
sp.expect_prompt,
|
|
sp.expect_re,
|
|
sp.expect_str,
|
|
)
|
|
|
|
|
|
def expect_read_prompt():
|
|
expect_re(r"\r\n?read> \x1b\[\?1004h$")
|
|
|
|
|
|
def expect_marker(text):
|
|
expect_prompt("\r\n.*@MARKER:" + str(text) + "@\\r\\n")
|
|
|
|
|
|
def print_var_contents(varname, expected):
|
|
sendline("echo $" + varname)
|
|
expect_prompt(expected)
|
|
|
|
|
|
expect_prompt()
|
|
|
|
# read
|
|
|
|
sendline("read")
|
|
expect_read_prompt()
|
|
sendline("text")
|
|
expect_prompt()
|
|
|
|
sendline("read foo")
|
|
expect_read_prompt()
|
|
sendline("text")
|
|
expect_prompt()
|
|
print_var_contents("foo", "text")
|
|
|
|
sendline("read foo")
|
|
expect_read_prompt()
|
|
sendline("again\r_marker 1")
|
|
expect_prompt()
|
|
expect_marker(1)
|
|
print_var_contents("foo", "again")
|
|
|
|
sendline("read foo")
|
|
expect_read_prompt()
|
|
sendline("bar\r_marker 2")
|
|
expect_prompt()
|
|
expect_marker(2)
|
|
print_var_contents("foo", "bar")
|
|
|
|
# read -c (see #8633)
|
|
sendline(r"read -c init_text somevar && echo $somevar")
|
|
expect_re(r"\r\n?read> init_text\x1b\[\?1004h$")
|
|
sendline("someval")
|
|
expect_prompt("someval\r\n")
|
|
|
|
sendline(r"read --command='some other text' somevar && echo $somevar")
|
|
expect_re(r"\r\n?read> some other text\x1b\[\?1004h$")
|
|
sendline("another value")
|
|
expect_prompt("another value\r\n")
|
|
|
|
|
|
# read -s
|
|
|
|
sendline("read -s foo")
|
|
expect_read_prompt()
|
|
sendline("read_s\r_marker 3")
|
|
expect_prompt()
|
|
expect_marker(3)
|
|
print_var_contents("foo", "read_s")
|
|
|
|
# read -n
|
|
|
|
sendline("read -n 3 foo")
|
|
expect_read_prompt()
|
|
sendline("123_marker 3")
|
|
expect_prompt()
|
|
expect_marker(3)
|
|
print_var_contents("foo", "123")
|
|
|
|
sendline("read -n 3 foo")
|
|
expect_read_prompt()
|
|
sendline("456_marker 4")
|
|
expect_prompt()
|
|
expect_marker(4)
|
|
print_var_contents("foo", "456")
|
|
|
|
sendline("read -n 12 foo bar")
|
|
expect_read_prompt()
|
|
sendline("hello world!_marker 5")
|
|
expect_prompt()
|
|
expect_marker(5)
|
|
print_var_contents("foo", "hello")
|
|
print_var_contents("bar", "world!")
|
|
|
|
sendline("bind ` 'commandline -i test'`")
|
|
expect_prompt()
|
|
sendline("read -n 4 foo")
|
|
expect_read_prompt()
|
|
sendline("te`_marker 6")
|
|
expect_prompt()
|
|
expect_marker(6)
|
|
print_var_contents("foo", "tete")
|
|
|
|
sendline("read -n 4 foo")
|
|
expect_read_prompt()
|
|
sendline("12`_marker 7")
|
|
expect_prompt()
|
|
expect_marker(7)
|
|
print_var_contents("foo", "12te")
|
|
|
|
# Verify we don't hang on `read | cat`. See #4540.
|
|
sendline("read | cat")
|
|
expect_read_prompt()
|
|
sendline("bar\r_marker 4540")
|
|
expect_prompt()
|
|
expect_marker(4540)
|
|
|
|
|
|
# ==========
|
|
# The fix for issue #2007 initially introduced a problem when using a function
|
|
# to read from /dev/stdin when that is associated with the tty. These tests
|
|
# are to ensure we don't introduce a regression.
|
|
send("r2l\n")
|
|
expect_read_prompt()
|
|
send("abc\n")
|
|
expect_read_prompt()
|
|
send("def\n")
|
|
expect_str("abc then def\r\n")
|
|
expect_prompt()
|
|
|
|
# Some systems don't have /dev/stdin - effectively skip the test there.
|
|
# I'd love to warn about it, but I don't know how.
|
|
send("test -r /dev/stdin; and r2l </dev/stdin; or r2l\n")
|
|
expect_read_prompt()
|
|
send("ghi\n")
|
|
expect_read_prompt()
|
|
send("jkl\n")
|
|
expect_str("ghi then jkl\r\n")
|
|
expect_prompt()
|
|
|
|
# Long line so we don't have to count prompts
|
|
sendline(
|
|
"""set -g fish_prompt_fired 0; function dontfire --on-event fish_prompt; set -g fish_prompt_fired (math $fish_prompt_fired + 1); end; function dofire --on-event fish_read; set -g fish_read_fired 1; end"""
|
|
)
|
|
|
|
expect_prompt()
|
|
sendline("read foo")
|
|
expect_read_prompt()
|
|
sendline("text")
|
|
expect_prompt()
|
|
# Once for right after setting the listener, another for after the read.
|
|
print_var_contents("fish_prompt_fired", "2")
|
|
print_var_contents("fish_read_fired", "1")
|