@@ -142,8 +142,97 @@ func fish_setup_func(shell_integration_dir string, argv []string, env map[string
142142 return argv , env , nil
143143}
144144
145- func bash_setup_func (shell_integration_dir string , argv []string , env map [string ]string ) (final_argv []string , final_env map [string ]string , err error ) {
146- return
145+ func bash_setup_func (shell_integration_dir string , argv []string , env map [string ]string ) ([]string , map [string ]string , error ) {
146+ inject := utils .NewSetWithItems (`1` )
147+ var posix_env , rcfile string
148+ remove_args := utils.NewSet [int ](8 )
149+ expecting_multi_chars_opt := true
150+ var expecting_option_arg , interactive_opt , expecting_file_arg , file_arg_set bool
151+
152+ for i := 1 ; i < len (argv ); i ++ {
153+ arg := argv [i ]
154+ if expecting_file_arg {
155+ file_arg_set = true
156+ break
157+ }
158+ if expecting_option_arg {
159+ expecting_option_arg = false
160+ continue
161+ }
162+ if arg == `-` || arg == `--` {
163+ if ! expecting_file_arg {
164+ expecting_file_arg = true
165+ }
166+ continue
167+ } else if len (arg ) > 1 && arg [1 ] != '-' && (arg [0 ] == '-' || strings .HasPrefix (arg , `+O` )) {
168+ expecting_multi_chars_opt = false
169+ options := strings .TrimLeft (arg , `-+` )
170+ // shopt option
171+ if a , b , found := strings .Cut (options , `O` ); found {
172+ if b == "" {
173+ expecting_option_arg = true
174+ }
175+ options = a
176+ }
177+ // command string
178+ if strings .ContainsRune (options , 'c' ) {
179+ // non-interactive shell
180+ // also skip `bash -ic` interactive mode with command string
181+ return argv , env , nil
182+ }
183+ // read from stdin and follow with args
184+ if strings .ContainsRune (options , 's' ) {
185+ break
186+ }
187+ // interactive option
188+ if strings .ContainsRune (options , 'i' ) {
189+ interactive_opt = true
190+ }
191+ } else if strings .HasPrefix (arg , `--` ) && expecting_multi_chars_opt {
192+ if arg == `--posix` {
193+ inject .Add (`posix` )
194+ posix_env = env [`ENV` ]
195+ remove_args .Add (i )
196+ } else if arg == `--norc` {
197+ inject .Add (`no-rc` )
198+ remove_args .Add (i )
199+ } else if arg == `--noprofile` {
200+ inject .Add (`no-profile` )
201+ remove_args .Add (i )
202+ } else if (arg == `--rcfile` || arg == `--init-file` ) && i + 1 < len (argv ) {
203+ expecting_option_arg = true
204+ rcfile = argv [i + 1 ]
205+ remove_args .AddItems (i , i + 1 )
206+ }
207+ } else {
208+ file_arg_set = true
209+ break
210+ }
211+ }
212+ if file_arg_set && ! interactive_opt {
213+ // non-interactive shell
214+ return argv , env , nil
215+ }
216+ env [`ENV` ] = filepath .Join (shell_integration_dir , `kitty.bash` )
217+ env [`KITTY_BASH_INJECT` ] = strings .Join (inject .AsSlice (), " " )
218+ if posix_env != "" {
219+ env [`KITTY_BASH_POSIX_ENV` ] = posix_env
220+ }
221+ if rcfile != "" {
222+ env [`KITTY_BASH_RCFILE` ] = rcfile
223+ }
224+ sorted := remove_args .AsSlice ()
225+ slices .Sort (sorted )
226+ for _ , i := range utils .Reverse (sorted ) {
227+ slices .Delete (argv , i , i + 1 )
228+ }
229+ if env [`HISTFILE` ] == "" && ! inject .Has (`posix` ) {
230+ // In POSIX mode the default history file is ~/.sh_history instead of ~/.bash_history
231+ env [`HISTFILE` ] = utils .Expanduser (`~/.bash_history` )
232+ env [`KITTY_BASH_UNEXPORT_HISTFILE` ] = `1`
233+ }
234+ argv = slices .Insert (argv , 1 , `--posix` )
235+ return argv , env , nil
147236}
148237
149238func setup_func_for_shell (shell_name string ) integration_setup_func {
0 commit comments