diff --git a/.gitignore b/.gitignore index 0e9e5ec53..9fa67af69 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ build/ Version v* *.bak config/user-* +config/aliases +config/profile.d diff --git a/README.md b/README.md index 2e42d2520..cdaa4d6c4 100644 --- a/README.md +++ b/README.md @@ -95,9 +95,19 @@ User specific configuration is possible using the cmder specific shell config fi Note: Bash and Mintty sessions will also source the '$HOME/.bashrc' file it it exists after it sources '$CMDER_ROOT/config/user-profile.sh'. +### Linux like 'profile.d' support for all supported shell types. +You can write *.cmd|*.bat, *.ps1, and *.sh scripts and just drop them in the %CMDER_ROOT%\config\profile.d folder to add startup config to Cmder. + +|Shell|Cmder 'Profile.d' Scripts| +| ------------- |:-------------:| +|Cmder|%CMDER_ROOT%\config\profile.d\\*.bat and *.cmd| +|Powershell|$ENV:CMDER_ROOT\config\profile.d\\*.ps1| +|Bash/Mintty|$CMDER_ROOT/config/profile.d/*.sh| + + ### Aliases #### Cmder(Cmd.exe) Aliases -You can define simple aliases for `cmd.exe` sessions with a command like `alias name=command`. Cmd.exe aliases support optional parameters through the `$1-9` or the `$*` special characters so the alias `vi=vim.exe $*` typed as `vi [filename]` will open `[filename]` in `vim.exe`. +You can define simple aliases for `cmd.exe` sessions with a command like `alias name=command`. Cmd.exe aliases support optional parameters through the `$1-9` or the `$*` special characters so the alias `vi=vim.exe $*` typed as `vi [filename]` will open `[filename]` in `vim.exe`. Cmd.exe aliases can also be more complex. See: [DOSKEY.EXE documentation](http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/doskey.mspx?mfr=true) for additional details on complex aliases/macros for 'cmd.exe' @@ -106,7 +116,7 @@ Aliases defined using the `alias.bat` command will automatically be saved in the #### Bash.exe|Mintty.exe Aliases Bash shells support simple and complex aliases with optional parameters natively so they work a little different. Typing `alias name=command` will create an alias only for the current running session. To make an alias permanent add it to either your `$CMDER_ROOT/config/user-profile.sh` or your `$HOME/.bashrc`. -If you add bash aliases to `$CMDER_ROOT/config/user-profile.sh` they will portable and follow your Cmder folder if you copy it to another machine. `$HOME/.bashrc` defined aliases are not portable. +If you add bash aliases to `$CMDER_ROOT/config/user-profile.sh` they will portable and follow your Cmder folder if you copy it to another machine. `$HOME/.bashrc` defined aliases are not portable. #### Powershell.exe Aliases Powershell has native simple alias support, for example `[new-alias | set-alias] alias command`, so complex aliases with optional parameters are not supported in Powershell sessions. Type `get-help [new-alias|set-alias] -full` for help on Powershell aliases. @@ -117,6 +127,31 @@ To start SSH agent simply call `start-ssh-agent`, which is in the `vendor/git-fo If you want to run SSH agent on startup, include the line `@call "%GIT_INSTALL_ROOT%/cmd/start-ssh-agent.cmd"` in `%CMDER_ROOT%/config/user-profile.cmd` (usually just uncomment it). +### Using external Cygwin/Babun, MSys2, or Git for Windows SDK with Cmder. + +1. Setup a new task by pressing 'Win +Alt + T' +1. Click the '+' button to add a task. +1. Name the new task in the top text box. +1. Provide task parameters, this is optional. +1. Add ```cmd /c "[path_to_external_env]\bin\bash --login -i" -new_console:d:%USERPROFILE%``` to the Commands text box. + +Recommended Optional Steps: + +Copy the 'vendor/cmder_exinit' file to the Cygwin/Babun, MSys2, or Git for Windows SDK environments ```/etc/profile.d/``` folder to use portable settings in the $CMDER_ROOT/config folder. + +Note: MinGW could work if the init scripts include profile.d but this has not been tested. + +The destination file extension depends on the shell you use in that environment. For example: + +* bash - Copy to /etc/profile.d/cmder_exinit.sh +* zsh - Copy to /etc/profile.d/cmder_exinit.zsh + +Uncomment and edit the below line in the script to use Cmder config even when launched from outside Cmder. + +``` +# CMDER_ROOT=${USERPROFILE}/cmder # This is not required if launched from Cmder. +``` + ## Todo 1. Check for clink and git before injecting them (Sort of done) diff --git a/config/Readme.md b/config/Readme.md index 1ed4f5113..15526c7bb 100644 --- a/config/Readme.md +++ b/config/Readme.md @@ -7,7 +7,7 @@ directly, it has to be hardlinked. `vendor\aliases.example`. * `*.lua`: clink completitions and prompt filters; called from vendor\cmder.lua after all other prompt filter and clink completitons are initialized; add your own. -* `user_profile.{sh|bat|ps1}: startup files for bash|cmd|powershell tasks; called from their +* `user_profile.{sh|bat|ps1}`: startup files for bash|cmd|powershell tasks; called from their respective startup scripts in `vendor\`; autocreated on first start of such a task * `.history`: the current commandline history; autoupdated on close * `settings`: settings for readline; overwritten on update diff --git a/launcher/src/CmderLauncher.cpp b/launcher/src/CmderLauncher.cpp index 4982fd08f..b2b0ffabb 100644 --- a/launcher/src/CmderLauncher.cpp +++ b/launcher/src/CmderLauncher.cpp @@ -3,7 +3,6 @@ #include #include "resource.h" #include -#include #pragma comment(lib, "Shlwapi.lib") @@ -156,16 +155,7 @@ void StartCmder(std::wstring path, bool is_single_mode) } SetEnvironmentVariable(L"CMDER_ROOT", exeDir); - if (streqi(path.c_str(), L"")) - { - wchar_t* homeProfile = 0; - SHGetKnownFolderPath(FOLDERID_Profile, 0, NULL, &homeProfile); - if (!SetEnvironmentVariable(L"CMDER_START", homeProfile)) { - MessageBox(NULL, _T("Error trying to set CMDER_START to given path!"), _T("Error"), MB_OK); - } - CoTaskMemFree(static_cast(homeProfile)); - } - else + if (!streqi(path.c_str(), L"")) { if (!SetEnvironmentVariable(L"CMDER_START", path.c_str())) { MessageBox(NULL, _T("Error trying to set CMDER_START to given path!"), _T("Error"), MB_OK); diff --git a/vendor/cmder.sh b/vendor/cmder.sh index 4d1da3ac0..4fac0becc 100644 --- a/vendor/cmder.sh +++ b/vendor/cmder.sh @@ -35,6 +35,26 @@ PATH=${CMDER_ROOT}/bin:$PATH:${CMDER_ROOT} export PATH +# Drop *.sh or *.zsh files into "${CMDER_ROOT}\config\profile.d" +# to source them at startup. +if [ ! -d "${CMDER_ROOT}/config/profile.d" ] ; then + mkdir -p ${CMDER_ROOT}/config/profile.d +fi + +if [ -d "${CMDER_ROOT}/config/profile.d" ] ; then + unset profile_d_scripts + pushd ${CMDER_ROOT}/config/profile.d >/dev/null + profile_d_scripts=$(ls ${CMDER_ROOT}/config/profile.d/*.sh 2>/dev/null) + + if [ ! "x${profile_d_scripts}" = "x" ] ; then + for x in ${profile_d_scripts} ; do + # echo Sourcing "${x}"... + . $x + done + fi + popd >/dev/null +fi + if [ -f ${CMDER_ROOT}/config/user-profile.sh ] ; then . ${CMDER_ROOT}/config/user-profile.sh else diff --git a/vendor/cmder_exinit b/vendor/cmder_exinit new file mode 100644 index 000000000..7e83d649d --- /dev/null +++ b/vendor/cmder_exinit @@ -0,0 +1,86 @@ +# Copy this file to your non integrated *nix-like environment, +# Cygwin/MSys2/Git for Windows SDK, installs '/etc/profile.d/' +# folder to integrate the externally installed Unix like environment +# into Cmder so it has access to settings stored in Cmder/config +# folder when launched. +# +# The destination file extension depends on the shell you use. For example: +# +# bash - Copy to /etc/profile.d/cmder_exinit.sh +# zsh - Copy to /etc/profile.d/cmder_exinit.zsh +# Add portable user customizations ${CMDER_ROOT}/config/user-profile.sh or +# add whole config scripts to ${CMDER_ROOT}/config/profile.d both will be sourced +# from mthis file and be appied to the environment at startup. +# +# These customizations will follow Cmder if $CMDER_ROOT is copied +# to another machine. +# +# Add system specific users customizations to $HOME/.bashrc, these +# customizations will not follow Cmder to another machine. + +# # Uncomment and edit the CMDER_ROOT line to use Cmder/config even when launched +# # from outside Cmder. +# CMDER_ROOT=${USERPROFILE}/cmder # This is not required if launched from Cmder. + +# Check that we haven't already been sourced. +[[ -z ${CMDER_EXINIT} ]] && CMDER_EXINIT="1" || return + +# We do this for bash as admin sessions since $CMDER_ROOT is not being set +if [ "$CMDER_ROOT" = "" -a "$ConEmuDir" != "" ] ; then + if [ -d "${ConEmuDir}../../vendor" ] ; then + case "$ConEmuDir" in *\\*) CMDER_ROOT=$( cd "$(cygpath -u "$ConEmuDir")/../.." ; pwd );; esac + else + echo "Running in ConEmu without Cmder, skipping Cmder integration." + fi +elif [ "$CMDER_ROOT" != "" ] ; then + case "$CMDER_ROOT" in *\\*) CMDER_ROOT="$(cygpath -u "$CMDER_ROOT")";; esac +fi + +if [ ! "$CMDER_ROOT" = "" ] ; then + # Remove any trailing '/' + CMDER_ROOT=$(echo $CMDER_ROOT | sed 's:/*$::') + + echo "Using \"CMDER_ROOT\" at \"${CMDER_ROOT}\"." + + export CMDER_ROOT + + PATH=${CMDER_ROOT}/bin:$PATH:${CMDER_ROOT} + + export PATH + + # Drop *.sh or *.zsh files into "${CMDER_ROOT}\config\profile.d" + # to source them at startup. + if [ ! -d "${CMDER_ROOT}/config/profile.d" ] ; then + mkdir -p ${CMDER_ROOT}/config/profile.d + fi + + if [ -d "${CMDER_ROOT}/config/profile.d" ] ; then + unset profile_d_scripts + pushd ${CMDER_ROOT}/config/profile.d >/dev/null + if [ ! "x${ZSH_VERSION}" = "x" ]; then + profile_d_scripts=$(ls ${CMDER_ROOT}/config/profile.d/*.zsh 2>/dev/null) + elif [ ! "x${BASH_VERSION}" = "x" ]; then + profile_d_scripts=$(ls ${CMDER_ROOT}/config/profile.d/*.sh 2>/dev/null) + fi + + if [ ! "x${profile_d_scripts}" = "x" ] ; then + for x in ${profile_d_scripts} ; do + # echo Sourcing "${x}"... + . $x + done + fi + popd >/dev/null + fi + + if [ -f ${CMDER_ROOT}/config/user-profile.sh ] ; then + . ${CMDER_ROOT}/config/user-profile.sh + else + echo Creating user startup file: "${CMDER_ROOT}/config/user-profile.sh" + cat <<-eof >"${CMDER_ROOT}/config/user-profile.sh" +# use this file to run your own startup commands for msys2 bash' + +# To add a new vendor to the path, do something like: +# export PATH=\${CMDER_ROOT}/vendor/whatever:\${PATH} +eof + fi +fi diff --git a/vendor/init.bat b/vendor/init.bat index 89e27c00d..4fc232c3f 100644 --- a/vendor/init.bat +++ b/vendor/init.bat @@ -1,3 +1,5 @@ +@echo off + :: Init Script for cmd.exe :: Created as part of cmder project @@ -5,41 +7,41 @@ :: !!! Use "%CMDER_ROOT%\config\user-profile.cmd" to add your own startup commands :: Find root dir -@if not defined CMDER_ROOT ( - for /f "delims=" %%i in ("%ConEmuDir%\..\..") do @set CMDER_ROOT=%%~fi +if not defined CMDER_ROOT ( + for /f "delims=" %%i in ("%ConEmuDir%\..\..") do set CMDER_ROOT=%%~fi ) :: Remove trailing '\' -@if "%CMDER_ROOT:~-1%" == "\" SET CMDER_ROOT=%CMDER_ROOT:~0,-1% +if "%CMDER_ROOT:~-1%" == "\" SET CMDER_ROOT=%CMDER_ROOT:~0,-1% :: Change the prompt style :: Mmm tasty lamb -@prompt $E[1;32;40m$P$S{git}{hg}$S$_$E[1;30;40m{lamb}$S$E[0m +prompt $E[1;32;40m$P$S{git}{hg}$S$_$E[1;30;40m{lamb}$S$E[0m :: Pick right version of clink -@if "%PROCESSOR_ARCHITECTURE%"=="x86" ( +if "%PROCESSOR_ARCHITECTURE%"=="x86" ( set architecture=86 ) else ( set architecture=64 ) :: Tell the user about the clink config files... -@if not exist "%CMDER_ROOT%\config\settings" ( +if not exist "%CMDER_ROOT%\config\settings" ( echo Generating clink initial settings in %CMDER_ROOT%\config\settings echo Additional *.lua files in %CMDER_ROOT%\config are loaded on startup. ) :: Run clink -@"%CMDER_ROOT%\vendor\clink\clink_x%architecture%.exe" inject --quiet --profile "%CMDER_ROOT%\config" --scripts "%CMDER_ROOT%\vendor" +"%CMDER_ROOT%\vendor\clink\clink_x%architecture%.exe" inject --quiet --profile "%CMDER_ROOT%\config" --scripts "%CMDER_ROOT%\vendor" :: Prepare for git-for-windows :: I do not even know, copypasted from their .bat -@set PLINK_PROTOCOL=ssh -@if not defined TERM set TERM=cygwin +set PLINK_PROTOCOL=ssh +if not defined TERM set TERM=cygwin :: Check if msysgit is installed -@if exist "%ProgramFiles%\Git" ( +if exist "%ProgramFiles%\Git" ( set "GIT_INSTALL_ROOT=%ProgramFiles%\Git" ) else if exist "%ProgramFiles(x86)%\Git" ( set "GIT_INSTALL_ROOT=%ProgramFiles(x86)%\Git" @@ -50,29 +52,41 @@ ) :: Add git to the path -@if defined GIT_INSTALL_ROOT ( +if defined GIT_INSTALL_ROOT ( set "PATH=%GIT_INSTALL_ROOT%\bin;%GIT_INSTALL_ROOT%\usr\bin;%GIT_INSTALL_ROOT%\usr\share\vim\vim74;%PATH%" :: define SVN_SSH so we can use git svn with ssh svn repositories if not defined SVN_SSH set "SVN_SSH=%GIT_INSTALL_ROOT:\=\\%\\bin\\ssh.exe" ) :: Enhance Path -@set "PATH=%CMDER_ROOT%\bin;%PATH%;%CMDER_ROOT%\" +set "PATH=%CMDER_ROOT%\bin;%PATH%;%CMDER_ROOT%\" + +:: Drop *.bat and *.cmd files into "%CMDER_ROOT%\config\profile.d" +:: to run them at startup. +if not exist "%CMDER_ROOT%\config\profile.d" ( + mkdir "%CMDER_ROOT%\config\profile.d" +) +pushd "%CMDER_ROOT%\config\profile.d" +for /f "usebackq" %%x in ( `dir /b *.bat *.cmd 2^>nul` ) do ( + REM echo Calling %CMDER_ROOT%\config\profile.d\%%x... + call "%CMDER_ROOT%\config\profile.d\%%x" +) +popd :: make sure we have an example file -@if not exist "%CMDER_ROOT%\config\aliases" ( +if not exist "%CMDER_ROOT%\config\aliases" ( echo Creating intial aliases in %CMDER_ROOT%\config\aliases copy "%CMDER_ROOT%\vendor\aliases.example" "%CMDER_ROOT%\config\aliases" > null ) :: Add aliases -@doskey /macrofile="%CMDER_ROOT%\config\aliases" +doskey /macrofile="%CMDER_ROOT%\config\aliases" :: See vendor\git-for-windows\README.portable for why we do this :: Basically we need to execute this post-install.bat because we are :: manually extracting the archive rather than executing the 7z sfx -@if exist "%CMDER_ROOT%\vendor\git-for-windows\post-install.bat" ( +if exist "%CMDER_ROOT%\vendor\git-for-windows\post-install.bat" ( echo Running Git for Windows one time Post Install.... cd /d "%CMDER_ROOT%\vendor\git-for-windows\" "%CMDER_ROOT%\vendor\git-for-windows\git-bash.exe" --no-needs-console --hide --no-cd --command=post-install.bat @@ -80,25 +94,25 @@ ) :: Set home path -@if not defined HOME set HOME=%USERPROFILE% +if not defined HOME set HOME=%USERPROFILE% :: This is either a env variable set by the user or the result of :: cmder.exe setting this variable due to a commandline argument or a "cmder here" -@if defined CMDER_START ( - @cd /d "%CMDER_START%" +if defined CMDER_START ( + cd /d "%CMDER_START%" ) -@if exist "%CMDER_ROOT%\config\user-profile.cmd" ( - @rem create this file and place your own command in there +if exist "%CMDER_ROOT%\config\user-profile.cmd" ( + rem create this file and place your own command in there call "%CMDER_ROOT%\config\user-profile.cmd" ) else ( - @echo Creating user startup file: "%CMDER_ROOT%\config\user-profile.cmd" + echo Creating user startup file: "%CMDER_ROOT%\config\user-profile.cmd" ( - @echo :: use this file to run your own startup commands - @echo :: use @ in front of the command to prevent printing the command - @echo. - @echo :: @call "%%GIT_INSTALL_ROOT%%/cmd/start-ssh-agent.cmd - @echo :: @set PATH=%%CMDER_ROOT%%\vendor\whatever;%%PATH%% - @echo. + echo :: use this file to run your own startup commands + echo :: use in front of the command to prevent printing the command + echo. + echo :: call "%%GIT_INSTALL_ROOT%%/cmd/start-ssh-agent.cmd + echo :: set PATH=%%CMDER_ROOT%%\vendor\whatever;%%PATH%% + echo. ) > "%CMDER_ROOT%\config\user-profile.cmd" ) diff --git a/vendor/profile.ps1 b/vendor/profile.ps1 index 5713f761c..0d830f568 100644 --- a/vendor/profile.ps1 +++ b/vendor/profile.ps1 @@ -88,9 +88,26 @@ if ( $ENV:CMDER_START ) { Set-Location -Path "$ENV:CMDER_START" } +if (Get-Module PSReadline -ErrorAction "SilentlyContinue") { + Set-PSReadlineOption -ExtraPromptLineCount 1 +} + # Enhance Path $env:Path = "$Env:CMDER_ROOT\bin;$env:Path;$Env:CMDER_ROOT" +# Drop *.ps1 files into "$ENV:CMDER_ROOT\config\profile.d" +# to source them at startup. +if (-not (test-path "$ENV:CMDER_ROOT\config\profile.d")) { + mkdir "$ENV:CMDER_ROOT\config\profile.d" +} + +pushd $ENV:CMDER_ROOT\config\profile.d +foreach ($x in ls *.ps1) { + # write-host write-host Sourcing $x + . $x +} +popd + $CmderUserProfilePath = Join-Path $env:CMDER_ROOT "config\user-profile.ps1" if(Test-Path $CmderUserProfilePath) { # Create this file and place your own command in there. diff --git a/vendor/sources.json b/vendor/sources.json index e592752ff..3a63b22a0 100644 --- a/vendor/sources.json +++ b/vendor/sources.json @@ -1,8 +1,8 @@ [ { "name": "git-for-windows", - "version": "v2.7.1.windows.1", - "url": "https://github.com/git-for-windows/git/releases/download/v2.7.1.windows.1/PortableGit-2.7.1-32-bit.7z.exe" + "version": "v2.7.4.windows.1", + "url": "https://github.com/git-for-windows/git/releases/download/v2.7.4.windows.1/PortableGit-2.7.4-32-bit.7z.exe" }, { "name": "clink",