# vim: set filetype=expect: spawn $fish expect_prompt # Fish should start in default-mode (i.e., emacs) bindings. The default escape # timeout is 30ms. # Verify the emacs transpose word (\et) behavior using various delays, # including none, after the escape character. # Start by testing with no delay. This should transpose the words. send "echo abc def" send "\033t\r" expect_prompt -re {\r\ndef abc\r\n} { puts "emacs transpose words, default timeout: no delay" } unmatched { puts stderr "emacs transpose words fail, default timeout: no delay" } # Now test with a delay > 0 and < the escape timeout. This should transpose # the words. send "echo ghi jkl" send "\033" sleep 0.010 send "t\r" expect_prompt -re {\r\njkl ghi\r\n} { puts "emacs transpose words, default timeout: short delay" } unmatched { puts stderr "emacs transpose words fail, default timeout: short delay" } # Now test with a delay > the escape timeout. The transposition should not # occur and the "t" should become part of the text that is echoed. send "echo mno pqr" send "\033" sleep 0.200 send "t\r" expect_prompt -re {\r\nmno pqrt\r\n} { puts "emacs transpose words, default timeout: long delay" } unmatched { puts stderr "emacs transpose words fail, default timeout: long delay" } # Now test that exactly the expected bind modes are defined send "bind --list-modes\r" expect_prompt -re {\r\ndefault\r\npaste} { puts "emacs bind modes" } unmatched { puts stderr "Unexpected bind modes" } # Test vi key bindings. # This should leave vi mode in the insert state. send "set -g fish_key_bindings fish_vi_key_bindings\r" expect_prompt # Go through a prompt cycle to let fish catch up, it may be slow due to ASAN send "echo success: default escape timeout\r" expect_prompt -re {\r\nsuccess: default escape timeout\r\n} { puts "prime vi mode, default timeout" } unmatched { puts stderr "prime vi mode, default timeout" } send "echo fail: default escape timeout" send "\033" # Delay needed to allow fish to transition to vi "normal" mode. The delay is # longer than strictly necessary to let fish catch up as it may be slow due to # ASAN. sleep 0.150 send "ddi" send "echo success: default escape timeout\r" expect_prompt -re {\r\nsuccess: default escape timeout\r\n} { puts "vi replace line, default timeout: long delay" } unmatched { puts stderr "vi replace line, default timeout: long delay" } # Test replacing a single character. send "echo TEXT" send "\033" # Delay needed to allow fish to transition to vi "normal" mode. sleep 0.150 send "hhrAi\r" expect_prompt -re {\r\nTAXT\r\n} { puts "vi mode replace char, default timeout: long delay" } unmatched { puts stderr "vi mode replace char, default timeout: long delay" } # Test deleting characters with 'x'. send "echo MORE-TEXT" send "\033" # Delay needed to allow fish to transition to vi "normal" mode. sleep 0.250 send "xxxxx\r" expect_prompt -re {\r\nMORE\r\n} { puts "vi mode delete char, default timeout: long delay" } unmatched { puts stderr "vi mode delete char, default timeout: long delay" } # Test jumping forward til before a character with t send "echo MORE-TEXT-IS-NICE" send "\033" # Delay needed to allow fish to transition to vi "normal" mode. sleep 0.250 send "0tTD\r" expect_prompt -re {\r\nMORE\r\n} { puts "vi mode forward-jump-till character, default timeout: long delay" } unmatched { puts stderr "vi mode forward-jump-till character, default timeout: long delay" } # Test jumping backward til before a character with T send "echo MORE-TEXT-IS-NICE" send "\033" # Delay needed to allow fish to transition to vi "normal" mode. sleep 0.250 send "TSD\r" expect_prompt -re {\r\nMORE-TEXT-IS\r\n} { puts "vi mode backward-jump-till character, default timeout: long delay" } unmatched { puts stderr "vi mode backward-jump-till character, default timeout: long delay" } # Test jumping backward with F and repeating send "echo MORE-TEXT-IS-NICE" send "\033" # Delay needed to allow fish to transition to vi "normal" mode. sleep 0.250 send "F-;D\r" expect_prompt -re {\r\nMORE-TEXT\r\n} { puts "vi mode backward-jump-to character and repeat, default timeout: long delay" } unmatched { puts stderr "vi mode backward-jump-to character and repeat, default timeout: long delay" } # Test jumping backward with F w/reverse jump send "echo MORE-TEXT-IS-NICE" send "\033" # Delay needed to allow fish to transition to vi "normal" mode. sleep 0.250 send "F-F-,D\r" expect_prompt -re {\r\nMORE-TEXT-IS\r\n} { puts "vi mode backward-jump-to character, and reverse, default timeout: long delay" } unmatched { puts stderr "vi mode backward-jump-to character, and reverse, default timeout: long delay" } # Verify that changing the escape timeout has an effect. send "set -g fish_escape_delay_ms 200\r" expect_prompt send "echo fail: lengthened escape timeout" send "\033" sleep 0.350 send "ddi" send "echo success: lengthened escape timeout\r" expect_prompt -re {\r\nsuccess: lengthened escape timeout\r\n} { puts "vi replace line, 200ms timeout: long delay" } unmatched { puts stderr "vi replace line, 200ms timeout: long delay" } # Verify that we don't switch to vi normal mode if we don't wait long enough # after sending escape. send "echo fail: no normal mode" send "\033" sleep 0.050 send "ddi" send "inserted\r" expect_prompt -re {\r\nfail: no normal modediinserted\r\n} { puts "vi replace line, 200ms timeout: short delay" } unmatched { puts stderr "vi replace line, 200ms timeout: short delay" } # Test 't' binding that contains non-zero arity function (forward-jump) followed # by another function (and) https://github.com/fish-shell/fish-shell/issues/2357 send "\033" sleep 0.300 send "ddiecho TEXT\033" sleep 0.300 send "hhtTrN\r" expect_prompt -re {\r\nTENT\r\n} { puts "t-binding success" } -nounmatched -re {\r\nfail} { puts stderr "t-binding fail" } unmatched { puts stderr "Couldn't find expected output 'TENT'" } # Now test that exactly the expected bind modes are defined send "bind --list-modes\r" expect_prompt -re {\r\ndefault\r\ninsert\r\npaste\r\nreplace\r\nreplace_one\r\nvisual\r\n} { puts "vi bind modes" } unmatched { puts stderr "Unexpected vi bind modes" } # Switch back to regular (emacs mode) key bindings. send "set -g fish_key_bindings fish_default_key_bindings\r" expect_prompt # Verify the custom escape timeout of 200ms set earlier is still in effect. send "echo fish_escape_delay_ms=\$fish_escape_delay_ms\r" expect_prompt -re {\r\nfish_escape_delay_ms=200\r\n} { puts "default-mode custom timeout set correctly" } unmatched { puts stderr "default-mode custom timeout not set correctly" } # Set it to 100ms. send "set -g fish_escape_delay_ms 100\r" expect_prompt # Verify the emacs transpose word (\et) behavior using various delays, # including none, after the escape character. # Start by testing with no delay. This should transpose the words. send "echo abc def" send "\033" send "t\r" expect_prompt -re {\r\ndef abc\r\n} { puts "emacs transpose words, 100ms timeout: no delay" } unmatched { puts stderr "emacs transpose words fail, 100ms timeout: no delay" } # Same test as above but with a slight delay less than the escape timeout. send "echo ghi jkl" send "\033" sleep 0.080 send "t\r" expect_prompt -re {\r\njkl ghi\r\n} { puts "emacs transpose words, 100ms timeout: short delay" } unmatched { puts stderr "emacs transpose words fail, 100ms timeout: short delay" } # Now test with a delay > the escape timeout. The transposition should not # occur and the "t" should become part of the text that is echoed. send "echo mno pqr" send "\033" sleep 0.250 send "t\r" expect_prompt -re {\r\nmno pqrt\r\n} { puts "emacs transpose words, 100ms timeout: long delay" } unmatched { puts stderr "emacs transpose words fail, 100ms timeout: long delay" } # Verify special characters, such as \cV, are not intercepted by the kernel # tty driver. Rather, they can be bound and handled by fish. send "bind \\cV 'echo ctrl-v seen'\r" expect_prompt send "\026\r" expect_prompt -re {ctrl-v seen} { puts "ctrl-v seen" } unmatched { puts stderr "ctrl-v not seen" } send "bind \\cO 'echo ctrl-o seen'\r" expect_prompt send "\017\r" expect_prompt -re {ctrl-o seen} { puts "ctrl-o seen" } unmatched { puts stderr "ctrl-o not seen" } # \x17 is ctrl-w. send "echo git@github.com:fish-shell/fish-shell" send "\x17\x17\r" expect_prompt -re {git@github.com:} { puts "ctrl-w stops at :" } unmatched { puts stderr "ctrl-w does not stop at :" } send "echo git@github.com:fish-shell/fish-shell" send "\x17\x17\x17\r" expect_prompt -re {git@} { puts "ctrl-w stops at @" } unmatched { puts stderr "ctrl-w does not stop at @" } # Ensure that nul can be bound properly (#3189). send "bind -k nul 'echo nul seen'\r" expect_prompt send -null 3 send "\r" expect_prompt -re {nul seen\r\nnul seen\r\nnul seen} { puts "nul seen" } unmatched { puts stderr "nul not seen" } # Test self-insert-notfirst. (#6603) # Here the leading 'q's should be stripped, but the trailing ones not. send "bind q self-insert-notfirst\r" expect_prompt send "qqqecho qqq" send "\r" expect_prompt -re {qqq} { puts "Leading q properly stripped" } unmatched { puts stderr "Leading qs not stripped" }