#!/bin/sh
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}

#
# Check that it says "Interrupted" when it should.
#
# If the TCL variable $intr is set to a single character, probably alphabetic,
# we use Control-whatever as the interrupt character.
#

source scripts/term

if { [info exists intr] && [string length $intr] == 1 } {
    set intr_ch [ctrl $intr]
} else {
    # See what the interrupt chacter is. Control-something we assume.
    # For ^C, we set intr to "C" and intr_ch to the character Control-C.
    if {[catch {exec stty -a | sed -n {s/.*intr = ^\(.\);.*/\1/p}} intr] == 0} {
	if { [string length $intr] != 1 } {
	    send_error "Can't get interrupt char from stty"
	    fail 110
	}
	set intr_ch [ctrl $intr]
    } else {
	send_error "Can't figure out the interrupt character"
	fail 111
    }
}

# Give xvi's virtual terminal the right setting
exp_send "stty intr ^$intr\r"

start_vi

# Set the status line to anything other than "Interrupted"
proc clear_statusline { } {
    exp_send ":\b"
    term_expect timeout { fail 100 } \
	{ statusline_isnt "Interrupted" }
}

# Interrupt tests can take a little longer to happen
set timeout 4

# Tests begin

# Check it started up OK
term_expect timeout { fail 101 } \
	{ screen_is 1 0 [list "" "~"] }


# Interrupt it in keystroke command mode
#
# xvi and nvi say "Interrupted"; vim has its own message.

set vim FALSE	; # Are we running the tests using vim?

exp_send $intr_ch
term_expect timeout { fail 10 } \
    { expr { [screen_is 1 0 [list "" "~"]] && \
	[statusline_is "Interrupted"] } } { } \
    { expr { [screen_is 1 0 [list "" "~"]] && \
	[statusline_starts "Type  :quit<Enter>  to exit Vim"] } } {
	set vim TRUE
    }

# Interrupt it after one char of a 2-char command
#
# vim doen't display anything when this happens but POSIX says:
# "SIGINT: If in open or visual command mode, the terminal shall be alerted."

clear_statusline
exp_send "z$intr_ch"
term_expect timeout { fail 20 } \
    { expr { [screen_is 1 0 [list "" "~"]] &&
	     ( $vim || [statusline_is "Interrupted"] ) } }


# Interrupt it in insert mode

clear_statusline
exp_send "ii"
term_expect timeout { fail 30 } \
    { screen_is 1 1 "i" }
exp_send $intr_ch
term_expect timeout { fail 31 } \
    { expr { [screen_is 1 0 [list "i" "~"]] &&
	     ( $vim || [statusline_is "Interrupted"] ) } }
# Check that you can quote it with ^V
clear_statusline
test 32 a[ctrl V]	1 1 "i^"
exp_send $intr_ch
term_expect timeout { fail 33 } \
    { expr { [screen_is 1 3 [list "i^${intr}" "~"]] &&
	     ( $vim || [statusline_isnt "Interrupted"] ) } }
exp_send [esc]


# Interrupt it in replace mode

clear_statusline
exp_send "0Daabc[esc]h"
term_expect timeout { fail 40 } \
    { screen_is 1 1 "abc" }
exp_send "RX"
term_expect timeout { fail 41 } \
    { screen_is 1 2 "aXc" }
exp_send $intr_ch
term_expect timeout { fail 42 } \
    { expr { [screen_is 1 1 "aXc"] &&
	     ( $vim || [statusline_is "Interrupted"] ) } }
# Check that you can quote it with ^V
clear_statusline
test 43 "0Cabc[esc]hr[ctrl V]"	1 1 "a^c"
if { ! ( $vim || [statusline_isnt "Interrupted"] ) } { fail 44 }
test 45 $intr_ch		1 1 "a^${intr}c"
if { ! ( $vim || [statusline_isnt "Interrupted"] ) } { fail 46 }
test 47 "0Cabc[esc]hR[ctrl V]"	1 1 "a^c"
test 48 "$intr_ch"		1 3 "a^${intr}c"
if { ! ( $vim || [statusline_isnt "Interrupted"] ) } { fail 49 }
exp_send [esc]


# Interrupt it in command line mode

clear_statusline
exp_send "0D:"
term_expect timeout { fail 50 } \
    { expr { [statusline_is ":"] && [screen_is $rows 1 [list "" "~"]] } }
exp_send $intr_ch
term_expect timeout { fail 51 } \
    { expr { [screen_is 1 0 [list "" "~"]] &&
	     ( $vim || [statusline_is "Interrupted"] ) } }
# Check that you can quote it with ^V
clear_statusline
ctest 52 ":a[ctrl V]"	2 ":a^"
ctest 53 $intr_ch	4 ":a^${intr}"
if { ! ( $vim || [statusline_isnt "Interrupted"] ) } { fail 54 }
ctest 55 "\b\b"	1 ":"

# Interrupt it while doing infinite macro recursion

exp_send "map x y\r"
exp_send ":map y x\r"
exp_send "x"
sleep 1
exp_send $intr_ch
term_expect timeout { fail 60 } \
    { expr { [screen_is 1 0 [list "" "~"]] &&
	     ( $vim || [statusline_is "Interrupted"] ) } }

exp_send ":map! x axy\r"
exp_send "ax"
# The x should send it into a loop, appending content madly.
# POSIX says "If there is a currently executing command, it shall be aborted
# and a message displayed".
# and nvi shows "Interrupted: mapped keys discarded".

# Give it time to fill the screen with a's
sleep 1

# Interrupt it
exp_send $intr_ch
term_expect timeout { fail 70 } \
    { expr { $vim || [statusline_starts "Interrupted"] } }

# Now it should react to ":"
exp_send ":"
term_expect timeout { fail 71 } \
    { expr { [statusline_is ":"] && [cursor_at $rows 1] } }

stop_vi

exit 0
