Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using msys shell in Visual Studio Code

I'm getting into Visual Studio Code as I like its lightweight design and flexibility. It has an integrated terminal that can run, I believe, any shell [see here]. I'd like to use it run the msys shell that I've been using lately. Setting the terminal to run another shell other than the default powershell.exe should be as simple as changing the settings as described [here]. However, I use the msys shell by running the msys.bat file, as recommended on mingw.org.

So my question is, where is the .exe file I need to set the terminal to the msys shell? Or is running this shell without the .bat in this fashion impossible? Thanks!

like image 243
aNew Avatar asked Apr 09 '17 03:04

aNew


4 Answers

According to the msys.bat script, the actual executable that is launched depends on your TTY settings. The default setting uses the native command prompt and launches the sh.exe file as you can see from the following snippet:

:startsh
if NOT EXIST %WD%sh.exe goto notfound
start %WD%sh --login -i
exit

To get this to work in Visual Studio Code, you will need to add the following user settings:

"terminal.integrated.shell.windows": "C:\\MinGW\\msys\\1.0\\bin\\sh.exe",
"terminal.integrated.shellArgs.windows": ["--login", "-i"]

The path to the sh.exe file may be different depending on your install location for MSYS.

EDIT: (2019-01-20)

While the above still works for MSYS v1.0, I have since switched over to MSYS2 (https://www.msys2.org/). You can use the following settings to setup your Visual Studio Code to work with MSYS2 just as for v1.0 (once again, your install location might be different than mine):

"terminal.integrated.shell.windows": "C:\\msys64\\usr\\bin\\bash.exe",
"terminal.integrated.shellArgs.windows": ["--login", "-i"]

For extra-credit, we are going to modify an environment variable so that we always open the terminal in the current directory. There are various ways to accomplish this via scripting etc. However, the simplest way to do it, in my opinion, is to use the CHERE_INVOKING environment variable. By setting this flag to 1 it will inform the shell to use the current directory as the default entry point. Here is a complete tutorial on how to enable this flag:

  1. Press the windows key and type run and hit enter
  2. In the run dialog, type the following:

    rundll32.exe sysdm.cpl,EditEnvironmentVariables
    

    Run Dialog to open Environment Variables

  3. In the Environment Variables dialog that is opened, add a new user variable called CHERE_INVOKING and set it's value to 1.

    enter image description here

With this flag enabled in the Windows system, it should automatically open the terminal from the location where you called the bash.exe executable. For Visual Studio Code, this will be your root project directory. Enjoy!

like image 168
Jonny Morrill Avatar answered Sep 21 '22 20:09

Jonny Morrill


An extension to the previous answer:

To get it to open into your current working directory, for some reason it has to run it through a native shell first. We can use an incredibly intuitive PowerShell wrapper to set the cd and start bash or another shell.

Here's the config that got it working for me:

"terminal.integrated.shell.windows": "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
"terminal.integrated.shellArgs.windows": [
    "C:\\msys64\\usr\\bin\\sh.exe",
    "--login",
    "-i",
    "-c",
    "(\"cd \\`\"``cygpath '{0}'``\\`\"; /usr/bin/bash --login -i\" -f (Resolve-Path .).Path )"
],

You can replace bash with a different shell if you like, for example zsh.

Bash and JSON escapes use the \ character, but PowerShell uses ` instead, which bash would then attempt to use to execute a command, so be careful with all the escape characters.

Also, you have to specify the PowerShell binary, as opposed to the built-in "PowerShell" shell. I honestly have no idea why.

like image 39
Bryan K Avatar answered Sep 18 '22 20:09

Bryan K


To open MSys in the folder of your project, you just have to

A. Add the following setting in your personal settings of Visual Code (assuming your Msys folder is C:\msys\1.0):

"terminal.integrated.shell.windows": "C:\\msys\\1.0\\Run_MSYS.bat",

B. Copy getcp.exe in the bin folder of MSys (i.e. C:\msys\1.0\bin); you can find it here: https://github.com/msysgit/msysgit/blob/master/mingw/bin/getcp.exe

C. Create the file Run_MSYS.bat in your MSys folder as follows:

@rem Do not use "echo off" to not affect any child calls.
@SETLOCAL
@SETLOCAL ENABLEEXTENSIONS

:: Figure out where msys's root folder. If you want, you could just add the folder in the line
:: below.
@set MSYSROOT=
@if "x%MSYSROOT%"=="x" @if exist "%~dp0msys.bat" @set MSYSROOT=%~dp0
@if "x%MSYSROOT%"=="x" @if exist "%~dp0.msys-root" @set /P MSYSROOT=<%~dp0.msys-root
@if "x%MSYSROOT%"=="x" (
@echo Could not locate your mysys root folder.
@set /P MSYSROOT=Location:
)
:: Read as MSYSROOT.trim()
@if not "x%MSYSROOT%"=="x" (
@for /f "tokens=* delims= " %%a in ("%MSYSROOT%") do @set MSYSROOT=%%a
@for /f "useback tokens=*" %%a in ('%MSYSROOT%') do @set MSYSROOT=%%~a
@if not "%MSYSROOT:~-1%"=="\" @set MSYSROOT=%MSYSROOT%\
)
:: Verify that root folder exists
@if not exist "%MSYSROOT%" (
@echo "%MSYSROOT%" is not a valid folder. Please check for .msys-root in %~dp0, or if you entered the path above, please rerun this script and select a valid folder.
@exit /B 1
) else (
@if not "%MSYSROOT%"=="%~dp0" @echo %MSYSROOT%>%~dp0.msys-root
)

:: Home Folder
:: If you'd prefer the home directory set to your C:\Users\Username folder, uncomment the two lines
:: below.
@rem @if not exist "%HOME%" @set HOME=%HOMEDRIVE%%HOMEPATH%
@rem @if not exist "%HOME%" @set HOME=%USERPROFILE%
@if not exist "%HOME%" @if not "%MSYSROOT%"=="" @set HOME=%MSYSROOT%home\%USERNAME%
@if not "x%WD%"=="x" @set WD=
@set PLINK_PROTOCOL=ssh
@if not exist "%WD%msys-1.0.dll" @set WD=%MSYSROOT%\bin\
@set MSYSCON=sh.exe

:: Default action, open msys and go to the current folder.
@set OLDCD=%CD%
@if not "x%OLDCD%"=="x" @set CURRCD=%CD%
:: Get the current console ("OEM") codepage.
@for /f %%i in ('"%MSYSROOT%bin\getcp.exe" -oem') do @set cp_oem=%%i
:: Get the current GUI ("ANSI") codepage.
@for /f %%i in ('"%MSYSROOT%bin\getcp.exe" -ansi') do @set cp_ansi=%%i
:: Set the console codepage to match the GUI codepage.
@chcp %cp_ansi% > nul < nul
@if not "x%OLDCD%"=="x" (
@"%MSYSROOT%bin\bash.exe" -l -i -c "cd \"$CURRCD\"; exec /bin/bash -rcfile ~/.bash_profile"
) else (
@"%MSYSROOT%bin\bash.exe" -l
)
:: Store the error level returned by bash.
@set ErrorLevel=%ErrorLevel%
:: Restore the original console codepage.
@chcp %cp_oem% > nul < nul
:: If we had a current directory at the store of the script, go back to it.
@if not "x%OLDCD%"=="x" chdir /D "%OLDCD%"

:: quit script with the current error level.
@exit /b %ErrorLevel%

This is a shorter version of the script found (probably) here: https://gist.github.com/juntalis/1291621

Thank you Juntalis for the great script!!

Cheers

like image 43
Jean-Francois T. Avatar answered Sep 21 '22 20:09

Jean-Francois T.


according to MSYS terminals, we can use this:

    "terminal.integrated.profiles.windows": {
        "msys mingw64": {
            "path": "C:/msys64/msys2_shell.cmd",
            "args": [
                "-defterm",
                "-here",
                "-no-start",
                "-mingw64"
            ]
        }
    },

this starts msys mingw64. to start other shell, just change -mingw64 to -mingw32 or -msys.

like image 33
SodaCris Avatar answered Sep 20 '22 20:09

SodaCris