Home About Archive RSS

Bash from Git Bash in Shell mode in Emacs on Windows

Lately, I have been using PowerShell in Shell Mode in native Emacs on Windows. PowerShell isn't bad, especially not for automating tasks in Windows, but it's not the interactive shell I am used to. The small differences between PowerShell and Bash with GNU coreutils when it comes to day-to-day interactive use, even if many things are aliased to their Posix equivalents in PowerShell, are constant minor annoyances. For example, ls works in PowerShell since it is aliased to dir, but when I type ls -lah I get an error and realise I have to use dir \p since only the command without any flags are aliased. Since I use git from the command line and not vc-mode or magit (haven't had the time or energy to learn those yet), I use Shell mode enough that it is somewhat annoying to have to use PowerShell. It also feels foreign in GNU Emacs whereas GNU Bash doesn't.

I will of course use PowerShell when I demonstrate for instance git on the command line for my students since they would use PowerShell, but then I would use the blue PowerShell window and not Shell mode in Emacs. That also makes me more cognisant of the fact that I am not using Bash, but PowerShell. On Emacs on GNU/Linux, I am used to using Bash in Shell mode, so the muscle memory kicks in when I am in Shell mode even on Windows. I might even use PowerShell in a terminal in VSCode for demonstration purposes. But for my own use in Shell mode, a cosy and familiar Shell is better.

Today, I looked into switching to Bash from Git Bash. I am still trying to use Windows-native tools from MSYS2, chocholatey and win-get together with Windows-native Emacs since I need GUI Emacs for presentations in class when I use my laptop (I have a desktop with GNU/Linux in another classroom) and since WSLg's Wayland stack doesn't really work, especially not after locking the screen. If I just used Emacs to work on code, I could have used terminal Emacs with WSL2 which does work, but I need GUI Emacs for interactive presentations.

The solution is simple:

(use-package shell
  :config
  (add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)
  (add-to-list 'comint-output-filter-functions 'ansi-color-process-output)
  (add-hook 'comint-output-filter-functions 'comint-osc-process-output)
  (add-hook 'shell-mode-hook (lambda() (company-mode 0)))
  (when (eq system-type 'windows-nt)
    (setq explicit-shell-file-name "C:/Program Files/Git/bin/bash.exe")
    (setq explicit-bash.exe-args '("--login" "-i")))
  (when (eq system-type 'gnu/linux)
     (setq explicit-shell-file-name "/bin/bash")
     (setq system-uses-terminfo t)
     (setq comint-terminfo-terminal "xterm")))

The windows-specific part of the code above is the first when-statement where I say that when the system-type is equal to windows-nt, set the shell to the path to bash.exe from within the Git folder. I got the bash arguments to use from a SuperUser post online and haven't experimented with it since it works. The only slight annoyance is that I get a small complaint every time I launch the shell in the first two lines. I searched for solutions, but couldn't find any, so I guess I have to live with that. Otherwise, Bash from Git Bash works great in Shell mode and it feels good to have a familiar Shell even on Windows. Emacs is kind of my home away from home on Windows and with Bash in Shell mode, it feels even more like home than with PowerShell.

© Einar Mostad 2010 - 2025. Content is licensed under the terms of CC BY SA except code which is GNU GPL v3 or later.