Fix shebang viewing of short scripts not working

This commit is contained in:
Kovid Goyal 2025-03-20 12:49:28 +05:30
parent f3448cbbee
commit 0afa6d5b3d
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
2 changed files with 38 additions and 2 deletions

View file

@ -16,6 +16,7 @@ import (
"kitty/kittens/ask"
"kitty/tools/cli"
"kitty/tools/cli/markup"
"kitty/tools/tty"
"kitty/tools/utils"
)
@ -39,6 +40,10 @@ func ask_for_permission(script_path string) (response string, err error) {
return response, err
}
func permission_denied(script_path string) error {
return fmt.Errorf("Execution of %s was denied by user", script_path)
}
func confirm_and_run_shebang(args []string, confirm_policy ConfirmPolicy) (rc int, err error) {
script_path := args[len(args)-1]
do_confirm := true
@ -57,14 +62,23 @@ func confirm_and_run_shebang(args []string, confirm_policy ConfirmPolicy) (rc in
}
switch response {
default:
return 1, fmt.Errorf("Execution of %s was denied by user", script_path)
return 1, permission_denied(script_path)
case "v":
raw, err := os.ReadFile(script_path)
if err != nil {
return 1, err
}
cli.ShowHelpInPager(utils.UnsafeBytesToString(raw))
return confirm_and_run_shebang(args, ConfirmIfNeeded)
// The pager might have exited automatically if there is less than
// one screen of text, so confirm manually, here, where output from
// pager will still be visible.
fmt.Print("Execute the script? (y/n): ")
q, err := tty.ReadSingleByteFromTerminal()
if q != 'y' && q != 'Y' {
fmt.Println()
return 1, permission_denied(script_path)
}
fmt.Print("\x1b[H\x1b[2J") // clear screen
case "e":
exe, err := os.Executable()
if err != nil {

View file

@ -78,6 +78,10 @@ func SetReadTimeout(d time.Duration) TermiosOperation {
var SetBlockingRead TermiosOperation = SetReadTimeout(0)
var SetNoCanonical TermiosOperation = func(t *unix.Termios) {
t.Lflag &^= unix.ICANON
}
var SetRaw TermiosOperation = func(t *unix.Termios) {
// This attempts to replicate the behaviour documented for cfmakeraw in
// the termios(3) manpage, as Go doesn't wrap cfmakeraw probably because its not in POSIX
@ -380,3 +384,21 @@ func DebugPrintln(a ...any) {
term.DebugPrintln(a...)
}
}
func ReadSingleByteFromTerminal() (b byte, err error) {
term, err := OpenControllingTerm(SetBlockingRead, SetNoCanonical)
if err != nil {
return 0, err
}
defer term.Close()
ans := []byte{b}
for {
n, err := term.Read(ans)
if err != nil {
return 0, err
}
if n > 0 {
return ans[0], nil
}
}
}