diff --git a/tools/cmd/run_shell/main.go b/tools/cmd/run_shell/main.go index 6efddc75a..62288e242 100644 --- a/tools/cmd/run_shell/main.go +++ b/tools/cmd/run_shell/main.go @@ -47,8 +47,9 @@ func EntryPoint(root *cli.Command) *cli.Command { Help: "Specify a value for the shell_integration option, overriding the one from kitty.conf.", }) sc.Add(cli.OptionSpec{ - Name: "--shell", - Help: "Specify the shell command to run. If not specified the value of the shell option from kitty.conf is used.", + Name: "--shell", + Default: ".", + Help: "Specify the shell command to run. The default value of :code:`.` will use the parent shell if recognized, falling back to the value of the :code:`shell` option from kitty.conf.", }) return sc } diff --git a/tools/tui/run.go b/tools/tui/run.go index 41ae2c642..3640c7c0d 100644 --- a/tools/tui/run.go +++ b/tools/tui/run.go @@ -11,6 +11,7 @@ import ( "runtime" "strings" + "github.com/shirou/gopsutil/v3/process" "golang.org/x/sys/unix" "kitty/tools/config" @@ -63,18 +64,49 @@ var relevant_kitty_opts = utils.Once(func() KittyOpts { return read_relevant_kitty_opts(filepath.Join(utils.ConfigDir(), "kitty.conf")) }) -func ResolveShell(shell string) []string { - if shell == "" { - shell = relevant_kitty_opts().Shell - if shell == "." { - s, e := utils.LoginShellForCurrentUser() - if e != nil { - shell = "/bin/sh" - } else { - shell = s +func get_shell_from_kitty_conf() (shell string) { + shell = relevant_kitty_opts().Shell + if shell == "." { + s, e := utils.LoginShellForCurrentUser() + if e != nil { + shell = "/bin/sh" + } else { + shell = s + } + } + return +} + +func find_shell_parent_process() string { + var p *process.Process + var err error + for { + if p == nil { + p, err = process.NewProcess(int32(os.Getppid())) + } else { + p, err = p.Parent() + } + if err != nil { + return "" + } + if cmdline, err := p.CmdlineSlice(); err == nil && len(cmdline) > 0 { + exe := get_shell_name(filepath.Base(cmdline[0])) + if shell_integration.IsSupportedShell(exe) { + return exe } } } +} + +func ResolveShell(shell string) []string { + switch shell { + case "": + shell = get_shell_from_kitty_conf() + case ".": + if shell = find_shell_parent_process(); shell == "" { + shell = get_shell_from_kitty_conf() + } + } shell_cmd, err := shlex.Split(shell) if err != nil { shell_cmd = []string{shell}