@@ -4,14 +4,20 @@ package shell_integration
44
55import (
66 "archive/tar"
7+ "bytes"
78 "fmt"
9+ "kitty/tools/utils"
810 "os"
911 "path/filepath"
12+ "strings"
13+
14+ "golang.org/x/exp/maps"
15+ "golang.org/x/exp/slices"
1016)
1117
1218var _ = fmt .Print
1319
14- type integration_setup_func = func (argv []string , env map [string ]string ) ([]string , map [string ]string , error )
20+ type integration_setup_func = func (shell_integration_dir string , argv []string , env map [string ]string ) ([]string , map [string ]string , error )
1521
1622func extract_shell_integration_for (shell_name string , dest_dir string ) (err error ) {
1723 d := Data ()
@@ -32,23 +38,55 @@ func extract_shell_integration_for(shell_name string, dest_dir string) (err erro
3238 return
3339 }
3440 case tar .TypeReg :
35- if err = os .WriteFile (dest , entry .Data , 0o644 ); err != nil {
41+ if existing , rerr := os .ReadFile (dest ); rerr == nil && bytes .Equal (existing , entry .Data ) {
42+ continue
43+ }
44+ if err = utils .AtomicWriteFile (dest , entry .Data , 0o644 ); err != nil {
3645 return
3746 }
3847 }
3948 }
4049 return
4150}
4251
43- func zsh_setup_func (argv []string , env map [string ]string ) (final_argv []string , final_env map [string ]string , err error ) {
44- return
52+ func EnsureShellIntegrationFilesFor (shell_name string ) (shell_integration_dir string , err error ) {
53+ if kid := os .Getenv ("KITTY_INSTALLATION_DIR" ); kid != "" {
54+ if s , e := os .Stat (kid ); e == nil && s .IsDir () {
55+ q := filepath .Join (kid , "shell-integration" , shell_name )
56+ if s , e := os .Stat (q ); e == nil && s .IsDir () {
57+ return q , nil
58+ }
59+ }
60+ }
61+ base := filepath .Join (utils .CacheDir (), "extracted-ksi" )
62+ if err = os .MkdirAll (base , 0o755 ); err != nil {
63+ return "" , err
64+ }
65+ if err = extract_shell_integration_for (shell_name , base ); err != nil {
66+ return "" , err
67+ }
68+ return filepath .Join (base , "shell-integration" ), nil
4569}
4670
47- func fish_setup_func ( argv []string , env map [string ]string ) (final_argv []string , final_env map [string ]string , err error ) {
71+ func zsh_setup_func ( shell_integration_dir string , argv []string , env map [string ]string ) (final_argv []string , final_env map [string ]string , err error ) {
4872 return
4973}
5074
51- func bash_setup_func (argv []string , env map [string ]string ) (final_argv []string , final_env map [string ]string , err error ) {
75+ func fish_setup_func (shell_integration_dir string , argv []string , env map [string ]string ) (final_argv []string , final_env map [string ]string , err error ) {
76+ shell_integration_dir = filepath .Dir (shell_integration_dir )
77+ val := env [`XDG_DATA_DIRS` ]
78+ env [`KITTY_FISH_XDG_DATA_DIR` ] = shell_integration_dir
79+ if val == "" {
80+ env [`XDG_DATA_DIRS` ] = shell_integration_dir
81+ } else {
82+ dirs := utils .Filter (strings .Split (val , string (filepath .ListSeparator )), func (x string ) bool { return x != "" })
83+ dirs = append ([]string {shell_integration_dir }, dirs ... )
84+ env [`XDG_DATA_DIRS` ] = strings .Join (dirs , string (filepath .ListSeparator ))
85+ }
86+ return argv , env , nil
87+ }
88+
89+ func bash_setup_func (shell_integration_dir string , argv []string , env map [string ]string ) (final_argv []string , final_env map [string ]string , err error ) {
5290 return
5391}
5492
@@ -66,6 +104,14 @@ func setup_func_for_shell(shell_name string) integration_setup_func {
66104
67105func IsSupportedShell (shell_name string ) bool { return setup_func_for_shell (shell_name ) != nil }
68106
69- func Setup (shell_name string , argv []string , env map [string ]string ) ([]string , map [string ]string , error ) {
70- return setup_func_for_shell (shell_name )(argv , env )
107+ func Setup (shell_name string , ksi_var string , argv []string , env map [string ]string ) ([]string , map [string ]string , error ) {
108+ ksi_dir , err := EnsureShellIntegrationFilesFor (shell_name )
109+ if err != nil {
110+ return nil , nil , err
111+ }
112+ argv , env , err = setup_func_for_shell (shell_name )(ksi_dir , slices .Clone (argv ), maps .Clone (env ))
113+ if err == nil {
114+ env [`KITTY_SHELL_INTEGRATION` ] = ksi_var
115+ }
116+ return argv , env , err
71117}
0 commit comments