From 90d86a7e5e471311675354088518820a24e6b5c3 Mon Sep 17 00:00:00 2001 From: "Dax T. Games" Date: Mon, 6 Nov 2023 09:55:49 -0500 Subject: [PATCH 01/84] add vendor/bin/create-cmdercfg.cmd --- vendor/bin/create-cmdercfg.cmd | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 vendor/bin/create-cmdercfg.cmd diff --git a/vendor/bin/create-cmdercfg.cmd b/vendor/bin/create-cmdercfg.cmd new file mode 100644 index 0000000..cc8c711 --- /dev/null +++ b/vendor/bin/create-cmdercfg.cmd @@ -0,0 +1,3 @@ +@echo off + +powershell -executionpolicy bypass -f "%cmder_root%\vendor\bin\create-cmdercfg.ps1" -shell cmd -outfile "%CMDER_CONFIG_DIR%\user_init.cmd" From 41195ad8dd02a8a85b4f282372de14041ab9e39b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 15:58:11 +0000 Subject: [PATCH 02/84] Bump peter-evans/create-pull-request from 6 to 7 Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 6 to 7. - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](https://github.com/peter-evans/create-pull-request/compare/v6...v7) --- updated-dependencies: - dependency-name: peter-evans/create-pull-request dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/vendor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/vendor.yml b/.github/workflows/vendor.yml index f237626..a9d3e17 100644 --- a/.github/workflows/vendor.yml +++ b/.github/workflows/vendor.yml @@ -51,7 +51,7 @@ jobs: Set-GHVariable -Name LIST_UPDATED -Value $listUpdated.Trim(', ') echo "UPDATE_MESSAGE<< 0 with: title: 'Updates to `${{ env.COUNT_UPDATED }}` vendored dependencies' From 0c2e5ce1f2379e4bef10845ca1191c1bf96a03b3 Mon Sep 17 00:00:00 2001 From: "Dax T. Games" Date: Sun, 5 Jan 2025 19:28:51 -0500 Subject: [PATCH 03/84] CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b22a19..160f91a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## Unreleased + +### Adds + +- Cmder for Windows + - Cmder for Windows uses Windows Native Terminals and does not contain ConEmu. + ## [1.3.20](https://github.com/cmderdev/cmder/tree/v1.3.20) (2022-03-18) ### Changes From e0aa20a080fd43ab66d87f8b9d739e60de129892 Mon Sep 17 00:00:00 2001 From: "Dax T. Games" Date: Sun, 5 Jan 2025 19:38:45 -0500 Subject: [PATCH 04/84] CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 160f91a..7bf89cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,8 @@ ### Adds - Cmder for Windows - - Cmder for Windows uses Windows Native Terminals and does not contain ConEmu. + - Uses Windows and Git for Windows Native Terminals. + - Does not contain a terminal emulator like COnEmu or Windows Terminal.. ## [1.3.20](https://github.com/cmderdev/cmder/tree/v1.3.20) (2022-03-18) From 06349694f03d88c3b72201fd96784052305be871 Mon Sep 17 00:00:00 2001 From: "Dax T. Games" Date: Sun, 5 Jan 2025 19:46:59 -0500 Subject: [PATCH 05/84] CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b22a19..6962c14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## Unreleased + +### Fixes + +- Fixes [[Bug] development builds cmder.exe always overwrites the terminal emulator settings files.](#2940) + ## [1.3.20](https://github.com/cmderdev/cmder/tree/v1.3.20) (2022-03-18) ### Changes From b4120362621feaf37b786388a3a3a7065dfa35ea Mon Sep 17 00:00:00 2001 From: "Dax T. Games" Date: Sun, 5 Jan 2025 19:52:28 -0500 Subject: [PATCH 06/84] CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6962c14..c8fd4ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ### Fixes -- Fixes [[Bug] development builds cmder.exe always overwrites the terminal emulator settings files.](#2940) +- Fixes #2940 ## [1.3.20](https://github.com/cmderdev/cmder/tree/v1.3.20) (2022-03-18) From d349f57e78f09cbfbe7be168879d1900e3038cd2 Mon Sep 17 00:00:00 2001 From: "Dax T. Games" Date: Sun, 5 Jan 2025 20:19:40 -0500 Subject: [PATCH 07/84] add executionpolicy bypass --- vendor/init.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/init.bat b/vendor/init.bat index fafb0ee..a010ba9 100644 --- a/vendor/init.bat +++ b/vendor/init.bat @@ -540,7 +540,7 @@ if "%CMDER_ALIASES%" == "1" if exist "%CMDER_ROOT%\bin\alias.bat" if exist "%CMD set initialConfig= if not exist "%CMDER_CONFIG_DIR%\user_init.cmd" ( - powershell -f "%cmder_root%\vendor\bin\create-cmdercfg.ps1" -shell cmd -outfile "%CMDER_CONFIG_DIR%\user_init.cmd" + powershell -executionpolicy bypass -f "%cmder_root%\vendor\bin\create-cmdercfg.ps1" -shell cmd -outfile "%CMDER_CONFIG_DIR%\user_init.cmd" if not exist "%CMDER_ROOT%\config\user_init.cmd" ( %print_error% "Failed to generate Cmder config" From 8683dad1118204ae4817cddf617c783ec7a08336 Mon Sep 17 00:00:00 2001 From: "Dax T. Games" Date: Sun, 5 Jan 2025 22:07:27 -0500 Subject: [PATCH 08/84] Remove /a switch and associated code. --- launcher/CmderLauncher.vcxproj | 3 ++ launcher/src/CmderLauncher.cpp | 63 ++++++------------------ launcher/src/resource.rc | 89 ++++++++++++++++++++-------------- 3 files changed, 70 insertions(+), 85 deletions(-) diff --git a/launcher/CmderLauncher.vcxproj b/launcher/CmderLauncher.vcxproj index 2662957..6d49ed9 100644 --- a/launcher/CmderLauncher.vcxproj +++ b/launcher/CmderLauncher.vcxproj @@ -188,6 +188,9 @@ + + + diff --git a/launcher/src/CmderLauncher.cpp b/launcher/src/CmderLauncher.cpp index 7f505e1..76e2243 100644 --- a/launcher/src/CmderLauncher.cpp +++ b/launcher/src/CmderLauncher.cpp @@ -105,11 +105,11 @@ bool FileExists(const wchar_t * filePath) return false; } -void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstring taskName = L"", std::wstring title = L"", std::wstring iconPath = L"", std::wstring cfgRoot = L"", bool use_user_cfg = true, std::wstring conemu_args = L"", bool admin = false) +void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstring taskName = L"", std::wstring title = L"", std::wstring iconPath = L"", std::wstring cfgRoot = L"", bool use_user_cfg = true, std::wstring conemu_args = L"") { -#if USE_TASKBAR_API - wchar_t appId[MAX_PATH] = { 0 }; -#endif + #if USE_TASKBAR_API + wchar_t appId[MAX_PATH] = { 0 }; + #endif wchar_t exeDir[MAX_PATH] = { 0 }; wchar_t icoPath[MAX_PATH] = { 0 }; wchar_t cfgPath[MAX_PATH] = { 0 }; @@ -153,9 +153,9 @@ void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstr GetModuleFileName(NULL, exeDir, sizeof(exeDir)); -#if USE_TASKBAR_API - wcscpy_s(appId, exeDir); -#endif + #if USE_TASKBAR_API + wcscpy_s(appId, exeDir); + #endif PathRemoveFileSpec(exeDir); @@ -651,44 +651,13 @@ void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstr STARTUPINFO si = { 0 }; si.cb = sizeof(STARTUPINFO); -#if USE_TASKBAR_API - si.lpTitle = appId; - si.dwFlags = STARTF_TITLEISAPPID; -#endif + #if USE_TASKBAR_API + si.lpTitle = appId; + si.dwFlags = STARTF_TITLEISAPPID; + #endif PROCESS_INFORMATION pi; - // MessageBox(NULL, terminalPath, _T("Error"), MB_OK); - // MessageBox(NULL, args, _T("Error"), MB_OK); - // Let's try to rerun as Administrator - SHELLEXECUTEINFO sei = { sizeof(sei) }; - sei.fMask = SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS; - sei.lpVerb = L"runas"; - sei.lpFile = terminalPath; - sei.lpParameters = args; - sei.nShow = SW_SHOWNORMAL; - - if (admin && ShellExecuteEx(&sei)) - { - if (!sei.hProcess) - { - Sleep(500); - _ASSERTE(sei.hProcess != nullptr); - } - - if (sei.hProcess) - { - WaitForSingleObject(sei.hProcess, INFINITE); - } - - // int nZone = 0; - // if (!HasZoneIdentifier(lsFile, nZone) - // || (nZone != 0 /*LocalComputer*/)) - // { - // // Assuming that elevated copy has fixed all zone problems - // break; - // } - } - else if (!CreateProcess(terminalPath, args, NULL, NULL, false, 0, NULL, NULL, &si, &pi)) + if (!CreateProcess(terminalPath, args, NULL, NULL, false, 0, NULL, NULL, &si, &pi)) { if (PathFileExists(windowsTerminalDir)) { @@ -819,7 +788,6 @@ struct cmderOptions std::wstring cmderIcon = L""; std::wstring cmderRegScope = L"USER"; std::wstring cmderTerminalArgs = L""; - bool cmderAdmin = false; bool cmderSingle = false; bool cmderUserCfg = true; bool registerApp = false; @@ -908,10 +876,6 @@ cmderOptions GetOption() { cmderOptions.cmderUserCfg = false; } - else if (_wcsicmp(L"/a", szArgList[i]) == 0 && !PathFileExists(windowsTerminalDir) && !PathFileExists(conEmuDir)) - { - cmderOptions.cmderAdmin = true; - } else if (_wcsicmp(L"/register", szArgList[i]) == 0) { cmderOptions.registerApp = true; @@ -1048,7 +1012,8 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, } else { - StartCmder(cmderOptions.cmderStart, cmderOptions.cmderSingle, cmderOptions.cmderTask, cmderOptions.cmderTitle, cmderOptions.cmderIcon, cmderOptions.cmderCfgRoot, cmderOptions.cmderUserCfg, cmderOptions.cmderTerminalArgs, cmderOptions.cmderAdmin); } + StartCmder(cmderOptions.cmderStart, cmderOptions.cmderSingle, cmderOptions.cmderTask, cmderOptions.cmderTitle, cmderOptions.cmderIcon, cmderOptions.cmderCfgRoot, cmderOptions.cmderUserCfg, cmderOptions.cmderTerminalArgs); + } return 0; } \ No newline at end of file diff --git a/launcher/src/resource.rc b/launcher/src/resource.rc index 5960625..3d7b4f7 100644 --- a/launcher/src/resource.rc +++ b/launcher/src/resource.rc @@ -1,15 +1,6 @@ -/* _ - ___ _ __ ___ __| | ___ _ __ - / __| '_ ` _ \ / _` |/ _ \ '__| -| (__| | | | | | (_| | __/ | - \___|_| |_| |_|\__,_|\___|_| -============================================================================= - The Cmder Console Emulator Project -*/ - +// Microsoft Visual C++ generated resource script. +// #include "resource.h" -#include "version.rc2" -#include "strings.rc2" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// @@ -26,6 +17,7 @@ #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// @@ -33,25 +25,26 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // TEXTINCLUDE // -1 TEXTINCLUDE +1 TEXTINCLUDE BEGIN -"resource.h\0" + "resource.h\0" END -2 TEXTINCLUDE +2 TEXTINCLUDE BEGIN -"#include ""winres.h""\r\n" -"\0" + "#include ""winres.h""\r\n" + "\0" END -3 TEXTINCLUDE +3 TEXTINCLUDE BEGIN -"\r\n" -"\0" + "\r\n" + "\0" END #endif // APSTUDIO_INVOKED + ///////////////////////////////////////////////////////////////////////////// // // Icon @@ -60,8 +53,7 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDI_CMDER ICON "..\\..\\icons\\cmder.ico" -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////// // @@ -69,26 +61,30 @@ IDI_CMDER ICON "..\\..\\icons\\cmder.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION CMDER_MAJOR_VERSION,CMDER_MINOR_VERSION,CMDER_REVISION_VERSION,CMDER_BUILD_VERSION - PRODUCTVERSION CMDER_MAJOR_VERSION,CMDER_MINOR_VERSION,CMDER_REVISION_VERSION,CMDER_BUILD_VERSION - FILEFLAGSMASK VS_FFI_FILEFLAGSMASK - FILEFLAGS (CMDER_DEBUGFLAG | CMDER_BUILDFLAGS) - FILEOS VOS_NT_WINDOWS32 - FILETYPE VFT_APP - FILESUBTYPE VFT2_UNKNOWN + FILEVERSION 1,3,6,1 + PRODUCTVERSION 1,3,6,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "100904b0" BEGIN - VALUE "CompanyName", CMDER_COMPANY_NAME_STR "\0" - VALUE "FileDescription", CMDER_FILE_DESCRIPTION_STR "\0" - VALUE "FileVersion", CMDER_VERSION_STR "\0" - VALUE "InternalName", CMDER_INTERNAL_NAME_STR "\0" - VALUE "LegalCopyright", "Copyright (C) " CMDER_COPYRIGHT_YEAR_STR " " CMDER_COMPANY_NAME_STR "\0" - VALUE "OriginalFilename", CMDER_ORIGINAL_FILENAME_STR "\0" - VALUE "ProductName", CMDER_PRODUCT_NAME_STR "\0" - VALUE "ProductVersion", CMDER_VERSION_STR "\0" + VALUE "CompanyName", "Samuel Vasko" + VALUE "FileDescription", "Cmder: Lovely Console Emulator." + VALUE "FileVersion", "1.3.6-pre1" + VALUE "InternalName", "Cmder" + VALUE "LegalCopyright", "Copyright (C) 2016 Samuel Vasko" + VALUE "OriginalFilename", "Cmder.exe" + VALUE "ProductName", "Cmder" + VALUE "ProductVersion", "1.3.6-pre1" END END BLOCK "VarFileInfo" @@ -97,7 +93,26 @@ BEGIN END END + ///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_TITLE "Cmder Launcher" +END + +STRINGTABLE +BEGIN + IDS_SWITCHES "Valid options:\n\n /c [CMDER User Root Path]\n /task [Windows Terminal Profile/ConEmu Task Name]\n /icon [CMDER Icon Path] - ConEmu ONLY!\n [/start [Start in Path] | [Start in Path]]\n /single - ConEmu ONLY!\n /m\n -- [ConEmu/Windows Terminal extra arguments]\n\nNote: '-- [...]' must be the last argument!\n\nor, either:\n /register [USER | ALL]\n /unregister [USER | ALL]" +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// @@ -105,5 +120,7 @@ END // Generated from the TEXTINCLUDE 3 resource. // + ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED + From 1737bcdeb752923348c2bf5a96dbaf3721e20eff Mon Sep 17 00:00:00 2001 From: DRSDavidSoft <4673812+DRSDavidSoft@users.noreply.github.com> Date: Thu, 3 Apr 2025 13:43:06 +0000 Subject: [PATCH 09/84] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Update=20dependencie?= =?UTF-8?q?s=20(git-for-windows=20v2.49.0.windows.1,=20clink=20v1.7.14,=20?= =?UTF-8?q?clink-completions=20v0.6.2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vendor/sources.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/vendor/sources.json b/vendor/sources.json index 1926359..b155781 100644 --- a/vendor/sources.json +++ b/vendor/sources.json @@ -1,13 +1,13 @@ [ { "name": "git-for-windows", - "version": "2.47.0.windows.1", - "url": "https://github.com/git-for-windows/git/releases/download/v2.47.0.windows.1/PortableGit-2.47.0-64-bit.7z.exe" + "version": "2.49.0.windows.1", + "url": "https://github.com/git-for-windows/git/releases/download/v2.49.0.windows.1/PortableGit-2.49.0-64-bit.7z.exe" }, { "name": "clink", - "version": "1.7.3", - "url": "https://github.com/chrisant996/clink/releases/download/v1.7.3/clink.1.7.3.f8fb96.zip" + "version": "1.7.14", + "url": "https://github.com/chrisant996/clink/releases/download/v1.7.14/clink.1.7.14.843933.zip" }, { "name": "conemu-maximus5", @@ -16,7 +16,7 @@ }, { "name": "clink-completions", - "version": "0.6.0", - "url": "https://github.com/vladimir-kotikov/clink-completions/archive/v0.6.0.zip" + "version": "0.6.2", + "url": "https://github.com/vladimir-kotikov/clink-completions/archive/v0.6.2.zip" } ] From 6d82cf897ba7ed0816fec47de06596786e3a8ab5 Mon Sep 17 00:00:00 2001 From: "Dax T. Games" Date: Thu, 3 Apr 2025 20:34:34 +0000 Subject: [PATCH 10/84] fix build script --- scripts/build.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index f577fa1..9d484d3 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -129,8 +129,9 @@ if (-not $noVendor) { else { $WinTermSettingsJson = "" } # Kill ssh-agent.exe if it is running from the $env:cmder_root we are building + $cmder_folder = $cmder_root.toString() foreach ($ssh_agent in $(Get-Process ssh-agent -ErrorAction SilentlyContinue)) { - if ([string]$($ssh_agent.path) -Match [string]$cmder_root.replace('\', '\\')) { + if ([string]$($ssh_agent.path) -Match $cmder_folder.Replace('\', '\\')) { Write-Verbose $("Stopping " + $ssh_agent.path + "!") Stop-Process $ssh_agent.id } From a44b30c3eb4e5bedabe442784ea326762eeaabf3 Mon Sep 17 00:00:00 2001 From: Dax T Games Date: Thu, 3 Apr 2025 17:17:01 -0400 Subject: [PATCH 11/84] Update build.yml --- .github/workflows/build.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8fb9368..144e31c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -53,41 +53,41 @@ jobs: run: .\pack.ps1 -verbose -terminal all - name: Upload artifact (cmder_win_mini.zip) - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: path: build/cmder_win_mini.zip name: cmder_win_mini.zip if-no-files-found: error - name: Upload artifact (cmder_win.7z) - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: path: build/cmder_win.7z name: cmder_win.7z if-no-files-found: error - name: Upload artifact (cmder_win.zip) - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: path: build/cmder_win.zip name: cmder_win.zip if-no-files-found: error - name: Upload artifact (cmder_wt.zip) - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: path: build/cmder_wt.zip name: cmder_wt.zip if-no-files-found: error - name: Upload artifact (cmder_wt.7z) - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: path: build/cmder_wt.7z name: cmder_wt.7z - name: Upload artifact (cmder_wt_mini.zip) - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: path: build/cmder_wt_mini.zip name: cmder_wt_mini.zip From 2868f9ee92718fc300abc0230b03f4ed6aada221 Mon Sep 17 00:00:00 2001 From: "Dax T. Games" Date: Tue, 8 Apr 2025 12:11:37 -0400 Subject: [PATCH 12/84] revert inadvertent changes --- launcher/src/resource.rc | 89 ++++++++++++++++------------------------ launcher/src/strings.rc2 | 2 +- 2 files changed, 37 insertions(+), 54 deletions(-) diff --git a/launcher/src/resource.rc b/launcher/src/resource.rc index 3d7b4f7..5960625 100644 --- a/launcher/src/resource.rc +++ b/launcher/src/resource.rc @@ -1,6 +1,15 @@ -// Microsoft Visual C++ generated resource script. -// +/* _ + ___ _ __ ___ __| | ___ _ __ + / __| '_ ` _ \ / _` |/ _ \ '__| +| (__| | | | | | (_| | __/ | + \___|_| |_| |_|\__,_|\___|_| +============================================================================= + The Cmder Console Emulator Project +*/ + #include "resource.h" +#include "version.rc2" +#include "strings.rc2" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// @@ -17,7 +26,6 @@ #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// @@ -25,26 +33,25 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // TEXTINCLUDE // -1 TEXTINCLUDE +1 TEXTINCLUDE BEGIN - "resource.h\0" +"resource.h\0" END -2 TEXTINCLUDE +2 TEXTINCLUDE BEGIN - "#include ""winres.h""\r\n" - "\0" +"#include ""winres.h""\r\n" +"\0" END -3 TEXTINCLUDE +3 TEXTINCLUDE BEGIN - "\r\n" - "\0" +"\r\n" +"\0" END #endif // APSTUDIO_INVOKED - ///////////////////////////////////////////////////////////////////////////// // // Icon @@ -53,7 +60,8 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDI_CMDER ICON "..\\..\\icons\\cmder.ico" - +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // @@ -61,30 +69,26 @@ IDI_CMDER ICON "..\\..\\icons\\cmder.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,3,6,1 - PRODUCTVERSION 1,3,6,1 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x1L - FILESUBTYPE 0x0L + FILEVERSION CMDER_MAJOR_VERSION,CMDER_MINOR_VERSION,CMDER_REVISION_VERSION,CMDER_BUILD_VERSION + PRODUCTVERSION CMDER_MAJOR_VERSION,CMDER_MINOR_VERSION,CMDER_REVISION_VERSION,CMDER_BUILD_VERSION + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEFLAGS (CMDER_DEBUGFLAG | CMDER_BUILDFLAGS) + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE VFT2_UNKNOWN BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "100904b0" BEGIN - VALUE "CompanyName", "Samuel Vasko" - VALUE "FileDescription", "Cmder: Lovely Console Emulator." - VALUE "FileVersion", "1.3.6-pre1" - VALUE "InternalName", "Cmder" - VALUE "LegalCopyright", "Copyright (C) 2016 Samuel Vasko" - VALUE "OriginalFilename", "Cmder.exe" - VALUE "ProductName", "Cmder" - VALUE "ProductVersion", "1.3.6-pre1" + VALUE "CompanyName", CMDER_COMPANY_NAME_STR "\0" + VALUE "FileDescription", CMDER_FILE_DESCRIPTION_STR "\0" + VALUE "FileVersion", CMDER_VERSION_STR "\0" + VALUE "InternalName", CMDER_INTERNAL_NAME_STR "\0" + VALUE "LegalCopyright", "Copyright (C) " CMDER_COPYRIGHT_YEAR_STR " " CMDER_COMPANY_NAME_STR "\0" + VALUE "OriginalFilename", CMDER_ORIGINAL_FILENAME_STR "\0" + VALUE "ProductName", CMDER_PRODUCT_NAME_STR "\0" + VALUE "ProductVersion", CMDER_VERSION_STR "\0" END END BLOCK "VarFileInfo" @@ -93,26 +97,7 @@ BEGIN END END - ///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE -BEGIN - IDS_TITLE "Cmder Launcher" -END - -STRINGTABLE -BEGIN - IDS_SWITCHES "Valid options:\n\n /c [CMDER User Root Path]\n /task [Windows Terminal Profile/ConEmu Task Name]\n /icon [CMDER Icon Path] - ConEmu ONLY!\n [/start [Start in Path] | [Start in Path]]\n /single - ConEmu ONLY!\n /m\n -- [ConEmu/Windows Terminal extra arguments]\n\nNote: '-- [...]' must be the last argument!\n\nor, either:\n /register [USER | ALL]\n /unregister [USER | ALL]" -END - -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// @@ -120,7 +105,5 @@ END // Generated from the TEXTINCLUDE 3 resource. // - ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED - diff --git a/launcher/src/strings.rc2 b/launcher/src/strings.rc2 index 494cbfe..d8feb4d 100644 --- a/launcher/src/strings.rc2 +++ b/launcher/src/strings.rc2 @@ -6,7 +6,7 @@ STRINGTABLE { IDS_TITLE "Cmder Launcher" - IDS_SWITCHES L"Valid options:\n\n /a Admin - Native Terminals ONLY!\n /c [CMDER User Root Path]\n /task [Windows Terminal Profile/ConEmu Task Name]\n /icon [CMDER Icon Path] - ConEmu ONLY!\n [/start [Start in Path] | [Start in Path]]\n /single - ConEmu ONLY!\n /m\n -- [ConEmu/Windows Terminal extra arguments]\n\nNote: '-- [...]' must be the last argument!\n\nor, either:\n /register [USER | ALL]\n /unregister [USER | ALL]" + IDS_SWITCHES L"Valid options:\n\n /c [CMDER User Root Path]\n /task [Windows Terminal Profile/ConEmu Task Name]\n /icon [CMDER Icon Path] - ConEmu ONLY!\n [/start [Start in Path] | [Start in Path]]\n /single - ConEmu ONLY!\n /m\n -- [ConEmu/Windows Terminal extra arguments]\n\nNote: '-- [...]' must be the last argument!\n\nor, either:\n /register [USER | ALL]\n /unregister [USER | ALL]" } ///////////////////////////////////////////////////////////////////////////// From df42ff2d8c000df1c67b157a58f9d652ee2c8367 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Tue, 8 Apr 2025 20:48:47 +0330 Subject: [PATCH 13/84] indentation cleanup and comment fix --- launcher/src/resource.rc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/launcher/src/resource.rc b/launcher/src/resource.rc index 5960625..8602089 100644 --- a/launcher/src/resource.rc +++ b/launcher/src/resource.rc @@ -35,19 +35,19 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 1 TEXTINCLUDE BEGIN -"resource.h\0" + "resource.h\0" END 2 TEXTINCLUDE BEGIN -"#include ""winres.h""\r\n" -"\0" + "#include ""winres.h""\r\n" + "\0" END 3 TEXTINCLUDE BEGIN -"\r\n" -"\0" + "\r\n" + "\0" END #endif // APSTUDIO_INVOKED @@ -60,7 +60,7 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDI_CMDER ICON "..\\..\\icons\\cmder.ico" -#endif // English (United States) resources +#endif // not APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// From abcb1a1aa10edf3bcf5cd792c93f809aea456dfd Mon Sep 17 00:00:00 2001 From: David Refoua Date: Tue, 15 Jul 2025 19:26:49 +0330 Subject: [PATCH 14/84] display MSYSTEM if set; fix indentation; add comment --- vendor/git-prompt.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/vendor/git-prompt.sh b/vendor/git-prompt.sh index a02af62..f25784f 100644 --- a/vendor/git-prompt.sh +++ b/vendor/git-prompt.sh @@ -20,7 +20,7 @@ function getSimpleGitBranch() { then echo " (${headContent:16})" else - echo " (HEAD detached at ${headContent:0:7})" + echo " (HEAD detached at ${headContent:0:7})" fi } @@ -38,12 +38,12 @@ then . ~/.config/git/git-prompt.sh fi else - PS1='\[\033]0;$MSYSTEM:${PWD//[^[:ascii:]]/?}\007\]' # set window title - # PS1="$PS1"'\n' # new line + # Taken from https://github.com/git-for-windows/build-extra/blob/main/git-extra/git-prompt.sh + PS1='\[\033]0;$TITLEPREFIX:${PWD//[^[:ascii:]]/?}\007\]' # set window title + # PS1="$PS1"'\n' # new line (disabled) PS1="$PS1"'\[\033[32m\]' # change to green PS1="$PS1"'\u@\h ' # user@host - # PS1="$PS1"'\[\033[35m\]' # change to purple - # PS1="$PS1"'$MSYSTEM ' # show MSYSTEM + PS1="$PS1${MSYSTEM:+\[\033[35m\]$MSYSTEM }" # show MSYSTEM in purple (if set) PS1="$PS1"'\[\033[33m\]' # change to brownish yellow PS1="$PS1"'\w' # current working directory if test -z "$WINELOADERNOEXEC" @@ -68,7 +68,7 @@ else fi PS1="$PS1"'\[\033[0m\]' # change color PS1="$PS1"'\n' # new line - PS1="$PS1"'λ ' # prompt: always λ + PS1="$PS1"'λ ' # prompt: Cmder uses λ fi MSYS2_PS1="$PS1" # for detection by MSYS2 SDK's bash.basrc \ No newline at end of file From cb768684116a9ce9081c76f86671610ddafd15e8 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Tue, 15 Jul 2025 19:29:16 +0330 Subject: [PATCH 15/84] Import from upstream git-prompt.sh: user-specific bash completion scripts Source: https://github.com/git-for-windows/build-extra/commit/061dbfe92b3a5c93aa0c284c8dad979f7e7c0935 --- vendor/git-prompt.sh | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/vendor/git-prompt.sh b/vendor/git-prompt.sh index f25784f..630073b 100644 --- a/vendor/git-prompt.sh +++ b/vendor/git-prompt.sh @@ -71,4 +71,15 @@ else PS1="$PS1"'λ ' # prompt: Cmder uses λ fi -MSYS2_PS1="$PS1" # for detection by MSYS2 SDK's bash.basrc \ No newline at end of file +MSYS2_PS1="$PS1" # for detection by MSYS2 SDK's bash.basrc + +# Evaluate all user-specific Bash completion scripts (if any) +if test -z "$WINELOADERNOEXEC" +then + for c in "$HOME"/bash_completion.d/*.bash + do + # Handle absence of any scripts (or the folder) gracefully + test ! -f "$c" || + . "$c" + done +fi \ No newline at end of file From 76c5b9e116f27c622d462e42756de9d62e94bf8b Mon Sep 17 00:00:00 2001 From: David Refoua Date: Tue, 15 Jul 2025 19:31:41 +0330 Subject: [PATCH 16/84] resolve conflicts --- vendor/git-prompt.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/vendor/git-prompt.sh b/vendor/git-prompt.sh index 189e3dc..efbafd7 100644 --- a/vendor/git-prompt.sh +++ b/vendor/git-prompt.sh @@ -20,7 +20,7 @@ function getSimpleGitBranch() { then echo " (${headContent:16})" else - echo " (HEAD detached at ${headContent:0:7})" + echo " (HEAD detached at ${headContent:0:7})" fi } @@ -38,12 +38,12 @@ then . ~/.config/git/git-prompt.sh fi else - PS1='\[\033]0;$TITLEPREFIX:$PWD\007\]' # set window title - # PS1="$PS1"'\n' # new line + # Taken from https://github.com/git-for-windows/build-extra/blob/main/git-extra/git-prompt.sh + PS1='\[\033]0;$TITLEPREFIX:${PWD//[^[:ascii:]]/?}\007\]' # set window title + # PS1="$PS1"'\n' # new line (disabled) PS1="$PS1"'\[\033[32m\]' # change to green PS1="$PS1"'\u@\h ' # user@host - # PS1="$PS1"'\[\033[35m\]' # change to purple - # PS1="$PS1"'$MSYSTEM ' # show MSYSTEM + PS1="$PS1${MSYSTEM:+\[\033[35m\]$MSYSTEM }" # show MSYSTEM in purple (if set) PS1="$PS1"'\[\033[33m\]' # change to brownish yellow PS1="$PS1"'\w' # current working directory if test -z "$WINELOADERNOEXEC" @@ -68,7 +68,7 @@ else fi PS1="$PS1"'\[\033[0m\]' # change color PS1="$PS1"'\n' # new line - PS1="$PS1"'λ ' # prompt: always λ + PS1="$PS1"'λ ' # prompt: Cmder uses λ fi MSYS2_PS1="$PS1" # for detection by MSYS2 SDK's bash.basrc @@ -76,10 +76,10 @@ MSYS2_PS1="$PS1" # for detection by MSYS2 SDK's bash.basrc # Evaluate all user-specific Bash completion scripts (if any) if test -z "$WINELOADERNOEXEC" then - for c in "$HOME"/bash_completion.d/*.bash - do - # Handle absence of any scripts (or the folder) gracefully - test ! -f "$c" || - . "$c" - done + for c in "$HOME"/bash_completion.d/*.bash + do + # Handle absence of any scripts (or the folder) gracefully + test ! -f "$c" || + . "$c" + done fi From aff4ad259fb158c8b35683f0d5d7c5c7a82d1451 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Tue, 15 Jul 2025 20:25:59 +0330 Subject: [PATCH 17/84] fix color values and names mismatch in comments --- vendor/cmder_prompt_config.lua.default | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/vendor/cmder_prompt_config.lua.default b/vendor/cmder_prompt_config.lua.default index 0c99bd8..d6c0a8c 100644 --- a/vendor/cmder_prompt_config.lua.default +++ b/vendor/cmder_prompt_config.lua.default @@ -48,15 +48,15 @@ prompt_overrideSvnStatusOptIn = false -- Colors: https://github.com/cmderdev/cmder/wiki/Customization#list-of-colors -- Effects: https://github.com/cmderdev/cmder/wiki/Customization#list-of-effects -- --- Green: "\x1b[1;33;49m" --- Yellow: "\x1b[1;32;49m" +-- Green: "\x1b[1;32;49m" +-- Yellow: "\x1b[1;33;49m" -- Light Grey: "\x1b[1;30;49m" -- Prompt Element Colors -uah_color = "\x1b[1;33;49m" -- Green = uah = [user]@[hostname] -cwd_color = "\x1b[1;32;49m" -- Yellow cwd = Current Working Directory +uah_color = "\x1b[1;33;49m" -- Yellow uah = [user]@[hostname] +cwd_color = "\x1b[1;32;49m" -- Green cwd = Current Working Directory lamb_color = "\x1b[1;30;49m" -- Light Grey = Lambda Color clean_color = "\x1b[37;1m" dirty_color = "\x1b[33;3m" -- Yellow, Italic conflict_color = "\x1b[31;1m" -- Red, Bold -unknown_color = "\x1b[37;1m" -- White = No VCS Status Branch Color +unknown_color = "\x1b[37;1m" -- White, Bold = No VCS Status Branch Color From 1d51c4f402c303830a5cf7ae91ae4042073b2b7e Mon Sep 17 00:00:00 2001 From: David Refoua Date: Tue, 15 Jul 2025 21:02:12 +0330 Subject: [PATCH 18/84] =?UTF-8?q?make=20bash=20prompt=20more=20consistent;?= =?UTF-8?q?=20*=20display=20=CE=BB=20in=20grey=20and=20bold=20*=20fix=20a?= =?UTF-8?q?=20bug=20where=20an=20uneeded=20colon=20would=20be=20prepended?= =?UTF-8?q?=20to=20the=20tab=20title=20(when=20MSYSTEM=20is=20unset)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vendor/git-prompt.sh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/vendor/git-prompt.sh b/vendor/git-prompt.sh index 630073b..7e6c096 100644 --- a/vendor/git-prompt.sh +++ b/vendor/git-prompt.sh @@ -38,13 +38,13 @@ then . ~/.config/git/git-prompt.sh fi else - # Taken from https://github.com/git-for-windows/build-extra/blob/main/git-extra/git-prompt.sh - PS1='\[\033]0;$TITLEPREFIX:${PWD//[^[:ascii:]]/?}\007\]' # set window title + # Taken parts from https://github.com/git-for-windows/build-extra/blob/main/git-extra/git-prompt.sh + PS1='\[\033]0;${TITLEPREFIX:+$TITLEPREFIX:}${PWD//[^[:ascii:]]/?}\007\]' # set window title to TITLEPREFIX (if set) and current working directory # PS1="$PS1"'\n' # new line (disabled) - PS1="$PS1"'\[\033[32m\]' # change to green + PS1="$PS1"'\[\033[32m\]' # change to green and bold PS1="$PS1"'\u@\h ' # user@host PS1="$PS1${MSYSTEM:+\[\033[35m\]$MSYSTEM }" # show MSYSTEM in purple (if set) - PS1="$PS1"'\[\033[33m\]' # change to brownish yellow + PS1="$PS1"'\[\033[1;33m\]' # change to dark yellow in bold PS1="$PS1"'\w' # current working directory if test -z "$WINELOADERNOEXEC" then @@ -66,9 +66,11 @@ else fi fi fi - PS1="$PS1"'\[\033[0m\]' # change color + PS1="$PS1"'\[\033[0m\]' # reset color PS1="$PS1"'\n' # new line + PS1="$PS1"'\[\033[30;1m\]' # change color to grey in bold PS1="$PS1"'λ ' # prompt: Cmder uses λ + PS1="$PS1"'\[\033[0m\]' # reset color fi MSYS2_PS1="$PS1" # for detection by MSYS2 SDK's bash.basrc From c6bfd6f27689484d40a6158a1659698f3b135b4a Mon Sep 17 00:00:00 2001 From: David Refoua Date: Wed, 16 Jul 2025 04:16:47 +0330 Subject: [PATCH 19/84] Minor refactors to Git status and branch functions in git-prompt.sh - `getGitStatusSetting`: use local variables, improve regex pattern, use return status codes instead of echo strings - `getSimpleGitBranch`: better error handling, use local variables - Simplified conditional checks --- vendor/git-prompt.sh | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/vendor/git-prompt.sh b/vendor/git-prompt.sh index 7e6c096..0b41f90 100644 --- a/vendor/git-prompt.sh +++ b/vendor/git-prompt.sh @@ -1,24 +1,32 @@ function getGitStatusSetting() { - gitStatusSetting=$(git --no-pager config -l 2>/dev/null) + local gitConfig - if [[ -n ${gitStatusSetting} ]] && [[ ${gitStatusSetting} =~ cmder.status=false ]] || [[ ${gitStatusSetting} =~ cmder.shstatus=false ]] + # Get all git config entries for the current repository without pager + gitConfig=$(git --no-pager config -l 2>/dev/null) || return 0 # treat failure as enabled + + # Check if git status for Cmder is disabled + if [[ $gitConfig =~ (^|$'\n')cmder\.status=false($|$'\n') ]] || \ + [[ $gitConfig =~ (^|$'\n')cmder\.shstatus=false($|$'\n') ]] then - echo false - else - echo true + return 1 # disabled fi + + return 0 } +# Prints current branch or detached HEAD short commit hash function getSimpleGitBranch() { - gitDir=$(git rev-parse --git-dir 2>/dev/null) - if [ -z "$gitDir" ]; then - return 0 - fi + local gitDir + gitDir=$(git rev-parse --git-dir 2>/dev/null) || return 0 - headContent=$(< "$gitDir/HEAD") - if [[ "$headContent" == "ref: refs/heads/"* ]] + local headFile="$gitDir/HEAD" + [ -f "$headFile" ] || return 0 + + local headContent + headContent=$(< "$headFile") + if [[ "$headContent" =~ ^ref:\ refs/heads/(.+)$ ]] then - echo " (${headContent:16})" + echo " (${BASH_REMATCH[1]})" else echo " (HEAD detached at ${headContent:0:7})" fi @@ -33,7 +41,7 @@ fi if test -f ~/.config/git/git-prompt.sh then - if [[ $(getGitStatusSetting) == true ]] + if getGitStatusSetting then . ~/.config/git/git-prompt.sh fi @@ -55,7 +63,7 @@ else if test -f "$COMPLETION_PATH/git-prompt.sh" then . "$COMPLETION_PATH/git-completion.bash" - if [[ $(getGitStatusSetting) == true ]] + if getGitStatusSetting then . "$COMPLETION_PATH/git-prompt.sh" PS1="$PS1"'\[\033[36m\]' # change color to cyan From 05552dc51ca8ccdfdef965580328f73694ba95dc Mon Sep 17 00:00:00 2001 From: David Refoua Date: Wed, 16 Jul 2025 04:18:03 +0330 Subject: [PATCH 20/84] added a comment --- vendor/git-prompt.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vendor/git-prompt.sh b/vendor/git-prompt.sh index 0b41f90..1b67e76 100644 --- a/vendor/git-prompt.sh +++ b/vendor/git-prompt.sh @@ -1,3 +1,4 @@ +# Returns 1 if git status for Cmder is disabled, otherwise returns 0 function getGitStatusSetting() { local gitConfig @@ -92,4 +93,4 @@ then test ! -f "$c" || . "$c" done -fi \ No newline at end of file +fi From c7116bd5334b079e3d78e4ba793803c050cd2eed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Aug 2025 19:56:14 +0000 Subject: [PATCH 21/84] Bump actions/checkout from 4 to 5 Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/branches.yml | 2 +- .github/workflows/build.yml | 2 +- .github/workflows/codeql.yml | 2 +- .github/workflows/tests.yml | 2 +- .github/workflows/vendor.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/branches.yml b/.github/workflows/branches.yml index 333242b..d76c3a3 100644 --- a/.github/workflows/branches.yml +++ b/.github/workflows/branches.yml @@ -19,7 +19,7 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out the repository under $GITHUB_WORKSPACE, so the job can access it - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 0 # fetch all history for all branches and tags diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c0c7793..0f230c2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,7 +35,7 @@ jobs: discussions: write steps: - name: Check out repository code (Action from GitHub) - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 8e9f4b5..ed4878d 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -45,7 +45,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8d9ecec..f2bf770 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -38,7 +38,7 @@ jobs: continue-on-error: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Initialize vendors shell: pwsh working-directory: scripts diff --git a/.github/workflows/vendor.yml b/.github/workflows/vendor.yml index a9d3e17..62ccbcb 100644 --- a/.github/workflows/vendor.yml +++ b/.github/workflows/vendor.yml @@ -24,7 +24,7 @@ jobs: pull-requests: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 0 From 8ec4789e3528a9424e4ebfc2ba9a99907301a90c Mon Sep 17 00:00:00 2001 From: Chris Antos Date: Thu, 4 Sep 2025 10:41:08 -0700 Subject: [PATCH 22/84] Fix cmderdev/cmder#3020; hg prompt is slow. Cmder's hg prompt didn't use async prompt filtering yet. Cmder's svn prompt only used async prompt filtering if a special config variable was set (the commit which contributed it seems to have misunderstood the git config settings for the git async prompt). This commit makes the following changes: 1. Adds async prompt filtering for hg. 2. Makes async prompt filtering for svn the default. 3. Removes the prompt_overrideSvnStatusOptIn variable. 4. Fixes a bug where any errors during `svn status` in the svn prompt accidentally show up in the terminal. 5. Fixes a bug where any errors during `hg branch` in the hg prompt turn into Lua errors. 6. Simplifies the code for colors in the hg and svn prompts. 7. Clean up the svn prompt code and make it consistent with the git and hg prompt code. --- vendor/clink.lua | 152 ++++++++++++++----------- vendor/cmder_prompt_config.lua.default | 5 - 2 files changed, 83 insertions(+), 74 deletions(-) diff --git a/vendor/clink.lua b/vendor/clink.lua index 0593ae1..824c395 100644 --- a/vendor/clink.lua +++ b/vendor/clink.lua @@ -7,7 +7,7 @@ -- luacheck: globals uah_color cwd_color lamb_color clean_color dirty_color conflict_color unknown_color -- luacheck: globals prompt_homeSymbol prompt_lambSymbol prompt_type prompt_useHomeSymbol prompt_useUserAtHost -- luacheck: globals prompt_singleLine prompt_includeVersionControl --- luacheck: globals prompt_overrideGitStatusOptIn prompt_overrideSvnStatusOptIn +-- luacheck: globals prompt_overrideGitStatusOptIn -- luacheck: globals clink io.popenyield os.isdir settings.get -- At first, load the original clink.lua file @@ -350,13 +350,8 @@ end -- @return {false|mercurial branch information} --- local function get_hg_branch() - -- Return the branch information. The default is to get just the - -- branch name, but you could e.g. use the "hg-prompt" extension to - -- get more information, such as any applied mq patches. Here's an - -- example of that: - -- local cmd = "hg prompt \"{branch}{status}{|{patch}}{update}\"" - local cmd = "hg branch 2>nul" - local file = io.popen(cmd) + -- Return the branch information. + local file = io.popen("hg branch 2>nul") if not file then return false end @@ -424,12 +419,33 @@ local function get_git_status() return { status = is_status, conflict = conflict_found } end +--- +-- Get the status of working dir +-- @return {bool} +--- +local function get_hg_status() + -- The default is to just use the branch name, but you could e.g. use the + -- "hg-prompt" extension to get more information, such as any applied mq + -- patches. Here's an example of that: + -- "hg prompt \"{branch}{status}{|{patch}}{update}\"" + local pipe = io_popenyield("hg status -amrd 2>&1") + if not pipe then + return { error = true } + end + + local output = pipe:read('*all') + pipe:close() + + local dirty = (output ~= nil and output ~= "") + return { clean = not dirty } +end + --- -- Get the status of working dir -- @return {bool} --- local function get_svn_status() - local file = io_popenyield("svn status -q") + local file = io_popenyield("svn status -q 2>nul") if not file then return { error = true } end @@ -520,14 +536,6 @@ local function git_prompt_filter() return false end - -- Colors for git status - local colors = { - clean = get_clean_color(), - dirty = get_dirty_color(), - conflict = get_conflict_color(), - nostatus = get_unknown_color() - } - local git_dir = get_git_dir() local color if git_dir then @@ -547,18 +555,19 @@ local function git_prompt_filter() local gitConflict = gitInfo.conflict if gitStatus == nil then - color = colors.nostatus + color = get_unknown_color() elseif gitStatus then - color = colors.clean + color = get_clean_color() else - color = colors.dirty + color = get_dirty_color() end if gitConflict then - color = colors.conflict + color = get_conflict_color() end - clink.prompt.value = gsub_plain(clink.prompt.value, "{git}", " "..color.."("..branch..")") + local result = " "..color.."("..branch..")" + clink.prompt.value = gsub_plain(clink.prompt.value, "{git}", result) return false end end @@ -568,6 +577,18 @@ local function git_prompt_filter() return false end +local function get_hg_info_table() + local info = clink_promptcoroutine(function () + return get_hg_status() or {} + end) + if not info then + info = cached_info.hg_info or {} + else + cached_info.hg_info = info + end + return info +end + local function hg_prompt_filter() -- Don't do any hg processing if the prompt doesn't want to show hg info. @@ -577,33 +598,34 @@ local function hg_prompt_filter() local hg_dir = get_hg_dir() if hg_dir then - -- Colors for mercurial status - local colors = { - clean = get_clean_color(), - dirty = get_dirty_color(), - nostatus = get_unknown_color() - } - local output = get_hg_branch() + local output = get_hg_branch() or "" - -- strip the trailing newline from the branch name - local n = #output - while n > 0 and output:find("^%s", n) do n = n - 1 end - local branch = output:sub(1, n) + -- strip the trailing spaces and newline from the branch name + local branch = output:gsub("%s+$", "") if branch ~= nil and string.sub(branch,1,7) ~= "abort: " and -- not an HG working copy (not string.find(branch, "is not recognized")) then -- 'hg' not in path - local color = colors.clean - - local pipe = io.popen("hg status -amrd 2>&1") - if pipe then - output = pipe:read('*all') - pipe:close() - if output ~= nil and output ~= "" then color = colors.dirty end + -- If in a different repo or branch than last time, discard cached info + if cached_info.hg_dir ~= hg_dir or cached_info.hg_branch ~= branch then + cached_info.hg_info = nil + cached_info.hg_dir = hg_dir + cached_info.hg_branch = branch end - local result = color .. "(" .. branch .. ")" - clink.prompt.value = gsub_plain(clink.prompt.value, "{hg}", " "..result) + local hgInfo = get_hg_info_table() + + local color + if not hgInfo or hgInfo.error then + color = get_unknown_color() + elseif hgInfo.clean then + color = get_clean_color() + else + color = get_dirty_color() + end + + local result = " "..color.."("..branch..")" + clink.prompt.value = gsub_plain(clink.prompt.value, "{hg}", result) return false end end @@ -612,6 +634,18 @@ local function hg_prompt_filter() clink.prompt.value = gsub_plain(clink.prompt.value, "{hg}", "") end +local function get_svn_info_table() + local info = clink_promptcoroutine(function () + return get_svn_status() or {} + end) + if not info then + info = cached_info.svn_info or {} + else + cached_info.svn_info = info + end + return info +end + local function svn_prompt_filter() -- Don't do any svn processing if the prompt doesn't want to show svn info. @@ -619,13 +653,6 @@ local function svn_prompt_filter() return false end - -- Colors for svn status - local colors = { - clean = get_clean_color(), - dirty = get_dirty_color(), - nostatus = get_unknown_color() - } - local svn_dir = get_svn_dir() if svn_dir then -- if we're inside of svn repo then try to detect current branch @@ -637,29 +664,16 @@ local function svn_prompt_filter() cached_info.svn_dir = svn_dir cached_info.svn_branch = branch end - -- Get the svn status using coroutine if available and option is enabled. Otherwise use a blocking call - local svnStatus - if clink.promptcoroutine and io.popenyield and settings.get("prompt.async") and prompt_overrideSvnStatusOptIn then -- luacheck: no max line length - svnStatus = clink_promptcoroutine(function () - return get_svn_status() - end) - -- If the status result is pending, use the cached version instead, otherwise store it to the cache - if svnStatus == nil then - svnStatus = cached_info.svn_info - else - cached_info.svn_info = svnStatus - end - else - svnStatus = get_svn_status() - end + + local svnInfo = get_svn_info_table() local color - if not svnStatus or svnStatus.error then - color = colors.nostatus - elseif svnStatus.clean then - color = colors.clean + if not svnInfo or svnInfo.error then + color = get_unknown_color() + elseif svnInfo.clean then + color = get_clean_color() else - color = colors.dirty + color = get_dirty_color() end clink.prompt.value = gsub_plain(clink.prompt.value, "{svn}", " "..color.."("..branch..")") diff --git a/vendor/cmder_prompt_config.lua.default b/vendor/cmder_prompt_config.lua.default index d6c0a8c..b7dc1f6 100644 --- a/vendor/cmder_prompt_config.lua.default +++ b/vendor/cmder_prompt_config.lua.default @@ -38,11 +38,6 @@ prompt_includeVersionControl = true -- NOTE: This only takes effect if using Clink v1.2.10 or higher. prompt_overrideGitStatusOptIn = false --- OPTIONAL. If true then always ignore the cmder.status and cmder.cmdstatus svn config settings and run the svn prompt commands in the background. - -- default is false - -- NOTE: This only takes effect if using Clink v1.2.10 or higher. -prompt_overrideSvnStatusOptIn = false - -- Prompt Attributes -- -- Colors: https://github.com/cmderdev/cmder/wiki/Customization#list-of-colors From 173b86fbc8673518642ee2346763e5282d439b80 Mon Sep 17 00:00:00 2001 From: Chris Antos Date: Sun, 14 Sep 2025 10:34:23 -0700 Subject: [PATCH 23/84] Fix another pre-existing bug in the hg prompt. If the hg program is not found, then there used to be a Lua script error. I fixed that in the earlier commit in this PR. But the fix was incomplete, and the hg prompt still appended " ()" instead of not appending anything (which is how the svn prompt behaves when the svn program is not found). --- vendor/clink.lua | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/vendor/clink.lua b/vendor/clink.lua index 824c395..81b4d1e 100644 --- a/vendor/clink.lua +++ b/vendor/clink.lua @@ -598,12 +598,8 @@ local function hg_prompt_filter() local hg_dir = get_hg_dir() if hg_dir then - local output = get_hg_branch() or "" - - -- strip the trailing spaces and newline from the branch name - local branch = output:gsub("%s+$", "") - - if branch ~= nil and + local branch = get_hg_branch() + if branch and string.sub(branch,1,7) ~= "abort: " and -- not an HG working copy (not string.find(branch, "is not recognized")) then -- 'hg' not in path -- If in a different repo or branch than last time, discard cached info From 218400a4b8d8e1aa34a19e9d04114f8c7481afd9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 16 Sep 2025 10:47:03 +0000 Subject: [PATCH 24/84] Initial plan From 08ce81609afce4a6ff2e8aa22f172067f85adcd0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 16 Sep 2025 10:52:13 +0000 Subject: [PATCH 25/84] Add OSC 9;9 support for PowerShell prompt to enable Windows Terminal directory tracking Co-authored-by: DRSDavidSoft <4673812+DRSDavidSoft@users.noreply.github.com> --- vendor/profile.ps1 | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/vendor/profile.ps1 b/vendor/profile.ps1 index 1183377..0a37534 100644 --- a/vendor/profile.ps1 +++ b/vendor/profile.ps1 @@ -196,6 +196,15 @@ if ( $(Get-Command prompt).Definition -match 'PS \$\(\$executionContext.SessionS [ScriptBlock]$Prompt = { $lastSUCCESS = $? $realLastExitCode = $LastExitCode + + # Emit OSC 9;9 sequence for Windows Terminal directory tracking + # This enables "Duplicate Tab" and "Split Pane" to preserve the working directory + # Only active in Windows Terminal ($env:WT_SESSION) or ConEmu ($env:ConEmuPID) + $loc = $executionContext.SessionState.Path.CurrentLocation + if (($env:WT_SESSION -or $env:ConEmuPID) -and $loc.Provider.Name -eq "FileSystem") { + Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]27)]9;9;`"$($loc.ProviderPath)`"$([char]27)\" + } + $host.UI.RawUI.WindowTitle = Microsoft.PowerShell.Management\Split-Path $pwd.ProviderPath -Leaf Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x200B)`r$([char]0x1B)[K" if ($lastSUCCESS -or ($LastExitCode -ne 0)) { From 545331a336ba5ca9488db7d979acbbb3bf1f8f06 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 16 Sep 2025 10:53:33 +0000 Subject: [PATCH 26/84] Update README with Windows Terminal directory tracking feature documentation Co-authored-by: DRSDavidSoft <4673812+DRSDavidSoft@users.noreply.github.com> --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 735fd1e..72dec0e 100644 --- a/README.md +++ b/README.md @@ -352,6 +352,8 @@ Cmder by default comes with a vendored ConEmu installation as the underlying ter However, Cmder can in fact run in a variety of other terminal emulators, and even integrated IDEs. Assuming you have the latest version of Cmder, follow the following instructions to get Cmder working with your own terminal emulator. +⚠ *Note:* Cmder includes built-in support for Windows Terminal directory tracking via OSC 9;9 sequences. This enables "Duplicate Tab" and "Split Pane" features to preserve the current working directory for both `cmd.exe` and PowerShell sessions. + For instructions on how to integrate Cmder with your IDE, please read our [Wiki section](https://github.com/cmderdev/cmder/wiki#cmder-integration). ## Upgrading From 066203dbdcdbaace041e8312176b919984826a1b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Oct 2025 15:33:31 +0000 Subject: [PATCH 27/84] Bump github/codeql-action from 3 to 4 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3 to 4. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v3...v4) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index ed4878d..87ee1b5 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -49,7 +49,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@v4 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -68,6 +68,6 @@ jobs: run: .\build.ps1 -Compile -verbose - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@v4 with: category: "/language:${{matrix.language}}" From 1940e97ddc0d53b20dbd2bc93565c3bda180dfbc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Oct 2025 15:37:27 +0000 Subject: [PATCH 28/84] Bump actions/upload-artifact from 4 to 5 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0f230c2..ae2b262 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -53,26 +53,26 @@ jobs: run: .\pack.ps1 -verbose - name: Upload artifact (cmder.zip) - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: path: build/cmder.zip name: cmder.zip if-no-files-found: error - name: Upload artifact (cmder.7z) - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: path: build/cmder.7z name: cmder.7z - name: Upload artifact (cmder_mini.zip) - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: path: build/cmder_mini.zip name: cmder_mini.zip - name: Upload artifact (hashes.txt) - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: path: build/hashes.txt name: hashes.txt From a7c0e0642d19fcfa522fa4d95fdf8db81a6f5663 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Thu, 6 Nov 2025 16:59:58 +0330 Subject: [PATCH 29/84] implement fix suggested in https://github.com/cmderdev/cmder/issues/2990#issuecomment-3496143288 --- vendor/lib/lib_path.cmd | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/vendor/lib/lib_path.cmd b/vendor/lib/lib_path.cmd index 04f1cf3..0c46587 100644 --- a/vendor/lib/lib_path.cmd +++ b/vendor/lib/lib_path.cmd @@ -127,11 +127,12 @@ exit /b exit /b :toolong - echo "%OLD_PATH%">"%temp%\cmder_lib_pathA" - echo "%PATH%">"%temp%\cmder_lib_pathB" - fc /b "%temp%\cmder_lib_pathA" "%temp%\cmder_lib_pathB" 2>nul 1>nul - if errorlevel 1 ( del "%temp%\cmder_lib_pathA" & del "%temp%\cmder_lib_pathB" & goto :changed ) - del "%temp%\cmder_lib_pathA" & del "%temp%\cmder_lib_pathB" + set "_rand=%RANDOM%" + echo "%OLD_PATH%">"%temp%\%_rand%_cmder_lib_pathA" + echo "%PATH%">"%temp%\%_rand%_cmder_lib_pathB" + fc /b "%temp%\%_rand%_cmder_lib_pathA" "%temp%\%_rand%_cmder_lib_pathB" 2>nul 1>nul + if errorlevel 1 ( del "%temp%\%_rand%_cmder_lib_pathA" & del "%temp%\%_rand%_cmder_lib_pathB" & set "_rand=" & goto :changed ) + del "%temp%\%_rand%_cmder_lib_pathA" & del "%temp%\%_rand%_cmder_lib_pathB" & set "_rand=" exit /b :changed From e7f102bdee161d5dd9b0f8a0a207d82af7061d34 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Thu, 6 Nov 2025 17:09:40 +0330 Subject: [PATCH 30/84] avoid temp filename collisions --- vendor/lib/lib_path.cmd | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vendor/lib/lib_path.cmd b/vendor/lib/lib_path.cmd index 0c46587..8202b03 100644 --- a/vendor/lib/lib_path.cmd +++ b/vendor/lib/lib_path.cmd @@ -128,8 +128,14 @@ exit /b :toolong set "_rand=%RANDOM%" + if exist "%temp%\%_rand%_cmder_lib_pathA" del "%temp%\%_rand%_cmder_lib_pathA" 2>nul 1>nul + if exist "%temp%\%_rand%_cmder_lib_pathB" del "%temp%\%_rand%_cmder_lib_pathB" 2>nul 1>nul + if exist "%temp%\%_rand%_cmder_lib_pathA" goto :toolong + if exist "%temp%\%_rand%_cmder_lib_pathB" goto :toolong echo "%OLD_PATH%">"%temp%\%_rand%_cmder_lib_pathA" + if errorlevel 1 ( if exist "%temp%\%_rand%_cmder_lib_pathA" del "%temp%\%_rand%_cmder_lib_pathA" & goto :toolong ) echo "%PATH%">"%temp%\%_rand%_cmder_lib_pathB" + if errorlevel 1 ( if exist "%temp%\%_rand%_cmder_lib_pathA" del "%temp%\%_rand%_cmder_lib_pathA" & if exist "%temp%\%_cmder_lib_pathB" del "%temp%\%_rand%_cmder_lib_pathB" & goto :toolong ) fc /b "%temp%\%_rand%_cmder_lib_pathA" "%temp%\%_rand%_cmder_lib_pathB" 2>nul 1>nul if errorlevel 1 ( del "%temp%\%_rand%_cmder_lib_pathA" & del "%temp%\%_rand%_cmder_lib_pathB" & set "_rand=" & goto :changed ) del "%temp%\%_rand%_cmder_lib_pathA" & del "%temp%\%_rand%_cmder_lib_pathB" & set "_rand=" From 006567cdbc1c86f4ddff2372c9b875d612631d68 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Thu, 6 Nov 2025 18:07:13 +0330 Subject: [PATCH 31/84] fix inconsistencies --- vendor/lib/lib_base.cmd | 254 +++++++++---------- vendor/lib/lib_console.cmd | 214 ++++++++-------- vendor/lib/lib_git.cmd | 4 +- vendor/lib/lib_path.cmd | 506 ++++++++++++++++++------------------- vendor/lib/lib_profile.cmd | 90 +++---- 5 files changed, 534 insertions(+), 534 deletions(-) diff --git a/vendor/lib/lib_base.cmd b/vendor/lib/lib_base.cmd index f7420ef..46c444b 100644 --- a/vendor/lib/lib_base.cmd +++ b/vendor/lib/lib_base.cmd @@ -1,127 +1,127 @@ -@echo off - -set lib_base=call "%~dp0lib_base.cmd" - -if "%~1" == "/h" ( - %lib_base% help "%~0" -) else if "%1" neq "" ( - call :%* -) - -exit /b - -:::=============================================================================== -:::help - shows all sub routines in a .bat/.cmd file with documentation -:::. -:::include: -:::. -::: call "lib_base.cmd" -:::. -:::usage: -:::. -::: %lib_base% help "file" -:::. -:::options: -:::. -::: file full path to file containing lib_routines to display -:::------------------------------------------------------------------------------- - -:help - for /f "tokens=* delims=:" %%a in ('%WINDIR%\System32\findstr /i /r "^:::" "%~1"') do ( - if "%%a"=="." ( - echo. - ) else if /i "%%a" == "usage" ( - echo %%a: - ) else if /i "%%a" == "options" ( - echo %%a: - ) else if not "%%a" == "" ( - echo %%a - ) - ) - - pause - exit /b - -:::=============================================================================== -:::cmder_shell - Initializes the Cmder shell environment variables -:::. -:::description: -:::. -::: This routine sets up the Cmder shell environment by detecting the -::: command shell and initializing related variables. -:::. -:::include: -:::. -::: call "lib_base.cmd" -:::. -:::usage: -:::. -::: %lib_base% cmder_shell -:::------------------------------------------------------------------------------- - -:cmder_shell - call :detect_comspec %ComSpec% - exit /b - -:::=============================================================================== -:::detect_comspec - Detects the command shell being used::: -:::. -:::description: -:::. -::: This function sets the CMDER_SHELL variable to the name of the -::: detected command shell. It also initializes the CMDER_CLINK and -::: CMDER_ALIASES variables if they are not already defined. -:::. -:::include: -:::. -::: call "lib_base.cmd" -:::. -:::usage: -:::. -::: %lib_base% detect_comspec %ComSpec% -:::------------------------------------------------------------------------------- - -:detect_comspec - set CMDER_SHELL=%~n1 - if not defined CMDER_CLINK ( - set CMDER_CLINK=1 - ) - if not defined CMDER_ALIASES ( - set CMDER_ALIASES=1 - ) - exit /b - -:::=============================================================================== -:::update_legacy_aliases - Updates the legacy alias definitions in the user_aliases file -:::. -:::description: -:::. -::: This function checks if the user_aliases file contains the marker -::: ";= Add aliases below here". If the marker is not found, it creates -::: an initial user_aliases store by copying the default user_aliases file -::: from the CMDER_ROOT directory. If the CMDER_USER_CONFIG environment -::: variable is defined, it creates a backup of the existing user_aliases -::: file before copying the default file. -:::. -:::include: -:::. -::: call "lib_base.cmd" -:::. -:::usage: -:::. -::: %lib_base% update_legacy_aliases -:::------------------------------------------------------------------------------- - -:update_legacy_aliases - type "%user_aliases%" | %WINDIR%\System32\findstr /i ";= Add aliases below here" >nul - if "%errorlevel%" == "1" ( - echo Creating initial user_aliases store in "%user_aliases%"... - if defined CMDER_USER_CONFIG ( - copy "%user_aliases%" "%user_aliases%.old_format" - copy "%CMDER_ROOT%\vendor\user_aliases.cmd.default" "%user_aliases%" - ) else ( - copy "%user_aliases%" "%user_aliases%.old_format" - copy "%CMDER_ROOT%\vendor\user_aliases.cmd.default" "%user_aliases%" - ) - ) - exit /b +@echo off + +set lib_base=call "%~dp0lib_base.cmd" + +if "%~1" == "/h" ( + %lib_base% help "%~0" +) else if "%~1" neq "" ( + call :%* +) + +exit /b + +:::=============================================================================== +:::help - shows all sub routines in a .bat/.cmd file with documentation +:::. +:::include: +:::. +::: call "lib_base.cmd" +:::. +:::usage: +:::. +::: %lib_base% help "file" +:::. +:::options: +:::. +::: file full path to file containing lib_routines to display +:::------------------------------------------------------------------------------- + +:help + for /f "tokens=* delims=:" %%a in ('%WINDIR%\System32\findstr /i /r "^:::" "%~1"') do ( + if "%%a"=="." ( + echo. + ) else if /i "%%a" == "usage" ( + echo %%a: + ) else if /i "%%a" == "options" ( + echo %%a: + ) else if not "%%a" == "" ( + echo %%a + ) + ) + + pause + exit /b + +:::=============================================================================== +:::cmder_shell - Initializes the Cmder shell environment variables +:::. +:::description: +:::. +::: This routine sets up the Cmder shell environment by detecting the +::: command shell and initializing related variables. +:::. +:::include: +:::. +::: call "lib_base.cmd" +:::. +:::usage: +:::. +::: %lib_base% cmder_shell +:::------------------------------------------------------------------------------- + +:cmder_shell + call :detect_comspec %ComSpec% + exit /b + +:::=============================================================================== +:::detect_comspec - Detects the command shell being used::: +:::. +:::description: +:::. +::: This function sets the CMDER_SHELL variable to the name of the +::: detected command shell. It also initializes the CMDER_CLINK and +::: CMDER_ALIASES variables if they are not already defined. +:::. +:::include: +:::. +::: call "lib_base.cmd" +:::. +:::usage: +:::. +::: %lib_base% detect_comspec %ComSpec% +:::------------------------------------------------------------------------------- + +:detect_comspec + set CMDER_SHELL=%~n1 + if not defined CMDER_CLINK ( + set CMDER_CLINK=1 + ) + if not defined CMDER_ALIASES ( + set CMDER_ALIASES=1 + ) + exit /b + +:::=============================================================================== +:::update_legacy_aliases - Updates the legacy alias definitions in the user_aliases file +:::. +:::description: +:::. +::: This function checks if the user_aliases file contains the marker +::: ";= Add aliases below here". If the marker is not found, it creates +::: an initial user_aliases store by copying the default user_aliases file +::: from the CMDER_ROOT directory. If the CMDER_USER_CONFIG environment +::: variable is defined, it creates a backup of the existing user_aliases +::: file before copying the default file. +:::. +:::include: +:::. +::: call "lib_base.cmd" +:::. +:::usage: +:::. +::: %lib_base% update_legacy_aliases +:::------------------------------------------------------------------------------- + +:update_legacy_aliases + type "%user_aliases%" | %WINDIR%\System32\findstr /i ";= Add aliases below here" >nul + if "%errorlevel%" == "1" ( + echo Creating initial user_aliases store in "%user_aliases%"... + if defined CMDER_USER_CONFIG ( + copy "%user_aliases%" "%user_aliases%.old_format" + copy "%CMDER_ROOT%\vendor\user_aliases.cmd.default" "%user_aliases%" + ) else ( + copy "%user_aliases%" "%user_aliases%.old_format" + copy "%CMDER_ROOT%\vendor\user_aliases.cmd.default" "%user_aliases%" + ) + ) + exit /b diff --git a/vendor/lib/lib_console.cmd b/vendor/lib/lib_console.cmd index c3649cc..88ddd8d 100644 --- a/vendor/lib/lib_console.cmd +++ b/vendor/lib/lib_console.cmd @@ -1,107 +1,107 @@ -@echo off - -call "%~dp0lib_base.cmd" -set lib_console=call "%~dp0lib_console.cmd" -set ESC= - -:: Much faster than using "%lib_console% debug_output ..." etc. -set print_debug=if %debug_output% gtr 0 %lib_console% debug_output -set print_verbose=if %verbose_output% gtr 0 %lib_console% verbose_output -set print_warning=if %verbose_output% gtr 0 %lib_console% show_warning -set print_error=%lib_console% show_error - -if %fast_init% gtr %verbose_output% if %fast_init% gtr %debug_output% exit /b - -if "%~1" == "/h" ( - %lib_base% help "%~0" -) else if "%1" neq "" ( - call :%* -) - -exit /b - -:debug_output -:::=============================================================================== -:::debug_output - Output a debug message to the console. -:::. -:::include: -:::. -::: call "lib_console.cmd" -:::. -:::usage: -:::. -::: %lib_console% debug_output [caller] [message] -:::. -:::required: -:::. -::: [caller] Script/sub routine name calling debug_output -:::. -::: [message] Message text to display. -:::. -:::------------------------------------------------------------------------------- - - if %debug_output% gtr 0 echo %time% DEBUG(%~1): %~2 & echo. - exit /b - -:verbose_output -:::=============================================================================== -:::verbose_output - Output a debug message to the console. -:::. -:::include: -:::. -::: call "$0" -:::. -:::usage: -:::. -::: %lib_console% verbose_output "[message]" -:::. -:::required: -:::. -::: [message] Message text to display. -:::. -:::------------------------------------------------------------------------------- - - if %verbose_output% gtr 0 echo %~1 - exit /b - -:show_error -:::=============================================================================== -:::show_error - Output an error message to the console. -:::. -:::include: -:::. -::: call "$0" -:::. -:::usage: -:::. -::: %lib_console% show_error "[message]" -:::. -:::required: -:::. -::: [message] Message text to display. -:::. -:::------------------------------------------------------------------------------- - - echo %ESC%[91;1mERROR:%ESC%[0m %~1 - exit /b - -:show_warning -:::=============================================================================== -:::show_warning - Output a warning message to the console. -:::. -:::include: -:::. -::: call "$0" -:::. -:::usage: -:::. -::: %lib_console% show_warning "[message]" -:::. -:::required: -:::. -::: [message] Message text to display. -:::. -:::------------------------------------------------------------------------------- - - echo %ESC%[93;1mWARNING:%ESC%[0m %~1 - exit /b +@echo off + +call "%~dp0lib_base.cmd" +set lib_console=call "%~dp0lib_console.cmd" +set ESC= + +:: Much faster than using "%lib_console% debug_output ..." etc. +set print_debug=if %debug_output% gtr 0 %lib_console% debug_output +set print_verbose=if %verbose_output% gtr 0 %lib_console% verbose_output +set print_warning=if %verbose_output% gtr 0 %lib_console% show_warning +set print_error=%lib_console% show_error + +if %fast_init% gtr %verbose_output% if %fast_init% gtr %debug_output% exit /b + +if "%~1" == "/h" ( + %lib_base% help "%~0" +) else if "%~1" neq "" ( + call :%* +) + +exit /b + +:debug_output +:::=============================================================================== +:::debug_output - Output a debug message to the console. +:::. +:::include: +:::. +::: call "lib_console.cmd" +:::. +:::usage: +:::. +::: %lib_console% debug_output [caller] [message] +:::. +:::required: +:::. +::: [caller] Script/sub routine name calling debug_output +:::. +::: [message] Message text to display. +:::. +:::------------------------------------------------------------------------------- + + if %debug_output% gtr 0 echo %time% DEBUG(%~1): %~2 & echo. + exit /b + +:verbose_output +:::=============================================================================== +:::verbose_output - Output a debug message to the console. +:::. +:::include: +:::. +::: call "$0" +:::. +:::usage: +:::. +::: %lib_console% verbose_output "[message]" +:::. +:::required: +:::. +::: [message] Message text to display. +:::. +:::------------------------------------------------------------------------------- + + if %verbose_output% gtr 0 echo %~1 + exit /b + +:show_error +:::=============================================================================== +:::show_error - Output an error message to the console. +:::. +:::include: +:::. +::: call "$0" +:::. +:::usage: +:::. +::: %lib_console% show_error "[message]" +:::. +:::required: +:::. +::: [message] Message text to display. +:::. +:::------------------------------------------------------------------------------- + + echo %ESC%[91;1mERROR:%ESC%[0m %~1 + exit /b + +:show_warning +:::=============================================================================== +:::show_warning - Output a warning message to the console. +:::. +:::include: +:::. +::: call "$0" +:::. +:::usage: +:::. +::: %lib_console% show_warning "[message]" +:::. +:::required: +:::. +::: [message] Message text to display. +:::. +:::------------------------------------------------------------------------------- + + echo %ESC%[93;1mWARNING:%ESC%[0m %~1 + exit /b diff --git a/vendor/lib/lib_git.cmd b/vendor/lib/lib_git.cmd index 7b3bc47..db618cc 100644 --- a/vendor/lib/lib_git.cmd +++ b/vendor/lib/lib_git.cmd @@ -1,12 +1,12 @@ @echo off call "%~dp0lib_base.cmd" -call "%%~dp0lib_console.cmd" +call "%~dp0lib_console.cmd" set lib_git=call "%~dp0lib_git.cmd" if "%~1" == "/h" ( %lib_base% help "%~0" -) else if "%1" neq "" ( +) else if "%~1" neq "" ( call :%* ) diff --git a/vendor/lib/lib_path.cmd b/vendor/lib/lib_path.cmd index 8202b03..ee493b7 100644 --- a/vendor/lib/lib_path.cmd +++ b/vendor/lib/lib_path.cmd @@ -1,253 +1,253 @@ -@echo off - -call "%~dp0lib_base.cmd" -call "%%~dp0lib_console" -set lib_path=call "%~dp0lib_path.cmd" - -if "%~1" == "/h" ( - %lib_base% help "%~0" -) else if "%1" neq "" ( - call :%* -) - -setlocal enabledelayedexpansion -if not defined find_pathext ( - set "find_pathext=!PATHEXT:;= !" - set "find_pathext=!find_pathext:.=\.!" -) -endlocal & set "find_pathext=%find_pathext%" - -exit /b - -:enhance_path -:::=============================================================================== -:::enhance_path - Add a directory to the path env variable if required. -::: -:::include: -::: -::: call "lib_path.cmd" -::: -:::usage: -::: -::: %lib_path% enhance_path "[dir_path]" [append] -::: -:::required: -::: -::: [dir_path] Fully qualified directory path. Ex: "c:\bin" -::: -:::options: -::: -::: append Append to the path env variable rather than pre-pend. -::: -::: -:::output: -::: -::: path Sets the path env variable if required. -:::------------------------------------------------------------------------------- - if "%~1" neq "" ( - set "add_path=%~1" - ) else ( - %print_error% "You must specify a directory to add to the path!" - exit 1 - ) - - if "%~2" neq "" if /i "%~2" == "append" ( - set "position=%~2" - ) else ( - set "position=" - ) - - dir "%add_path%" 2>NUL | findstr -i -e "%find_pathext%" >NUL - - if "%ERRORLEVEL%" == "0" ( - set "add_to_path=%add_path%" - ) else ( - set "add_to_path=" - ) - - if "%fast_init%" == "1" ( - if "%position%" == "append" ( - set "PATH=%PATH%;%add_to_path%" - ) else ( - set "PATH=%add_to_path%;%PATH%" - ) - goto :end_enhance_path - ) else if "add_to_path" equ "" ( - goto :end_enhance_path - ) - - set found=0 - set "find_query=%add_to_path%" - set "find_query=%find_query:\=\\%" - set "find_query=%find_query: =\ %" - set "OLD_PATH=%PATH%" - - setlocal enabledelayedexpansion - if "!found!" == "0" ( - echo "!path!"|!WINDIR!\System32\findstr >nul /I /R /C:";!find_query!;" - call :set_found - ) - %print_debug% :enhance_path "Env Var INSIDE PATH !find_query! - found=!found!" - - if /i "!position!" == "append" ( - if "!found!" == "0" ( - echo "!path!"|!WINDIR!\System32\findstr >nul /I /R /C:";!find_query!\"$" - call :set_found - ) - %print_debug% :enhance_path "Env Var END PATH !find_query! - found=!found!" - ) else ( - if "!found!" == "0" ( - echo "!path!"|!WINDIR!\System32\findstr >nul /I /R /C:"^\"!find_query!;" - call :set_found - ) - %print_debug% :enhance_path "Env Var BEGIN PATH !find_query! - found=!found!" - ) - endlocal & set found=%found% - - if "%found%" == "0" ( - if /i "%position%" == "append" ( - %print_debug% :enhance_path "Appending '%add_to_path%'" - set "PATH=%PATH%;%add_to_path%" - ) else ( - %print_debug% :enhance_path "Prepending '%add_to_path%'" - set "PATH=%add_to_path%;%PATH%" - ) - - set found=1 - ) - - :end_enhance_path - set "PATH=%PATH:;;=;%" - - REM echo %path%|"C:\Users\dgames\cmder - dev\vendor\git-for-windows\usr\bin\wc" -c - if "%fast_init%" == "1" exit /b - - if not "%OLD_PATH:~0,3000%" == "%OLD_PATH:~0,3001%" goto :toolong - if not "%OLD_PATH%" == "%PATH%" goto :changed - exit /b - - :toolong - set "_rand=%RANDOM%" - if exist "%temp%\%_rand%_cmder_lib_pathA" del "%temp%\%_rand%_cmder_lib_pathA" 2>nul 1>nul - if exist "%temp%\%_rand%_cmder_lib_pathB" del "%temp%\%_rand%_cmder_lib_pathB" 2>nul 1>nul - if exist "%temp%\%_rand%_cmder_lib_pathA" goto :toolong - if exist "%temp%\%_rand%_cmder_lib_pathB" goto :toolong - echo "%OLD_PATH%">"%temp%\%_rand%_cmder_lib_pathA" - if errorlevel 1 ( if exist "%temp%\%_rand%_cmder_lib_pathA" del "%temp%\%_rand%_cmder_lib_pathA" & goto :toolong ) - echo "%PATH%">"%temp%\%_rand%_cmder_lib_pathB" - if errorlevel 1 ( if exist "%temp%\%_rand%_cmder_lib_pathA" del "%temp%\%_rand%_cmder_lib_pathA" & if exist "%temp%\%_cmder_lib_pathB" del "%temp%\%_rand%_cmder_lib_pathB" & goto :toolong ) - fc /b "%temp%\%_rand%_cmder_lib_pathA" "%temp%\%_rand%_cmder_lib_pathB" 2>nul 1>nul - if errorlevel 1 ( del "%temp%\%_rand%_cmder_lib_pathA" & del "%temp%\%_rand%_cmder_lib_pathB" & set "_rand=" & goto :changed ) - del "%temp%\%_rand%_cmder_lib_pathA" & del "%temp%\%_rand%_cmder_lib_pathB" & set "_rand=" - exit /b - - :changed - %print_debug% :enhance_path "END Env Var - PATH=%path%" - %print_debug% :enhance_path "Env Var %find_query% - found=%found%" - exit /b - - exit /b - -:set_found - if "%ERRORLEVEL%" == "0" ( - set found=1 - ) - - exit /b - -:enhance_path_recursive -:::=============================================================================== -:::enhance_path_recursive - Add a directory and subs to the path env variable if -::: required. -:::. -:::include: -:::. -::: call "$0" -:::. -:::usage: -:::. -::: call "%~DP0lib_path" enhance_path_recursive "[dir_path]" [max_depth] [append] -:::. -:::required: -:::. -::: [dir_path] Fully qualified directory path. Ex: "c:\bin" -:::. -:::options: -:::. -::: [max_depth] Max recursion depth. Default: 1 -:::. -::: append Append instead to path env variable rather than pre-pend. -:::. -:::output: -:::. -::: path Sets the path env variable if required. -:::------------------------------------------------------------------------------- - if "%~1" neq "" ( - set "add_path=%~1" - ) else ( - %print_error% "You must specify a directory to add to the path!" - exit 1 - ) - - set "depth=%~2" - set "max_depth=%~3" - - if "%~4" neq "" if /i "%~4" == "append" ( - set "position=%~4" - ) else ( - set "position=" - ) - - dir "%add_path%" 2>NUL | findstr -i -e "%find_pathext%" >NUL - - if "%ERRORLEVEL%" == "0" ( - set "add_to_path=%add_path%" - ) else ( - set "add_to_path=" - ) - - if "%fast_init%" == "1" ( - if "%add_to_path%" neq "" ( - call :enhance_path "%add_to_path%" %position% - ) - ) - - set "PATH=%PATH:;;=;%" - if "%fast_init%" == "1" ( - exit /b - ) - - %print_debug% :enhance_path_recursive "Env Var - add_path=%add_to_path%" - %print_debug% :enhance_path_recursive "Env Var - position=%position%" - %print_debug% :enhance_path_recursive "Env Var - depth=%depth%" - %print_debug% :enhance_path_recursive "Env Var - max_depth=%max_depth%" - - if %max_depth% gtr %depth% ( - if "%add_to_path%" neq "" ( - %print_debug% :enhance_path_recursive "Adding parent directory - '%add_to_path%'" - call :enhance_path "%add_to_path%" %position% - ) - call :set_depth - call :loop_depth - ) - - set "PATH=%PATH%" - - exit /b - -:set_depth - set /a "depth=%depth%+1" - exit /b - -:loop_depth - if %depth% == %max_depth% ( - exit /b - ) - - for /d %%i in ("%add_path%\*") do ( - %print_debug% :enhance_path_recursive "Env Var BEFORE - depth=%depth%" - %print_debug% :enhance_path_recursive "Found Subdirectory - '%%~fi'" - call :enhance_path_recursive "%%~fi" %depth% %max_depth% %position% - %print_debug% :enhance_path_recursive "Env Var AFTER- depth=%depth%" - ) - exit /b +@echo off + +call "%~dp0lib_base.cmd" +call "%~dp0lib_console.cmd" +set lib_path=call "%~dp0lib_path.cmd" + +if "%~1" == "/h" ( + %lib_base% help "%~0" +) else if "%~1" neq "" ( + call :%* +) + +setlocal enabledelayedexpansion +if not defined find_pathext ( + set "find_pathext=!PATHEXT:;= !" + set "find_pathext=!find_pathext:.=\.!" +) +endlocal & set "find_pathext=%find_pathext%" + +exit /b + +:enhance_path +:::=============================================================================== +:::enhance_path - Add a directory to the path env variable if required. +::: +:::include: +::: +::: call "lib_path.cmd" +::: +:::usage: +::: +::: %lib_path% enhance_path "[dir_path]" [append] +::: +:::required: +::: +::: [dir_path] Fully qualified directory path. Ex: "c:\bin" +::: +:::options: +::: +::: append Append to the path env variable rather than pre-pend. +::: +::: +:::output: +::: +::: path Sets the path env variable if required. +:::------------------------------------------------------------------------------- + if "%~1" neq "" ( + set "add_path=%~1" + ) else ( + %print_error% "You must specify a directory to add to the path!" + exit /b 1 + ) + + if "%~2" neq "" if /i "%~2" == "append" ( + set "position=%~2" + ) else ( + set "position=" + ) + + dir "%add_path%" 2>NUL | findstr -i -e "%find_pathext%" >NUL + + if "%ERRORLEVEL%" == "0" ( + set "add_to_path=%add_path%" + ) else ( + set "add_to_path=" + ) + + if "%fast_init%" == "1" ( + if "%position%" == "append" ( + set "PATH=%PATH%;%add_to_path%" + ) else ( + set "PATH=%add_to_path%;%PATH%" + ) + goto :end_enhance_path + ) else if "%add_to_path%" equ "" ( + goto :end_enhance_path + ) + + set found=0 + set "find_query=%add_to_path%" + set "find_query=%find_query:\=\\%" + set "find_query=%find_query: =\ %" + set "OLD_PATH=%PATH%" + + setlocal enabledelayedexpansion + if "!found!" == "0" ( + echo "!PATH!"|!WINDIR!\System32\findstr >nul /I /R /C:";!find_query!;" + call :set_found + ) + %print_debug% :enhance_path "Env Var INSIDE PATH !find_query! - found=!found!" + + if /i "!position!" == "append" ( + if "!found!" == "0" ( + echo "!PATH!"|!WINDIR!\System32\findstr >nul /I /R /C:";!find_query!\"$" + call :set_found + ) + %print_debug% :enhance_path "Env Var END PATH !find_query! - found=!found!" + ) else ( + if "!found!" == "0" ( + echo "!PATH!"|!WINDIR!\System32\findstr >nul /I /R /C:"^\"!find_query!;" + call :set_found + ) + %print_debug% :enhance_path "Env Var BEGIN PATH !find_query! - found=!found!" + ) + endlocal & set found=%found% + + if "%found%" == "0" ( + if /i "%position%" == "append" ( + %print_debug% :enhance_path "Appending '%add_to_path%'" + set "PATH=%PATH%;%add_to_path%" + ) else ( + %print_debug% :enhance_path "Prepending '%add_to_path%'" + set "PATH=%add_to_path%;%PATH%" + ) + + set found=1 + ) + + :end_enhance_path + set "PATH=%PATH:;;=;%" + + REM echo %PATH%|wc -c + if "%fast_init%" == "1" exit /b + + if not "%OLD_PATH:~0,3000%" == "%OLD_PATH:~0,3001%" goto :toolong + if not "%OLD_PATH%" == "%PATH%" goto :changed + exit /b + + :toolong + set "_rand=%RANDOM%" + if exist "%temp%\%_rand%_cmder_lib_pathA" del "%temp%\%_rand%_cmder_lib_pathA" 2>nul 1>nul + if exist "%temp%\%_rand%_cmder_lib_pathB" del "%temp%\%_rand%_cmder_lib_pathB" 2>nul 1>nul + if exist "%temp%\%_rand%_cmder_lib_pathA" goto :toolong + if exist "%temp%\%_rand%_cmder_lib_pathB" goto :toolong + echo "%OLD_PATH%">"%temp%\%_rand%_cmder_lib_pathA" + if errorlevel 1 ( if exist "%temp%\%_rand%_cmder_lib_pathA" del "%temp%\%_rand%_cmder_lib_pathA" & goto :toolong ) + echo "%PATH%">"%temp%\%_rand%_cmder_lib_pathB" + if errorlevel 1 ( if exist "%temp%\%_rand%_cmder_lib_pathA" del "%temp%\%_rand%_cmder_lib_pathA" & if exist "%temp%\%_cmder_lib_pathB" del "%temp%\%_rand%_cmder_lib_pathB" & goto :toolong ) + fc /b "%temp%\%_rand%_cmder_lib_pathA" "%temp%\%_rand%_cmder_lib_pathB" 2>nul 1>nul + if errorlevel 1 ( del "%temp%\%_rand%_cmder_lib_pathA" & del "%temp%\%_rand%_cmder_lib_pathB" & set "_rand=" & goto :changed ) + del "%temp%\%_rand%_cmder_lib_pathA" & del "%temp%\%_rand%_cmder_lib_pathB" & set "_rand=" + exit /b + + :changed + %print_debug% :enhance_path "END Env Var - PATH=%PATH%" + %print_debug% :enhance_path "Env Var %find_query% - found=%found%" + exit /b + + exit /b + +:set_found + if "%ERRORLEVEL%" == "0" ( + set found=1 + ) + + exit /b + +:enhance_path_recursive +:::=============================================================================== +:::enhance_path_recursive - Add a directory and subs to the path env variable if +::: required. +:::. +:::include: +:::. +::: call "$0" +:::. +:::usage: +:::. +::: call "%~DP0lib_path" enhance_path_recursive "[dir_path]" [max_depth] [append] +:::. +:::required: +:::. +::: [dir_path] Fully qualified directory path. Ex: "c:\bin" +:::. +:::options: +:::. +::: [max_depth] Max recursion depth. Default: 1 +:::. +::: append Append instead to path env variable rather than pre-pend. +:::. +:::output: +:::. +::: path Sets the path env variable if required. +:::------------------------------------------------------------------------------- + if "%~1" neq "" ( + set "add_path=%~1" + ) else ( + %print_error% "You must specify a directory to add to the path!" + exit /b 1 + ) + + set "depth=%~2" + set "max_depth=%~3" + + if "%~4" neq "" if /i "%~4" == "append" ( + set "position=%~4" + ) else ( + set "position=" + ) + + dir "%add_path%" 2>NUL | findstr -i -e "%find_pathext%" >NUL + + if "%ERRORLEVEL%" == "0" ( + set "add_to_path=%add_path%" + ) else ( + set "add_to_path=" + ) + + if "%fast_init%" == "1" ( + if "%add_to_path%" neq "" ( + call :enhance_path "%add_to_path%" %position% + ) + ) + + set "PATH=%PATH:;;=;%" + if "%fast_init%" == "1" ( + exit /b + ) + + %print_debug% :enhance_path_recursive "Env Var - add_path=%add_to_path%" + %print_debug% :enhance_path_recursive "Env Var - position=%position%" + %print_debug% :enhance_path_recursive "Env Var - depth=%depth%" + %print_debug% :enhance_path_recursive "Env Var - max_depth=%max_depth%" + + if %max_depth% gtr %depth% ( + if "%add_to_path%" neq "" ( + %print_debug% :enhance_path_recursive "Adding parent directory - '%add_to_path%'" + call :enhance_path "%add_to_path%" %position% + ) + call :set_depth + call :loop_depth + ) + + set "PATH=%PATH%" + + exit /b + +:set_depth + set /a "depth=%depth%+1" + exit /b + +:loop_depth + if %depth% == %max_depth% ( + exit /b + ) + + for /d %%i in ("%add_path%\*") do ( + %print_debug% :enhance_path_recursive "Env Var BEFORE - depth=%depth%" + %print_debug% :enhance_path_recursive "Found Subdirectory - '%%~fi'" + call :enhance_path_recursive "%%~fi" %depth% %max_depth% %position% + %print_debug% :enhance_path_recursive "Env Var AFTER- depth=%depth%" + ) + exit /b diff --git a/vendor/lib/lib_profile.cmd b/vendor/lib/lib_profile.cmd index 050beac..c0449b9 100644 --- a/vendor/lib/lib_profile.cmd +++ b/vendor/lib/lib_profile.cmd @@ -1,45 +1,45 @@ -@echo off - -call "%~dp0lib_base.cmd" -call "%%~dp0lib_console" -set lib_profile=call "%~dp0lib_profile.cmd" - -if "%~1" == "/h" ( - %lib_base% help "%~0" -) else if "%1" neq "" ( - call :%* -) - -exit /b - -:::=============================================================================== -:::run_profile_d - Run all scripts in the passed directory path -:::. -:::include: -:::. -::: call "lib_profile.cmd" -:::. -:::usage: -:::. -::: %lib_profile% "[dir_path]" -:::. -:::required: -:::. -::: [dir_path] Fully qualified directory path containing init *.cmd|*.bat. -::: Example: "c:\bin" -:::. -::: path Sets the path env variable if required. -:::------------------------------------------------------------------------------- - -:run_profile_d - if not exist "%~1" ( - mkdir "%~1" - ) - - pushd "%~1" - for /f "usebackq" %%x in ( `dir /b *.bat *.cmd 2^>nul` ) do ( - %print_verbose% "Calling '%~1\%%x'..." - call "%~1\%%x" - ) - popd - exit /b +@echo off + +call "%~dp0lib_base.cmd" +call "%~dp0lib_console.cmd" +set lib_profile=call "%~dp0lib_profile.cmd" + +if "%~1" == "/h" ( + %lib_base% help "%~0" +) else if "%~1" neq "" ( + call :%* +) + +exit /b + +:::=============================================================================== +:::run_profile_d - Run all scripts in the passed directory path +:::. +:::include: +:::. +::: call "lib_profile.cmd" +:::. +:::usage: +:::. +::: %lib_profile% "[dir_path]" +:::. +:::required: +:::. +::: [dir_path] Fully qualified directory path containing init *.cmd|*.bat. +::: Example: "c:\bin" +:::. +::: path Sets the path env variable if required. +:::------------------------------------------------------------------------------- + +:run_profile_d + if not exist "%~1" ( + mkdir "%~1" + ) + + pushd "%~1" + for /f "usebackq" %%x in ( `dir /b *.bat *.cmd 2^>nul` ) do ( + %print_verbose% "Calling '%~1\%%x'..." + call "%~1\%%x" + ) + popd + exit /b From f6bc623284914489e891bbac923feb774c862b99 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Thu, 6 Nov 2025 18:13:33 +0330 Subject: [PATCH 32/84] fix line endings --- vendor/lib/lib_base.cmd | 254 +++++++++---------- vendor/lib/lib_console.cmd | 214 ++++++++-------- vendor/lib/lib_path.cmd | 506 ++++++++++++++++++------------------- vendor/lib/lib_profile.cmd | 90 +++---- 4 files changed, 532 insertions(+), 532 deletions(-) diff --git a/vendor/lib/lib_base.cmd b/vendor/lib/lib_base.cmd index 46c444b..39371c7 100644 --- a/vendor/lib/lib_base.cmd +++ b/vendor/lib/lib_base.cmd @@ -1,127 +1,127 @@ -@echo off - -set lib_base=call "%~dp0lib_base.cmd" - -if "%~1" == "/h" ( - %lib_base% help "%~0" -) else if "%~1" neq "" ( - call :%* -) - -exit /b - -:::=============================================================================== -:::help - shows all sub routines in a .bat/.cmd file with documentation -:::. -:::include: -:::. -::: call "lib_base.cmd" -:::. -:::usage: -:::. -::: %lib_base% help "file" -:::. -:::options: -:::. -::: file full path to file containing lib_routines to display -:::------------------------------------------------------------------------------- - -:help - for /f "tokens=* delims=:" %%a in ('%WINDIR%\System32\findstr /i /r "^:::" "%~1"') do ( - if "%%a"=="." ( - echo. - ) else if /i "%%a" == "usage" ( - echo %%a: - ) else if /i "%%a" == "options" ( - echo %%a: - ) else if not "%%a" == "" ( - echo %%a - ) - ) - - pause - exit /b - -:::=============================================================================== -:::cmder_shell - Initializes the Cmder shell environment variables -:::. -:::description: -:::. -::: This routine sets up the Cmder shell environment by detecting the -::: command shell and initializing related variables. -:::. -:::include: -:::. -::: call "lib_base.cmd" -:::. -:::usage: -:::. -::: %lib_base% cmder_shell -:::------------------------------------------------------------------------------- - -:cmder_shell - call :detect_comspec %ComSpec% - exit /b - -:::=============================================================================== -:::detect_comspec - Detects the command shell being used::: -:::. -:::description: -:::. -::: This function sets the CMDER_SHELL variable to the name of the -::: detected command shell. It also initializes the CMDER_CLINK and -::: CMDER_ALIASES variables if they are not already defined. -:::. -:::include: -:::. -::: call "lib_base.cmd" -:::. -:::usage: -:::. -::: %lib_base% detect_comspec %ComSpec% -:::------------------------------------------------------------------------------- - -:detect_comspec - set CMDER_SHELL=%~n1 - if not defined CMDER_CLINK ( - set CMDER_CLINK=1 - ) - if not defined CMDER_ALIASES ( - set CMDER_ALIASES=1 - ) - exit /b - -:::=============================================================================== -:::update_legacy_aliases - Updates the legacy alias definitions in the user_aliases file -:::. -:::description: -:::. -::: This function checks if the user_aliases file contains the marker -::: ";= Add aliases below here". If the marker is not found, it creates -::: an initial user_aliases store by copying the default user_aliases file -::: from the CMDER_ROOT directory. If the CMDER_USER_CONFIG environment -::: variable is defined, it creates a backup of the existing user_aliases -::: file before copying the default file. -:::. -:::include: -:::. -::: call "lib_base.cmd" -:::. -:::usage: -:::. -::: %lib_base% update_legacy_aliases -:::------------------------------------------------------------------------------- - -:update_legacy_aliases - type "%user_aliases%" | %WINDIR%\System32\findstr /i ";= Add aliases below here" >nul - if "%errorlevel%" == "1" ( - echo Creating initial user_aliases store in "%user_aliases%"... - if defined CMDER_USER_CONFIG ( - copy "%user_aliases%" "%user_aliases%.old_format" - copy "%CMDER_ROOT%\vendor\user_aliases.cmd.default" "%user_aliases%" - ) else ( - copy "%user_aliases%" "%user_aliases%.old_format" - copy "%CMDER_ROOT%\vendor\user_aliases.cmd.default" "%user_aliases%" - ) - ) - exit /b +@echo off + +set lib_base=call "%~dp0lib_base.cmd" + +if "%~1" == "/h" ( + %lib_base% help "%~0" +) else if "%~1" neq "" ( + call :%* +) + +exit /b + +:::=============================================================================== +:::help - shows all sub routines in a .bat/.cmd file with documentation +:::. +:::include: +:::. +::: call "lib_base.cmd" +:::. +:::usage: +:::. +::: %lib_base% help "file" +:::. +:::options: +:::. +::: file full path to file containing lib_routines to display +:::------------------------------------------------------------------------------- + +:help + for /f "tokens=* delims=:" %%a in ('%WINDIR%\System32\findstr /i /r "^:::" "%~1"') do ( + if "%%a"=="." ( + echo. + ) else if /i "%%a" == "usage" ( + echo %%a: + ) else if /i "%%a" == "options" ( + echo %%a: + ) else if not "%%a" == "" ( + echo %%a + ) + ) + + pause + exit /b + +:::=============================================================================== +:::cmder_shell - Initializes the Cmder shell environment variables +:::. +:::description: +:::. +::: This routine sets up the Cmder shell environment by detecting the +::: command shell and initializing related variables. +:::. +:::include: +:::. +::: call "lib_base.cmd" +:::. +:::usage: +:::. +::: %lib_base% cmder_shell +:::------------------------------------------------------------------------------- + +:cmder_shell + call :detect_comspec %ComSpec% + exit /b + +:::=============================================================================== +:::detect_comspec - Detects the command shell being used::: +:::. +:::description: +:::. +::: This function sets the CMDER_SHELL variable to the name of the +::: detected command shell. It also initializes the CMDER_CLINK and +::: CMDER_ALIASES variables if they are not already defined. +:::. +:::include: +:::. +::: call "lib_base.cmd" +:::. +:::usage: +:::. +::: %lib_base% detect_comspec %ComSpec% +:::------------------------------------------------------------------------------- + +:detect_comspec + set CMDER_SHELL=%~n1 + if not defined CMDER_CLINK ( + set CMDER_CLINK=1 + ) + if not defined CMDER_ALIASES ( + set CMDER_ALIASES=1 + ) + exit /b + +:::=============================================================================== +:::update_legacy_aliases - Updates the legacy alias definitions in the user_aliases file +:::. +:::description: +:::. +::: This function checks if the user_aliases file contains the marker +::: ";= Add aliases below here". If the marker is not found, it creates +::: an initial user_aliases store by copying the default user_aliases file +::: from the CMDER_ROOT directory. If the CMDER_USER_CONFIG environment +::: variable is defined, it creates a backup of the existing user_aliases +::: file before copying the default file. +:::. +:::include: +:::. +::: call "lib_base.cmd" +:::. +:::usage: +:::. +::: %lib_base% update_legacy_aliases +:::------------------------------------------------------------------------------- + +:update_legacy_aliases + type "%user_aliases%" | %WINDIR%\System32\findstr /i ";= Add aliases below here" >nul + if "%errorlevel%" == "1" ( + echo Creating initial user_aliases store in "%user_aliases%"... + if defined CMDER_USER_CONFIG ( + copy "%user_aliases%" "%user_aliases%.old_format" + copy "%CMDER_ROOT%\vendor\user_aliases.cmd.default" "%user_aliases%" + ) else ( + copy "%user_aliases%" "%user_aliases%.old_format" + copy "%CMDER_ROOT%\vendor\user_aliases.cmd.default" "%user_aliases%" + ) + ) + exit /b diff --git a/vendor/lib/lib_console.cmd b/vendor/lib/lib_console.cmd index 88ddd8d..600655f 100644 --- a/vendor/lib/lib_console.cmd +++ b/vendor/lib/lib_console.cmd @@ -1,107 +1,107 @@ -@echo off - -call "%~dp0lib_base.cmd" -set lib_console=call "%~dp0lib_console.cmd" -set ESC= - -:: Much faster than using "%lib_console% debug_output ..." etc. -set print_debug=if %debug_output% gtr 0 %lib_console% debug_output -set print_verbose=if %verbose_output% gtr 0 %lib_console% verbose_output -set print_warning=if %verbose_output% gtr 0 %lib_console% show_warning -set print_error=%lib_console% show_error - -if %fast_init% gtr %verbose_output% if %fast_init% gtr %debug_output% exit /b - -if "%~1" == "/h" ( - %lib_base% help "%~0" -) else if "%~1" neq "" ( - call :%* -) - -exit /b - -:debug_output -:::=============================================================================== -:::debug_output - Output a debug message to the console. -:::. -:::include: -:::. -::: call "lib_console.cmd" -:::. -:::usage: -:::. -::: %lib_console% debug_output [caller] [message] -:::. -:::required: -:::. -::: [caller] Script/sub routine name calling debug_output -:::. -::: [message] Message text to display. -:::. -:::------------------------------------------------------------------------------- - - if %debug_output% gtr 0 echo %time% DEBUG(%~1): %~2 & echo. - exit /b - -:verbose_output -:::=============================================================================== -:::verbose_output - Output a debug message to the console. -:::. -:::include: -:::. -::: call "$0" -:::. -:::usage: -:::. -::: %lib_console% verbose_output "[message]" -:::. -:::required: -:::. -::: [message] Message text to display. -:::. -:::------------------------------------------------------------------------------- - - if %verbose_output% gtr 0 echo %~1 - exit /b - -:show_error -:::=============================================================================== -:::show_error - Output an error message to the console. -:::. -:::include: -:::. -::: call "$0" -:::. -:::usage: -:::. -::: %lib_console% show_error "[message]" -:::. -:::required: -:::. -::: [message] Message text to display. -:::. -:::------------------------------------------------------------------------------- - - echo %ESC%[91;1mERROR:%ESC%[0m %~1 - exit /b - -:show_warning -:::=============================================================================== -:::show_warning - Output a warning message to the console. -:::. -:::include: -:::. -::: call "$0" -:::. -:::usage: -:::. -::: %lib_console% show_warning "[message]" -:::. -:::required: -:::. -::: [message] Message text to display. -:::. -:::------------------------------------------------------------------------------- - - echo %ESC%[93;1mWARNING:%ESC%[0m %~1 - exit /b +@echo off + +call "%~dp0lib_base.cmd" +set lib_console=call "%~dp0lib_console.cmd" +set ESC= + +:: Much faster than using "%lib_console% debug_output ..." etc. +set print_debug=if %debug_output% gtr 0 %lib_console% debug_output +set print_verbose=if %verbose_output% gtr 0 %lib_console% verbose_output +set print_warning=if %verbose_output% gtr 0 %lib_console% show_warning +set print_error=%lib_console% show_error + +if %fast_init% gtr %verbose_output% if %fast_init% gtr %debug_output% exit /b + +if "%~1" == "/h" ( + %lib_base% help "%~0" +) else if "%~1" neq "" ( + call :%* +) + +exit /b + +:debug_output +:::=============================================================================== +:::debug_output - Output a debug message to the console. +:::. +:::include: +:::. +::: call "lib_console.cmd" +:::. +:::usage: +:::. +::: %lib_console% debug_output [caller] [message] +:::. +:::required: +:::. +::: [caller] Script/sub routine name calling debug_output +:::. +::: [message] Message text to display. +:::. +:::------------------------------------------------------------------------------- + + if %debug_output% gtr 0 echo %time% DEBUG(%~1): %~2 & echo. + exit /b + +:verbose_output +:::=============================================================================== +:::verbose_output - Output a debug message to the console. +:::. +:::include: +:::. +::: call "$0" +:::. +:::usage: +:::. +::: %lib_console% verbose_output "[message]" +:::. +:::required: +:::. +::: [message] Message text to display. +:::. +:::------------------------------------------------------------------------------- + + if %verbose_output% gtr 0 echo %~1 + exit /b + +:show_error +:::=============================================================================== +:::show_error - Output an error message to the console. +:::. +:::include: +:::. +::: call "$0" +:::. +:::usage: +:::. +::: %lib_console% show_error "[message]" +:::. +:::required: +:::. +::: [message] Message text to display. +:::. +:::------------------------------------------------------------------------------- + + echo %ESC%[91;1mERROR:%ESC%[0m %~1 + exit /b + +:show_warning +:::=============================================================================== +:::show_warning - Output a warning message to the console. +:::. +:::include: +:::. +::: call "$0" +:::. +:::usage: +:::. +::: %lib_console% show_warning "[message]" +:::. +:::required: +:::. +::: [message] Message text to display. +:::. +:::------------------------------------------------------------------------------- + + echo %ESC%[93;1mWARNING:%ESC%[0m %~1 + exit /b diff --git a/vendor/lib/lib_path.cmd b/vendor/lib/lib_path.cmd index ee493b7..7edb2f5 100644 --- a/vendor/lib/lib_path.cmd +++ b/vendor/lib/lib_path.cmd @@ -1,253 +1,253 @@ -@echo off - -call "%~dp0lib_base.cmd" -call "%~dp0lib_console.cmd" -set lib_path=call "%~dp0lib_path.cmd" - -if "%~1" == "/h" ( - %lib_base% help "%~0" -) else if "%~1" neq "" ( - call :%* -) - -setlocal enabledelayedexpansion -if not defined find_pathext ( - set "find_pathext=!PATHEXT:;= !" - set "find_pathext=!find_pathext:.=\.!" -) -endlocal & set "find_pathext=%find_pathext%" - -exit /b - -:enhance_path -:::=============================================================================== -:::enhance_path - Add a directory to the path env variable if required. -::: -:::include: -::: -::: call "lib_path.cmd" -::: -:::usage: -::: -::: %lib_path% enhance_path "[dir_path]" [append] -::: -:::required: -::: -::: [dir_path] Fully qualified directory path. Ex: "c:\bin" -::: -:::options: -::: -::: append Append to the path env variable rather than pre-pend. -::: -::: -:::output: -::: -::: path Sets the path env variable if required. -:::------------------------------------------------------------------------------- - if "%~1" neq "" ( - set "add_path=%~1" - ) else ( - %print_error% "You must specify a directory to add to the path!" - exit /b 1 - ) - - if "%~2" neq "" if /i "%~2" == "append" ( - set "position=%~2" - ) else ( - set "position=" - ) - - dir "%add_path%" 2>NUL | findstr -i -e "%find_pathext%" >NUL - - if "%ERRORLEVEL%" == "0" ( - set "add_to_path=%add_path%" - ) else ( - set "add_to_path=" - ) - - if "%fast_init%" == "1" ( - if "%position%" == "append" ( - set "PATH=%PATH%;%add_to_path%" - ) else ( - set "PATH=%add_to_path%;%PATH%" - ) - goto :end_enhance_path - ) else if "%add_to_path%" equ "" ( - goto :end_enhance_path - ) - - set found=0 - set "find_query=%add_to_path%" - set "find_query=%find_query:\=\\%" - set "find_query=%find_query: =\ %" - set "OLD_PATH=%PATH%" - - setlocal enabledelayedexpansion - if "!found!" == "0" ( - echo "!PATH!"|!WINDIR!\System32\findstr >nul /I /R /C:";!find_query!;" - call :set_found - ) - %print_debug% :enhance_path "Env Var INSIDE PATH !find_query! - found=!found!" - - if /i "!position!" == "append" ( - if "!found!" == "0" ( - echo "!PATH!"|!WINDIR!\System32\findstr >nul /I /R /C:";!find_query!\"$" - call :set_found - ) - %print_debug% :enhance_path "Env Var END PATH !find_query! - found=!found!" - ) else ( - if "!found!" == "0" ( - echo "!PATH!"|!WINDIR!\System32\findstr >nul /I /R /C:"^\"!find_query!;" - call :set_found - ) - %print_debug% :enhance_path "Env Var BEGIN PATH !find_query! - found=!found!" - ) - endlocal & set found=%found% - - if "%found%" == "0" ( - if /i "%position%" == "append" ( - %print_debug% :enhance_path "Appending '%add_to_path%'" - set "PATH=%PATH%;%add_to_path%" - ) else ( - %print_debug% :enhance_path "Prepending '%add_to_path%'" - set "PATH=%add_to_path%;%PATH%" - ) - - set found=1 - ) - - :end_enhance_path - set "PATH=%PATH:;;=;%" - - REM echo %PATH%|wc -c - if "%fast_init%" == "1" exit /b - - if not "%OLD_PATH:~0,3000%" == "%OLD_PATH:~0,3001%" goto :toolong - if not "%OLD_PATH%" == "%PATH%" goto :changed - exit /b - - :toolong - set "_rand=%RANDOM%" - if exist "%temp%\%_rand%_cmder_lib_pathA" del "%temp%\%_rand%_cmder_lib_pathA" 2>nul 1>nul - if exist "%temp%\%_rand%_cmder_lib_pathB" del "%temp%\%_rand%_cmder_lib_pathB" 2>nul 1>nul - if exist "%temp%\%_rand%_cmder_lib_pathA" goto :toolong - if exist "%temp%\%_rand%_cmder_lib_pathB" goto :toolong - echo "%OLD_PATH%">"%temp%\%_rand%_cmder_lib_pathA" - if errorlevel 1 ( if exist "%temp%\%_rand%_cmder_lib_pathA" del "%temp%\%_rand%_cmder_lib_pathA" & goto :toolong ) - echo "%PATH%">"%temp%\%_rand%_cmder_lib_pathB" - if errorlevel 1 ( if exist "%temp%\%_rand%_cmder_lib_pathA" del "%temp%\%_rand%_cmder_lib_pathA" & if exist "%temp%\%_cmder_lib_pathB" del "%temp%\%_rand%_cmder_lib_pathB" & goto :toolong ) - fc /b "%temp%\%_rand%_cmder_lib_pathA" "%temp%\%_rand%_cmder_lib_pathB" 2>nul 1>nul - if errorlevel 1 ( del "%temp%\%_rand%_cmder_lib_pathA" & del "%temp%\%_rand%_cmder_lib_pathB" & set "_rand=" & goto :changed ) - del "%temp%\%_rand%_cmder_lib_pathA" & del "%temp%\%_rand%_cmder_lib_pathB" & set "_rand=" - exit /b - - :changed - %print_debug% :enhance_path "END Env Var - PATH=%PATH%" - %print_debug% :enhance_path "Env Var %find_query% - found=%found%" - exit /b - - exit /b - -:set_found - if "%ERRORLEVEL%" == "0" ( - set found=1 - ) - - exit /b - -:enhance_path_recursive -:::=============================================================================== -:::enhance_path_recursive - Add a directory and subs to the path env variable if -::: required. -:::. -:::include: -:::. -::: call "$0" -:::. -:::usage: -:::. -::: call "%~DP0lib_path" enhance_path_recursive "[dir_path]" [max_depth] [append] -:::. -:::required: -:::. -::: [dir_path] Fully qualified directory path. Ex: "c:\bin" -:::. -:::options: -:::. -::: [max_depth] Max recursion depth. Default: 1 -:::. -::: append Append instead to path env variable rather than pre-pend. -:::. -:::output: -:::. -::: path Sets the path env variable if required. -:::------------------------------------------------------------------------------- - if "%~1" neq "" ( - set "add_path=%~1" - ) else ( - %print_error% "You must specify a directory to add to the path!" - exit /b 1 - ) - - set "depth=%~2" - set "max_depth=%~3" - - if "%~4" neq "" if /i "%~4" == "append" ( - set "position=%~4" - ) else ( - set "position=" - ) - - dir "%add_path%" 2>NUL | findstr -i -e "%find_pathext%" >NUL - - if "%ERRORLEVEL%" == "0" ( - set "add_to_path=%add_path%" - ) else ( - set "add_to_path=" - ) - - if "%fast_init%" == "1" ( - if "%add_to_path%" neq "" ( - call :enhance_path "%add_to_path%" %position% - ) - ) - - set "PATH=%PATH:;;=;%" - if "%fast_init%" == "1" ( - exit /b - ) - - %print_debug% :enhance_path_recursive "Env Var - add_path=%add_to_path%" - %print_debug% :enhance_path_recursive "Env Var - position=%position%" - %print_debug% :enhance_path_recursive "Env Var - depth=%depth%" - %print_debug% :enhance_path_recursive "Env Var - max_depth=%max_depth%" - - if %max_depth% gtr %depth% ( - if "%add_to_path%" neq "" ( - %print_debug% :enhance_path_recursive "Adding parent directory - '%add_to_path%'" - call :enhance_path "%add_to_path%" %position% - ) - call :set_depth - call :loop_depth - ) - - set "PATH=%PATH%" - - exit /b - -:set_depth - set /a "depth=%depth%+1" - exit /b - -:loop_depth - if %depth% == %max_depth% ( - exit /b - ) - - for /d %%i in ("%add_path%\*") do ( - %print_debug% :enhance_path_recursive "Env Var BEFORE - depth=%depth%" - %print_debug% :enhance_path_recursive "Found Subdirectory - '%%~fi'" - call :enhance_path_recursive "%%~fi" %depth% %max_depth% %position% - %print_debug% :enhance_path_recursive "Env Var AFTER- depth=%depth%" - ) - exit /b +@echo off + +call "%~dp0lib_base.cmd" +call "%~dp0lib_console.cmd" +set lib_path=call "%~dp0lib_path.cmd" + +if "%~1" == "/h" ( + %lib_base% help "%~0" +) else if "%~1" neq "" ( + call :%* +) + +setlocal enabledelayedexpansion +if not defined find_pathext ( + set "find_pathext=!PATHEXT:;= !" + set "find_pathext=!find_pathext:.=\.!" +) +endlocal & set "find_pathext=%find_pathext%" + +exit /b + +:enhance_path +:::=============================================================================== +:::enhance_path - Add a directory to the path env variable if required. +::: +:::include: +::: +::: call "lib_path.cmd" +::: +:::usage: +::: +::: %lib_path% enhance_path "[dir_path]" [append] +::: +:::required: +::: +::: [dir_path] Fully qualified directory path. Ex: "c:\bin" +::: +:::options: +::: +::: append Append to the path env variable rather than pre-pend. +::: +::: +:::output: +::: +::: path Sets the path env variable if required. +:::------------------------------------------------------------------------------- + if "%~1" neq "" ( + set "add_path=%~1" + ) else ( + %print_error% "You must specify a directory to add to the path!" + exit /b 1 + ) + + if "%~2" neq "" if /i "%~2" == "append" ( + set "position=%~2" + ) else ( + set "position=" + ) + + dir "%add_path%" 2>NUL | findstr -i -e "%find_pathext%" >NUL + + if "%ERRORLEVEL%" == "0" ( + set "add_to_path=%add_path%" + ) else ( + set "add_to_path=" + ) + + if "%fast_init%" == "1" ( + if "%position%" == "append" ( + set "PATH=%PATH%;%add_to_path%" + ) else ( + set "PATH=%add_to_path%;%PATH%" + ) + goto :end_enhance_path + ) else if "%add_to_path%" equ "" ( + goto :end_enhance_path + ) + + set found=0 + set "find_query=%add_to_path%" + set "find_query=%find_query:\=\\%" + set "find_query=%find_query: =\ %" + set "OLD_PATH=%PATH%" + + setlocal enabledelayedexpansion + if "!found!" == "0" ( + echo "!PATH!"|!WINDIR!\System32\findstr >nul /I /R /C:";!find_query!;" + call :set_found + ) + %print_debug% :enhance_path "Env Var INSIDE PATH !find_query! - found=!found!" + + if /i "!position!" == "append" ( + if "!found!" == "0" ( + echo "!PATH!"|!WINDIR!\System32\findstr >nul /I /R /C:";!find_query!\"$" + call :set_found + ) + %print_debug% :enhance_path "Env Var END PATH !find_query! - found=!found!" + ) else ( + if "!found!" == "0" ( + echo "!PATH!"|!WINDIR!\System32\findstr >nul /I /R /C:"^\"!find_query!;" + call :set_found + ) + %print_debug% :enhance_path "Env Var BEGIN PATH !find_query! - found=!found!" + ) + endlocal & set found=%found% + + if "%found%" == "0" ( + if /i "%position%" == "append" ( + %print_debug% :enhance_path "Appending '%add_to_path%'" + set "PATH=%PATH%;%add_to_path%" + ) else ( + %print_debug% :enhance_path "Prepending '%add_to_path%'" + set "PATH=%add_to_path%;%PATH%" + ) + + set found=1 + ) + + :end_enhance_path + set "PATH=%PATH:;;=;%" + + REM echo %PATH%|wc -c + if "%fast_init%" == "1" exit /b + + if not "%OLD_PATH:~0,3000%" == "%OLD_PATH:~0,3001%" goto :toolong + if not "%OLD_PATH%" == "%PATH%" goto :changed + exit /b + + :toolong + set "_rand=%RANDOM%" + if exist "%temp%\%_rand%_cmder_lib_pathA" del "%temp%\%_rand%_cmder_lib_pathA" 2>nul 1>nul + if exist "%temp%\%_rand%_cmder_lib_pathB" del "%temp%\%_rand%_cmder_lib_pathB" 2>nul 1>nul + if exist "%temp%\%_rand%_cmder_lib_pathA" goto :toolong + if exist "%temp%\%_rand%_cmder_lib_pathB" goto :toolong + echo "%OLD_PATH%">"%temp%\%_rand%_cmder_lib_pathA" + if errorlevel 1 ( if exist "%temp%\%_rand%_cmder_lib_pathA" del "%temp%\%_rand%_cmder_lib_pathA" & goto :toolong ) + echo "%PATH%">"%temp%\%_rand%_cmder_lib_pathB" + if errorlevel 1 ( if exist "%temp%\%_rand%_cmder_lib_pathA" del "%temp%\%_rand%_cmder_lib_pathA" & if exist "%temp%\%_cmder_lib_pathB" del "%temp%\%_rand%_cmder_lib_pathB" & goto :toolong ) + fc /b "%temp%\%_rand%_cmder_lib_pathA" "%temp%\%_rand%_cmder_lib_pathB" 2>nul 1>nul + if errorlevel 1 ( del "%temp%\%_rand%_cmder_lib_pathA" & del "%temp%\%_rand%_cmder_lib_pathB" & set "_rand=" & goto :changed ) + del "%temp%\%_rand%_cmder_lib_pathA" & del "%temp%\%_rand%_cmder_lib_pathB" & set "_rand=" + exit /b + + :changed + %print_debug% :enhance_path "END Env Var - PATH=%PATH%" + %print_debug% :enhance_path "Env Var %find_query% - found=%found%" + exit /b + + exit /b + +:set_found + if "%ERRORLEVEL%" == "0" ( + set found=1 + ) + + exit /b + +:enhance_path_recursive +:::=============================================================================== +:::enhance_path_recursive - Add a directory and subs to the path env variable if +::: required. +:::. +:::include: +:::. +::: call "$0" +:::. +:::usage: +:::. +::: call "%~DP0lib_path" enhance_path_recursive "[dir_path]" [max_depth] [append] +:::. +:::required: +:::. +::: [dir_path] Fully qualified directory path. Ex: "c:\bin" +:::. +:::options: +:::. +::: [max_depth] Max recursion depth. Default: 1 +:::. +::: append Append instead to path env variable rather than pre-pend. +:::. +:::output: +:::. +::: path Sets the path env variable if required. +:::------------------------------------------------------------------------------- + if "%~1" neq "" ( + set "add_path=%~1" + ) else ( + %print_error% "You must specify a directory to add to the path!" + exit /b 1 + ) + + set "depth=%~2" + set "max_depth=%~3" + + if "%~4" neq "" if /i "%~4" == "append" ( + set "position=%~4" + ) else ( + set "position=" + ) + + dir "%add_path%" 2>NUL | findstr -i -e "%find_pathext%" >NUL + + if "%ERRORLEVEL%" == "0" ( + set "add_to_path=%add_path%" + ) else ( + set "add_to_path=" + ) + + if "%fast_init%" == "1" ( + if "%add_to_path%" neq "" ( + call :enhance_path "%add_to_path%" %position% + ) + ) + + set "PATH=%PATH:;;=;%" + if "%fast_init%" == "1" ( + exit /b + ) + + %print_debug% :enhance_path_recursive "Env Var - add_path=%add_to_path%" + %print_debug% :enhance_path_recursive "Env Var - position=%position%" + %print_debug% :enhance_path_recursive "Env Var - depth=%depth%" + %print_debug% :enhance_path_recursive "Env Var - max_depth=%max_depth%" + + if %max_depth% gtr %depth% ( + if "%add_to_path%" neq "" ( + %print_debug% :enhance_path_recursive "Adding parent directory - '%add_to_path%'" + call :enhance_path "%add_to_path%" %position% + ) + call :set_depth + call :loop_depth + ) + + set "PATH=%PATH%" + + exit /b + +:set_depth + set /a "depth=%depth%+1" + exit /b + +:loop_depth + if %depth% == %max_depth% ( + exit /b + ) + + for /d %%i in ("%add_path%\*") do ( + %print_debug% :enhance_path_recursive "Env Var BEFORE - depth=%depth%" + %print_debug% :enhance_path_recursive "Found Subdirectory - '%%~fi'" + call :enhance_path_recursive "%%~fi" %depth% %max_depth% %position% + %print_debug% :enhance_path_recursive "Env Var AFTER- depth=%depth%" + ) + exit /b diff --git a/vendor/lib/lib_profile.cmd b/vendor/lib/lib_profile.cmd index c0449b9..2a72e9d 100644 --- a/vendor/lib/lib_profile.cmd +++ b/vendor/lib/lib_profile.cmd @@ -1,45 +1,45 @@ -@echo off - -call "%~dp0lib_base.cmd" -call "%~dp0lib_console.cmd" -set lib_profile=call "%~dp0lib_profile.cmd" - -if "%~1" == "/h" ( - %lib_base% help "%~0" -) else if "%~1" neq "" ( - call :%* -) - -exit /b - -:::=============================================================================== -:::run_profile_d - Run all scripts in the passed directory path -:::. -:::include: -:::. -::: call "lib_profile.cmd" -:::. -:::usage: -:::. -::: %lib_profile% "[dir_path]" -:::. -:::required: -:::. -::: [dir_path] Fully qualified directory path containing init *.cmd|*.bat. -::: Example: "c:\bin" -:::. -::: path Sets the path env variable if required. -:::------------------------------------------------------------------------------- - -:run_profile_d - if not exist "%~1" ( - mkdir "%~1" - ) - - pushd "%~1" - for /f "usebackq" %%x in ( `dir /b *.bat *.cmd 2^>nul` ) do ( - %print_verbose% "Calling '%~1\%%x'..." - call "%~1\%%x" - ) - popd - exit /b +@echo off + +call "%~dp0lib_base.cmd" +call "%~dp0lib_console.cmd" +set lib_profile=call "%~dp0lib_profile.cmd" + +if "%~1" == "/h" ( + %lib_base% help "%~0" +) else if "%~1" neq "" ( + call :%* +) + +exit /b + +:::=============================================================================== +:::run_profile_d - Run all scripts in the passed directory path +:::. +:::include: +:::. +::: call "lib_profile.cmd" +:::. +:::usage: +:::. +::: %lib_profile% "[dir_path]" +:::. +:::required: +:::. +::: [dir_path] Fully qualified directory path containing init *.cmd|*.bat. +::: Example: "c:\bin" +:::. +::: path Sets the path env variable if required. +:::------------------------------------------------------------------------------- + +:run_profile_d + if not exist "%~1" ( + mkdir "%~1" + ) + + pushd "%~1" + for /f "usebackq" %%x in ( `dir /b *.bat *.cmd 2^>nul` ) do ( + %print_verbose% "Calling '%~1\%%x'..." + call "%~1\%%x" + ) + popd + exit /b From 9653adc5f94e3fcc9b172ceee21641fdf285564d Mon Sep 17 00:00:00 2001 From: leo-liar <25538015+leo-liar@users.noreply.github.com> Date: Thu, 6 Nov 2025 15:50:52 +0100 Subject: [PATCH 33/84] Update lib_path.cmd Fixed missing variable in temp file name --- vendor/lib/lib_path.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/lib/lib_path.cmd b/vendor/lib/lib_path.cmd index 7edb2f5..aec86ad 100644 --- a/vendor/lib/lib_path.cmd +++ b/vendor/lib/lib_path.cmd @@ -135,7 +135,7 @@ exit /b echo "%OLD_PATH%">"%temp%\%_rand%_cmder_lib_pathA" if errorlevel 1 ( if exist "%temp%\%_rand%_cmder_lib_pathA" del "%temp%\%_rand%_cmder_lib_pathA" & goto :toolong ) echo "%PATH%">"%temp%\%_rand%_cmder_lib_pathB" - if errorlevel 1 ( if exist "%temp%\%_rand%_cmder_lib_pathA" del "%temp%\%_rand%_cmder_lib_pathA" & if exist "%temp%\%_cmder_lib_pathB" del "%temp%\%_rand%_cmder_lib_pathB" & goto :toolong ) + if errorlevel 1 ( if exist "%temp%\%_rand%_cmder_lib_pathA" del "%temp%\%_rand%_cmder_lib_pathA" & if exist "%temp%\%_rand%_cmder_lib_pathB" del "%temp%\%_rand%_cmder_lib_pathB" & goto :toolong ) fc /b "%temp%\%_rand%_cmder_lib_pathA" "%temp%\%_rand%_cmder_lib_pathB" 2>nul 1>nul if errorlevel 1 ( del "%temp%\%_rand%_cmder_lib_pathA" & del "%temp%\%_rand%_cmder_lib_pathB" & set "_rand=" & goto :changed ) del "%temp%\%_rand%_cmder_lib_pathA" & del "%temp%\%_rand%_cmder_lib_pathB" & set "_rand=" From 6f6c21dcae51bbeaee0ce90efdf8da6270f285f5 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Thu, 6 Nov 2025 18:23:10 +0330 Subject: [PATCH 34/84] add missing prefix --- vendor/lib/lib_path.cmd | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vendor/lib/lib_path.cmd b/vendor/lib/lib_path.cmd index 7edb2f5..4415388 100644 --- a/vendor/lib/lib_path.cmd +++ b/vendor/lib/lib_path.cmd @@ -119,7 +119,8 @@ exit /b :end_enhance_path set "PATH=%PATH:;;=;%" - REM echo %PATH%|wc -c + REM echo %path%|wc -c + if "%fast_init%" == "1" exit /b if not "%OLD_PATH:~0,3000%" == "%OLD_PATH:~0,3001%" goto :toolong @@ -135,7 +136,7 @@ exit /b echo "%OLD_PATH%">"%temp%\%_rand%_cmder_lib_pathA" if errorlevel 1 ( if exist "%temp%\%_rand%_cmder_lib_pathA" del "%temp%\%_rand%_cmder_lib_pathA" & goto :toolong ) echo "%PATH%">"%temp%\%_rand%_cmder_lib_pathB" - if errorlevel 1 ( if exist "%temp%\%_rand%_cmder_lib_pathA" del "%temp%\%_rand%_cmder_lib_pathA" & if exist "%temp%\%_cmder_lib_pathB" del "%temp%\%_rand%_cmder_lib_pathB" & goto :toolong ) + if errorlevel 1 ( if exist "%temp%\%_rand%_cmder_lib_pathA" del "%temp%\%_rand%_cmder_lib_pathA" & if exist "%temp%\%_rand%_cmder_lib_pathB" del "%temp%\%_rand%_cmder_lib_pathB" & goto :toolong ) fc /b "%temp%\%_rand%_cmder_lib_pathA" "%temp%\%_rand%_cmder_lib_pathB" 2>nul 1>nul if errorlevel 1 ( del "%temp%\%_rand%_cmder_lib_pathA" & del "%temp%\%_rand%_cmder_lib_pathB" & set "_rand=" & goto :changed ) del "%temp%\%_rand%_cmder_lib_pathA" & del "%temp%\%_rand%_cmder_lib_pathB" & set "_rand=" From 278694285c666f963b2060af8a59a5c84dd056a2 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Thu, 6 Nov 2025 18:40:46 +0330 Subject: [PATCH 35/84] fix typo --- launcher/src/CmderLauncher.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/src/CmderLauncher.cpp b/launcher/src/CmderLauncher.cpp index 76e2243..b285a76 100644 --- a/launcher/src/CmderLauncher.cpp +++ b/launcher/src/CmderLauncher.cpp @@ -312,7 +312,7 @@ void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstr MessageBox(NULL, (GetLastError() == ERROR_ACCESS_DENIED) ? L"Failed to copy vendor/windows-terminal/settings/settings.json file to config/windows_terminal_%COMPUTERNAME%_settings.json! Access Denied." - : L"Failed to copy vendor/windows-terminal/settings/settings.json file to config/windows_teerminal_%COMPUTERNAME%_settigns.json!", MB_TITLE, MB_ICONSTOP); + : L"Failed to copy vendor/windows-terminal/settings/settings.json file to config/windows_terminal_%COMPUTERNAME%_settigns.json!", MB_TITLE, MB_ICONSTOP); exit(1); } else if (PathFileExists(conEmuDir)) @@ -361,7 +361,7 @@ void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstr MessageBox(NULL, (GetLastError() == ERROR_ACCESS_DENIED) ? L"Failed to copy vendor/windows-terminal/settings/settings.json file to config/windows_terminal_settings.json! Access Denied." - : L"Failed to copy vendor/windows-terminal/settings/settings.json file to config/windows_teerminal_settigns.json!", MB_TITLE, MB_ICONSTOP); + : L"Failed to copy vendor/windows-terminal/settings/settings.json file to config/windows_terminal_settigns.json!", MB_TITLE, MB_ICONSTOP); exit(1); } else if (PathFileExists(conEmuDir)) From 375f63ac7ec17d44e201240f29ce7fe5e0dcd3bc Mon Sep 17 00:00:00 2001 From: David Refoua Date: Thu, 6 Nov 2025 18:41:18 +0330 Subject: [PATCH 36/84] fix indentation --- launcher/src/CmderLauncher.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/src/CmderLauncher.cpp b/launcher/src/CmderLauncher.cpp index b285a76..dc40577 100644 --- a/launcher/src/CmderLauncher.cpp +++ b/launcher/src/CmderLauncher.cpp @@ -329,7 +329,7 @@ void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstr { if (!CopyFile(cpuCfgPath, cfgPath, FALSE)) { - if (PathFileExists(windowsTerminalDir)) { + if (PathFileExists(windowsTerminalDir)) { MessageBox(NULL, (GetLastError() == ERROR_ACCESS_DENIED) ? L"Failed to copy config/windows_terminal_%COMPUTERNAME%_settings.json file to vendor/windows-terminal/settings/settings.json! Access Denied." From 76711b43b420008bc806d67956caf5c33dc85573 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Thu, 6 Nov 2025 18:47:25 +0330 Subject: [PATCH 37/84] improve consistency --- scripts/build.ps1 | 22 +++++++++++----------- vendor/sources.json | 10 +++++----- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 9d484d3..813ff6f 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -55,7 +55,7 @@ Param( # Using this option will skip all downloads, if you only need to build launcher [switch]$noVendor, - + # Using this option will specify the emulator to use [none, all, conemu-maximus5, or windows-terminal] [string]$terminal = 'all', @@ -139,13 +139,13 @@ if (-not $noVendor) { foreach ($s in $sources) { if ($terminal -eq "none") { - return + continue } elseif ($s.name -eq "conemu-maximus5" -and $terminal -eq "windows-terminal") { - return + continue } elseif ($s.name -eq "windows-terminal" -and $terminal -eq "conemu-maximus5") { - return + continue } - + Write-Verbose "Getting vendored $($s.name) $($s.version)..." # We do not care about the extensions/type of archive @@ -158,12 +158,12 @@ if (-not $noVendor) { # Make Embedded Windows Terminal Portable if ($s.name -eq "windows-terminal") { - $windowTerminalFiles = resolve-path ($saveTo + "\" + $s.name + "\terminal*") - move-item -ErrorAction SilentlyContinue $windowTerminalFiles\* $s.name >$null - remove-item -ErrorAction SilentlyContinue $windowTerminalFiles >$null - write-verbose "Making Windows Terminal Portable..." - New-Item -Type Directory -Path (Join-Path $saveTo "/windows-terminal/settings") -ErrorAction SilentlyContinue >$null - New-Item -Type File -Path (Join-Path $saveTo "/windows-terminal/.portable") -ErrorAction SilentlyContinue >$null + $windowTerminalFiles = resolve-path ($saveTo + "\" + $s.name + "\terminal*") + Move-Item -ErrorAction SilentlyContinue $windowTerminalFiles\* $s.name >$null + Remove-Item -ErrorAction SilentlyContinue $windowTerminalFiles >$null + Write-Verbose "Making Windows Terminal Portable..." + New-Item -Type Directory -Path (Join-Path $saveTo "/windows-terminal/settings") -ErrorAction SilentlyContinue >$null + New-Item -Type File -Path (Join-Path $saveTo "/windows-terminal/.portable") -ErrorAction SilentlyContinue >$null } if ((Get-ChildItem $s.name).Count -eq 1) { diff --git a/vendor/sources.json b/vendor/sources.json index dae2c16..7362cc0 100644 --- a/vendor/sources.json +++ b/vendor/sources.json @@ -1,9 +1,4 @@ [ - { - "name": "windows-terminal", - "version": "1.20.11271.0", - "url": "https://github.com/microsoft/terminal/releases/download/v1.20.11271.0/Microsoft.WindowsTerminal_1.20.11271.0_x64.zip" - }, { "name": "git-for-windows", "version": "2.49.0.windows.1", @@ -19,6 +14,11 @@ "version": "23.07.24", "url": "https://github.com/Maximus5/ConEmu/releases/download/v23.07.24/ConEmuPack.230724.7z" }, + { + "name": "windows-terminal", + "version": "1.20.11271.0", + "url": "https://github.com/microsoft/terminal/releases/download/v1.20.11271.0/Microsoft.WindowsTerminal_1.20.11271.0_x64.zip" + }, { "name": "clink-completions", "version": "0.6.2", From 0cbe1e8d8c37b21b117210806f16ffcf6e6bf821 Mon Sep 17 00:00:00 2001 From: Mihai Botezatu Date: Fri, 7 Nov 2025 01:03:40 +0100 Subject: [PATCH 38/84] Wrap git_locale in quotes Without quoting, the lookup would fail for some characters --- vendor/init.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/init.bat b/vendor/init.bat index 583e0e9..3d82855 100644 --- a/vendor/init.bat +++ b/vendor/init.bat @@ -355,7 +355,7 @@ setlocal enabledelayedexpansion if defined git_locale ( REM %print_debug% init.bat "Env Var - git_locale=!git_locale!" if not defined LANG ( - for /F "delims=" %%F in ('!git_locale! -uU 2') do ( + for /F "delims=" %%F in ('"!git_locale!" -uU 2') do ( set "LANG=%%F" ) ) From fb01ee7bb971ec4b6ecb0d4dcdcec12c74d59e5a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 7 Nov 2025 14:23:28 +0000 Subject: [PATCH 39/84] Initial plan From a513d08ab89fd593ae28d9a0d09865302f8b221c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 7 Nov 2025 14:35:44 +0000 Subject: [PATCH 40/84] Add pre-release/RC version filtering to update.ps1 Co-authored-by: DRSDavidSoft <4673812+DRSDavidSoft@users.noreply.github.com> --- scripts/update.ps1 | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/scripts/update.ps1 b/scripts/update.ps1 index 768744a..3c0637b 100644 --- a/scripts/update.ps1 +++ b/scripts/update.ps1 @@ -32,7 +32,11 @@ Param( # -whatif switch to not actually make changes # Path to the vendor configuration source file - [string]$sourcesPath = "$PSScriptRoot\..\vendor\sources.json" + [string]$sourcesPath = "$PSScriptRoot\..\vendor\sources.json", + + # Include pre-release versions (RC, beta, alpha, etc.) + # By default, only stable releases are considered + [switch]$IncludePrerelease = $false ) # Get the root directory of the cmder project. @@ -83,7 +87,10 @@ function Match-Filenames { function Fetch-DownloadUrl { param ( [Parameter(Mandatory = $true)] - $urlStr + $urlStr, + + [Parameter(Mandatory = $false)] + [bool]$includePrerelease = $false ) $url = [uri] $urlStr @@ -127,6 +134,31 @@ function Fetch-DownloadUrl { } :loop foreach ($i in $info) { + # Skip pre-release versions unless explicitly included + # Pre-releases include RC (Release Candidate), beta, alpha, and other test versions + if (-not $includePrerelease) { + # Check if marked as pre-release by GitHub + if ($i.prerelease -eq $true) { + Write-Verbose "Skipping pre-release version: $($i.tag_name)" + continue + } + + # Check for common pre-release keywords in tag name + # This catches versions like v2.50.0-rc, v1.0.0-beta, v1.0.0-alpha, etc. + $prereleaseKeywords = @('-rc', '-beta', '-alpha', '-preview', '-pre') + $isPrerelease = $false + foreach ($keyword in $prereleaseKeywords) { + if ($i.tag_name -ilike "*$keyword*") { + Write-Verbose "Skipping version with pre-release keyword '$keyword': $($i.tag_name)" + $isPrerelease = $true + break + } + } + if ($isPrerelease) { + continue + } + } + if (-not ($i.assets -is [array])) { continue } @@ -215,7 +247,7 @@ foreach ($s in $sources) { Write-Verbose "Old Link: $($s.url)" - $downloadUrl = Fetch-DownloadUrl $s.url + $downloadUrl = Fetch-DownloadUrl $s.url -includePrerelease $IncludePrerelease if (($null -eq $downloadUrl) -or ($downloadUrl -eq '')) { Write-Verbose "No new links were found" From d01ab39181c6995296c0852930c1b3af4c0244f8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 7 Nov 2025 14:36:57 +0000 Subject: [PATCH 41/84] Fix pre-release filtering for archive downloads Co-authored-by: DRSDavidSoft <4673812+DRSDavidSoft@users.noreply.github.com> --- scripts/update.ps1 | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/scripts/update.ps1 b/scripts/update.ps1 index 3c0637b..84e38aa 100644 --- a/scripts/update.ps1 +++ b/scripts/update.ps1 @@ -196,12 +196,39 @@ function Fetch-DownloadUrl { # Special case for archive downloads of repository if (($null -eq $downloadLinks) -or (-not $downloadLinks)) { - if ((($p | ForEach-Object { $_.Trim('/') }) -contains "archive") -and $info[0].tag_name) { - for ($i = 0; $i -lt $p.Length; $i++) { - if ($p[$i].Trim('/') -eq "archive") { - $p[$i + 1] = $info[0].tag_name + ".zip" - $downloadLinks = $url.Scheme + "://" + $url.Host + ($p -join '') - return $downloadLinks + if ((($p | ForEach-Object { $_.Trim('/') }) -contains "archive")) { + # Find the first release that matches our pre-release filtering criteria + $selectedRelease = $null + foreach ($release in $info) { + # Apply the same filtering logic + if (-not $includePrerelease) { + if ($release.prerelease -eq $true) { + continue + } + $prereleaseKeywords = @('-rc', '-beta', '-alpha', '-preview', '-pre') + $isPrerelease = $false + foreach ($keyword in $prereleaseKeywords) { + if ($release.tag_name -ilike "*$keyword*") { + $isPrerelease = $true + break + } + } + if ($isPrerelease) { + continue + } + } + # Use the first release that passes the filter + $selectedRelease = $release + break + } + + if ($selectedRelease -and $selectedRelease.tag_name) { + for ($i = 0; $i -lt $p.Length; $i++) { + if ($p[$i].Trim('/') -eq "archive") { + $p[$i + 1] = $selectedRelease.tag_name + ".zip" + $downloadLinks = $url.Scheme + "://" + $url.Host + ($p -join '') + return $downloadLinks + } } } } From aa6b28a2b02bc2bd19328cd480793e09c7daee78 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 7 Nov 2025 14:38:56 +0000 Subject: [PATCH 42/84] Refactor: Extract pre-release check to helper function Co-authored-by: DRSDavidSoft <4673812+DRSDavidSoft@users.noreply.github.com> --- scripts/update.ps1 | 56 ++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/scripts/update.ps1 b/scripts/update.ps1 index 84e38aa..135c1e3 100644 --- a/scripts/update.ps1 +++ b/scripts/update.ps1 @@ -83,6 +83,31 @@ function Match-Filenames { return $position } +# Checks if a release is a pre-release based on GitHub API flag and version tag keywords +# Pre-release keywords include: -rc (release candidate), -beta, -alpha, -preview, -pre +function Test-IsPrerelease { + param ( + [Parameter(Mandatory = $true)] + $release + ) + + # Check if marked as pre-release by GitHub + if ($release.prerelease -eq $true) { + return $true + } + + # Check for common pre-release keywords in tag name + # This catches versions like v2.50.0-rc, v1.0.0-beta, v1.0.0-alpha, etc. + $prereleaseKeywords = @('-rc', '-beta', '-alpha', '-preview', '-pre') + foreach ($keyword in $prereleaseKeywords) { + if ($release.tag_name -ilike "*$keyword*") { + return $true + } + } + + return $false +} + # Uses the GitHub api in order to fetch the current download links for the latest releases of the repo. function Fetch-DownloadUrl { param ( @@ -137,26 +162,10 @@ function Fetch-DownloadUrl { # Skip pre-release versions unless explicitly included # Pre-releases include RC (Release Candidate), beta, alpha, and other test versions if (-not $includePrerelease) { - # Check if marked as pre-release by GitHub - if ($i.prerelease -eq $true) { + if (Test-IsPrerelease $i) { Write-Verbose "Skipping pre-release version: $($i.tag_name)" continue } - - # Check for common pre-release keywords in tag name - # This catches versions like v2.50.0-rc, v1.0.0-beta, v1.0.0-alpha, etc. - $prereleaseKeywords = @('-rc', '-beta', '-alpha', '-preview', '-pre') - $isPrerelease = $false - foreach ($keyword in $prereleaseKeywords) { - if ($i.tag_name -ilike "*$keyword*") { - Write-Verbose "Skipping version with pre-release keyword '$keyword': $($i.tag_name)" - $isPrerelease = $true - break - } - } - if ($isPrerelease) { - continue - } } if (-not ($i.assets -is [array])) { @@ -202,18 +211,7 @@ function Fetch-DownloadUrl { foreach ($release in $info) { # Apply the same filtering logic if (-not $includePrerelease) { - if ($release.prerelease -eq $true) { - continue - } - $prereleaseKeywords = @('-rc', '-beta', '-alpha', '-preview', '-pre') - $isPrerelease = $false - foreach ($keyword in $prereleaseKeywords) { - if ($release.tag_name -ilike "*$keyword*") { - $isPrerelease = $true - break - } - } - if ($isPrerelease) { + if (Test-IsPrerelease $release) { continue } } From 73739407b11d6c4211e9d77ffa02fd8253e7ee2d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 7 Nov 2025 14:40:21 +0000 Subject: [PATCH 43/84] Simplify conditional logic for better readability Co-authored-by: DRSDavidSoft <4673812+DRSDavidSoft@users.noreply.github.com> --- scripts/update.ps1 | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/scripts/update.ps1 b/scripts/update.ps1 index 135c1e3..c6b982d 100644 --- a/scripts/update.ps1 +++ b/scripts/update.ps1 @@ -161,11 +161,9 @@ function Fetch-DownloadUrl { :loop foreach ($i in $info) { # Skip pre-release versions unless explicitly included # Pre-releases include RC (Release Candidate), beta, alpha, and other test versions - if (-not $includePrerelease) { - if (Test-IsPrerelease $i) { - Write-Verbose "Skipping pre-release version: $($i.tag_name)" - continue - } + if (-not $includePrerelease -and (Test-IsPrerelease $i)) { + Write-Verbose "Skipping pre-release version: $($i.tag_name)" + continue } if (-not ($i.assets -is [array])) { @@ -210,10 +208,8 @@ function Fetch-DownloadUrl { $selectedRelease = $null foreach ($release in $info) { # Apply the same filtering logic - if (-not $includePrerelease) { - if (Test-IsPrerelease $release) { - continue - } + if (-not $includePrerelease -and (Test-IsPrerelease $release)) { + continue } # Use the first release that passes the filter $selectedRelease = $release From b20f084fbc76fd8c7fad80c87ca93a0384b27951 Mon Sep 17 00:00:00 2001 From: DRSDavidSoft <4673812+DRSDavidSoft@users.noreply.github.com> Date: Fri, 7 Nov 2025 14:59:14 +0000 Subject: [PATCH 44/84] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Update=20dependencie?= =?UTF-8?q?s=20(git-for-windows=20v2.51.2.windows.1,=20clink=20v1.8.8,=20c?= =?UTF-8?q?link-completions=20v0.6.6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vendor/sources.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/vendor/sources.json b/vendor/sources.json index b155781..7ea486f 100644 --- a/vendor/sources.json +++ b/vendor/sources.json @@ -1,22 +1,22 @@ [ { "name": "git-for-windows", - "version": "2.49.0.windows.1", - "url": "https://github.com/git-for-windows/git/releases/download/v2.49.0.windows.1/PortableGit-2.49.0-64-bit.7z.exe" + "version": "2.51.2.windows.1", + "url": "https://github.com/git-for-windows/git/releases/download/v2.51.2.windows.1/PortableGit-2.51.2-64-bit.7z.exe" }, { "name": "clink", - "version": "1.7.14", - "url": "https://github.com/chrisant996/clink/releases/download/v1.7.14/clink.1.7.14.843933.zip" + "version": "1.8.8", + "url": "https://github.com/chrisant996/clink/releases/download/v1.8.8/clink.1.8.8.a63364.zip" }, { "name": "conemu-maximus5", "version": "23.07.24", - "url": "https://github.com/Maximus5/ConEmu/releases/download/v23.07.24/ConEmuPack.230724.7z" + "url": "https://github.com/ConEmu/ConEmu/releases/download/v23.07.24/ConEmuPack.230724.7z" }, { "name": "clink-completions", - "version": "0.6.2", - "url": "https://github.com/vladimir-kotikov/clink-completions/archive/v0.6.2.zip" + "version": "0.6.6", + "url": "https://github.com/vladimir-kotikov/clink-completions/archive/v0.6.6.zip" } ] From 641a3b55fc1af3938719b57c86fe55c0b04afece Mon Sep 17 00:00:00 2001 From: DRSDavidSoft <4673812+DRSDavidSoft@users.noreply.github.com> Date: Fri, 7 Nov 2025 15:06:05 +0000 Subject: [PATCH 45/84] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Update=20dependencie?= =?UTF-8?q?s=20(windows-terminal=20v1.23.12811.0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vendor/sources.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vendor/sources.json b/vendor/sources.json index 7ea486f..f86c7fc 100644 --- a/vendor/sources.json +++ b/vendor/sources.json @@ -14,6 +14,11 @@ "version": "23.07.24", "url": "https://github.com/ConEmu/ConEmu/releases/download/v23.07.24/ConEmuPack.230724.7z" }, + { + "name": "windows-terminal", + "version": "1.23.12811.0", + "url": "https://github.com/microsoft/terminal/releases/download/v1.23.12811.0/Microsoft.WindowsTerminal_1.23.12811.0_x64.zip" + }, { "name": "clink-completions", "version": "0.6.6", From d37d173702137b1fc6325294cf78dc6d00a577fb Mon Sep 17 00:00:00 2001 From: David Refoua Date: Fri, 7 Nov 2025 19:23:30 +0330 Subject: [PATCH 46/84] Fix comment formatting in profile.ps1 --- vendor/profile.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/profile.ps1 b/vendor/profile.ps1 index 0a37534..1639e15 100644 --- a/vendor/profile.ps1 +++ b/vendor/profile.ps1 @@ -28,7 +28,7 @@ if (!$ENV:CMDER_ROOT) { # Remove trailing '\' $ENV:CMDER_ROOT = ($ENV:CMDER_ROOT).TrimEnd("\") -# -> recent PowerShell versions include PowerShellGet out of the box +# Recent PowerShell versions include PowerShellGet out of the box $moduleInstallerAvailable = [bool](Get-Command -Name 'Install-Module' -ErrorAction SilentlyContinue) # Add Cmder modules directory to the autoload path. From d7fd2244cf302661ce9cd51ca9ff3cbd13d094e5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 13:35:59 +0000 Subject: [PATCH 47/84] Initial plan From 88ca59f82e353a3ebd7f93e6429220806006b340 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 13:42:07 +0000 Subject: [PATCH 48/84] Add OSC 133 shell integration sequences for Windows Terminal PowerShell support Co-authored-by: DRSDavidSoft <4673812+DRSDavidSoft@users.noreply.github.com> --- README.md | 2 ++ vendor/profile.ps1 | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/README.md b/README.md index 72dec0e..4eec2fe 100644 --- a/README.md +++ b/README.md @@ -354,6 +354,8 @@ However, Cmder can in fact run in a variety of other terminal emulators, and eve ⚠ *Note:* Cmder includes built-in support for Windows Terminal directory tracking via OSC 9;9 sequences. This enables "Duplicate Tab" and "Split Pane" features to preserve the current working directory for both `cmd.exe` and PowerShell sessions. +⚠ *Note:* Cmder also includes built-in support for Windows Terminal shell integration via OSC 133 sequences (A, B, C) for PowerShell sessions. This enables features like command navigation (jump between commands), command selection, visual command separators, and improved command history management in Windows Terminal. + For instructions on how to integrate Cmder with your IDE, please read our [Wiki section](https://github.com/cmderdev/cmder/wiki#cmder-integration). ## Upgrading diff --git a/vendor/profile.ps1 b/vendor/profile.ps1 index 1639e15..75dc4f2 100644 --- a/vendor/profile.ps1 +++ b/vendor/profile.ps1 @@ -91,6 +91,24 @@ if (Get-Command -Name "vim" -ErrorAction SilentlyContinue) { if (Get-Module PSReadline -ErrorAction "SilentlyContinue") { Set-PSReadlineOption -ExtraPromptLineCount 1 + + # Add OSC 133;C support for Windows Terminal shell integration + # This marks the start of command output (emitted when Enter is pressed) + if ($env:WT_SESSION) { + Set-PSReadLineKeyHandler -Key Enter -ScriptBlock { + # Get the current command line + $line = $null + $cursor = $null + [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor) + + # Accept the line first + [Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine() + + # Emit OSC 133;C sequence to mark start of command output + # This is written directly to the console after the command is accepted + [Console]::Write("$([char]27)]133;C$([char]7)") + } + } } # Pre-assign default prompt hooks so the first run of cmder gets a working prompt. @@ -205,6 +223,14 @@ if ( $(Get-Command prompt).Definition -match 'PS \$\(\$executionContext.SessionS Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]27)]9;9;`"$($loc.ProviderPath)`"$([char]27)\" } + # Emit OSC 133;A sequence for Windows Terminal shell integration + # This marks the start of the prompt + # Enables features like command navigation, selection, and visual separators + # Only active in Windows Terminal ($env:WT_SESSION) + if ($env:WT_SESSION) { + Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]27)]133;A$([char]7)" + } + $host.UI.RawUI.WindowTitle = Microsoft.PowerShell.Management\Split-Path $pwd.ProviderPath -Leaf Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x200B)`r$([char]0x1B)[K" if ($lastSUCCESS -or ($LastExitCode -ne 0)) { @@ -213,6 +239,13 @@ if ( $(Get-Command prompt).Definition -match 'PS \$\(\$executionContext.SessionS PrePrompt | Microsoft.PowerShell.Utility\Write-Host -NoNewline CmderPrompt PostPrompt | Microsoft.PowerShell.Utility\Write-Host -NoNewline + + # Emit OSC 133;B sequence for Windows Terminal shell integration + # This marks the start of command input (after prompt, before user types) + if ($env:WT_SESSION) { + Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]27)]133;B$([char]7)" + } + $global:LastExitCode = $realLastExitCode return " " } From 538662ce56a8cbf8cb6edbfd8643b090681d6e44 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sat, 8 Nov 2025 17:39:50 +0330 Subject: [PATCH 49/84] improve documentation --- README.md | 2 +- vendor/profile.ps1 | 550 +++++++++++++++++++------------------ vendor/psmodules/Cmder.ps1 | 358 ++++++++++++------------ 3 files changed, 458 insertions(+), 452 deletions(-) diff --git a/README.md b/README.md index 4eec2fe..c45e254 100644 --- a/README.md +++ b/README.md @@ -354,7 +354,7 @@ However, Cmder can in fact run in a variety of other terminal emulators, and eve ⚠ *Note:* Cmder includes built-in support for Windows Terminal directory tracking via OSC 9;9 sequences. This enables "Duplicate Tab" and "Split Pane" features to preserve the current working directory for both `cmd.exe` and PowerShell sessions. -⚠ *Note:* Cmder also includes built-in support for Windows Terminal shell integration via OSC 133 sequences (A, B, C) for PowerShell sessions. This enables features like command navigation (jump between commands), command selection, visual command separators, and improved command history management in Windows Terminal. +⚠ *Note:* Cmder also includes built-in support for [Windows Terminal shell integration](https://learn.microsoft.com/en-us/windows/terminal/tutorials/shell-integration) via OSC 133 sequences (A, B, C) for PowerShell sessions. This enables features like command navigation (jump between commands), command selection, visual command separators, and improved command history management in Windows Terminal. For instructions on how to integrate Cmder with your IDE, please read our [Wiki section](https://github.com/cmderdev/cmder/wiki#cmder-integration). diff --git a/vendor/profile.ps1 b/vendor/profile.ps1 index 75dc4f2..977b8c5 100644 --- a/vendor/profile.ps1 +++ b/vendor/profile.ps1 @@ -1,272 +1,278 @@ -# Init Script for PowerShell -# Created as part of Cmder project -# NOTE: This file must be saved using UTF-8 with BOM encoding for prompt symbol to work correctly. - -# !!! THIS FILE IS OVERWRITTEN WHEN CMDER IS UPDATED -# !!! Use "%CMDER_ROOT%\config\user_profile.ps1" to add your own startup commands - -$CMDER_INIT_START = Get-Date - -# Compatibility with PS major versions <= 2 -if (!$PSScriptRoot) { - $PSScriptRoot = Split-Path $Script:MyInvocation.MyCommand.Path -} - -if ($ENV:CMDER_USER_CONFIG) { - Write-Verbose "CMDER IS ALSO USING INDIVIDUAL USER CONFIG FROM '$ENV:CMDER_USER_CONFIG'!" -} - -# We do this for Powershell as Admin Sessions because CMDER_ROOT is not being set. -if (!$ENV:CMDER_ROOT) { - if ($ENV:ConEmuDir) { - $ENV:CMDER_ROOT = Resolve-Path($ENV:ConEmuDir + "\..\..") - } else { - $ENV:CMDER_ROOT = Resolve-Path($PSScriptRoot + "\..") - } -} - -# Remove trailing '\' -$ENV:CMDER_ROOT = ($ENV:CMDER_ROOT).TrimEnd("\") - -# Recent PowerShell versions include PowerShellGet out of the box -$moduleInstallerAvailable = [bool](Get-Command -Name 'Install-Module' -ErrorAction SilentlyContinue) - -# Add Cmder modules directory to the autoload path. -$CmderModulePath = Join-path $PSScriptRoot "psmodules/" - -$CmderFunctions = Join-Path $CmderModulePath "Cmder.ps1" -. $CmderFunctions - -if(-not $moduleInstallerAvailable -and -not $env:PSModulePath.Contains($CmderModulePath) ) { - $env:PSModulePath = $env:PSModulePath.Insert(0, "$CmderModulePath;") -} - -$gitVersionVendor = (readVersion -gitPath "$ENV:CMDER_ROOT\vendor\git-for-windows\cmd") -Write-Debug "GIT VENDOR: ${gitVersionVendor}" - -# Get user installed Git Version[s] and Compare with vendored if found. -foreach ($git in (Get-Command -ErrorAction SilentlyContinue 'git')) { - Write-Debug "GIT PATH: {$git.Path}" - $gitDir = Split-Path -Path $git.Path - $gitDir = isGitShim -gitPath $gitDir - $gitVersionUser = (readVersion -gitPath $gitDir) - Write-Debug "GIT USER: ${gitVersionUser}" - - $useGitVersion = compare_git_versions -userVersion $gitVersionUser -vendorVersion $gitVersionVendor - Write-Debug "Using Git Version: ${useGitVersion}" - - # Use user installed Git - if ($null -eq $gitPathUser) { - if ($gitDir -match '\\mingw32\\bin' -or $gitDir -match '\\mingw64\\bin') { - $gitPathUser = ($gitDir.subString(0,$gitDir.Length - 12)) - } else { - $gitPathUser = ($gitDir.subString(0,$gitDir.Length - 4)) - } - } - - if ($useGitVersion -eq $gitVersionUser) { - Write-Debug "Using Git Dir: ${gitDir}" - $ENV:GIT_INSTALL_ROOT = $gitPathUser - $ENV:GIT_INSTALL_TYPE = 'USER' - break - } -} - -# User vendored Git. -if ($null -eq $ENV:GIT_INSTALL_ROOT -and $null -ne $gitVersionVendor) { - $ENV:GIT_INSTALL_ROOT = "$ENV:CMDER_ROOT\vendor\git-for-windows" - $ENV:GIT_INSTALL_TYPE = 'VENDOR' -} - -Write-Debug "GIT_INSTALL_ROOT: ${ENV:GIT_INSTALL_ROOT}" -Write-Debug "GIT_INSTALL_TYPE: ${ENV:GIT_INSTALL_TYPE}" - -if ($null -ne $ENV:GIT_INSTALL_ROOT) { - $env:Path = Configure-Git -gitRoot "$ENV:GIT_INSTALL_ROOT" -gitType $ENV:GIT_INSTALL_TYPE -gitPathUser $gitPathUser -} - -if (Get-Command -Name "vim" -ErrorAction SilentlyContinue) { - New-Alias -name "vi" -value vim -} - -if (Get-Module PSReadline -ErrorAction "SilentlyContinue") { - Set-PSReadlineOption -ExtraPromptLineCount 1 - - # Add OSC 133;C support for Windows Terminal shell integration - # This marks the start of command output (emitted when Enter is pressed) - if ($env:WT_SESSION) { - Set-PSReadLineKeyHandler -Key Enter -ScriptBlock { - # Get the current command line - $line = $null - $cursor = $null - [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor) - - # Accept the line first - [Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine() - - # Emit OSC 133;C sequence to mark start of command output - # This is written directly to the console after the command is accepted - [Console]::Write("$([char]27)]133;C$([char]7)") - } - } -} - -# Pre-assign default prompt hooks so the first run of cmder gets a working prompt. -$env:gitLoaded = $null -[ScriptBlock]$PrePrompt = {} -[ScriptBlock]$PostPrompt = {} -[ScriptBlock]$CmderPrompt = { - # Check if we're currently running under Admin privileges. - $identity = [Security.Principal.WindowsIdentity]::GetCurrent() - $principal = [Security.Principal.WindowsPrincipal] $identity - $adminRole = [Security.Principal.WindowsBuiltInRole]::Administrator - $color = "White" - if ($principal.IsInRole($adminRole)) { $color = "Red" } - $Host.UI.RawUI.ForegroundColor = "White" - Microsoft.PowerShell.Utility\Write-Host "PS " -NoNewline -ForegroundColor $color - Microsoft.PowerShell.Utility\Write-Host $pwd.ProviderPath -NoNewLine -ForegroundColor Green - checkGit($pwd.ProviderPath) - Microsoft.PowerShell.Utility\Write-Host "`nλ" -NoNewLine -ForegroundColor "DarkGray" -} - -# Enhance Path -$env:Path = "$Env:CMDER_ROOT\bin;$Env:CMDER_ROOT\vendor\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 -PathType container "$ENV:CMDER_ROOT\config\profile.d")) { - New-Item -ItemType Directory -Path "$ENV:CMDER_ROOT\config\profile.d" -} - -Push-Location $ENV:CMDER_ROOT\config\profile.d -foreach ($x in Get-ChildItem *.psm1) { - Write-Verbose "Sourcing $x" - Import-Module $x -} -foreach ($x in Get-ChildItem *.ps1) { - Write-Verbose "Sourcing $x" - . $x -} -Pop-Location - -# Drop *.ps1 files into "$ENV:CMDER_USER_CONFIG\config\profile.d" -# to source them at startup. Requires using cmder.exe /C [cmder_user_root_path] argument -if ($ENV:CMDER_USER_CONFIG -ne "" -and (Test-Path "$ENV:CMDER_USER_CONFIG\profile.d")) { - Push-Location $ENV:CMDER_USER_CONFIG\profile.d - foreach ($x in Get-ChildItem *.psm1) { - Write-Verbose "Sourcing $x" - Import-Module $x - } - foreach ($x in Get-ChildItem *.ps1) { - Write-Verbose "Sourcing $x" - . $x - } - Pop-Location -} - -# Renaming to "config\user_profile.ps1" to "user_profile.ps1" for consistency. -if (Test-Path "$env:CMDER_ROOT\config\user-profile.ps1") { - Rename-Item "$env:CMDER_ROOT\config\user-profile.ps1" user_profile.ps1 -} - -$CmderUserProfilePath = Join-Path $env:CMDER_ROOT "config\user_profile.ps1" -if (Test-Path $CmderUserProfilePath) { - # Create this file and place your own command in there. - . "$CmderUserProfilePath" # user_profile.ps1 is not a module DO NOT USE import-module -} - -if ($ENV:CMDER_USER_CONFIG) { - # Renaming to "$env:CMDER_USER_CONFIG\user-profile.ps1" to "user_profile.ps1" for consistency. - if (Test-Path "$env:CMDER_USER_CONFIG\user-profile.ps1") { - Rename-Item "$env:CMDER_USER_CONFIG\user-profile.ps1" user_profile.ps1 - } - - $env:Path = "$Env:CMDER_USER_CONFIG\bin;$env:Path" - - $CmderUserProfilePath = Join-Path $ENV:CMDER_USER_CONFIG "user_profile.ps1" - if (Test-Path $CmderUserProfilePath) { - . "$CmderUserProfilePath" # user_profile.ps1 is not a module DO NOT USE import-module - } -} - -if (-not (Test-Path $CmderUserProfilePath)) { - $CmderUserProfilePath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($CmderUserProfilePath) - Write-Host -NoNewline "`r" - Write-Host -BackgroundColor Green -ForegroundColor Black "First Run: Creating user startup file: $CmderUserProfilePath" - Copy-Item "$env:CMDER_ROOT\vendor\user_profile.ps1.default" -Destination $CmderUserProfilePath -} - -# -# Prompt Section -# Users should modify their user_profile.ps1 as it will be safe from updates. -# - -# Only set the prompt if it is currently set to the default -# This allows users to configure the prompt in their user_profile.ps1 or config\profile.d\*.ps1 -if ( $(Get-Command prompt).Definition -match 'PS \$\(\$executionContext.SessionState.Path.CurrentLocation\)\$\(' -and ` - $(Get-Command prompt).Definition -match '\(\$nestedPromptLevel \+ 1\)\) ";') { - - <# - This scriptblock runs every time the prompt is returned. - Explicitly use functions from MS namespace to protect from being overridden in the user session. - Custom prompt functions are loaded in as constants to get the same behaviour - #> - [ScriptBlock]$Prompt = { - $lastSUCCESS = $? - $realLastExitCode = $LastExitCode - - # Emit OSC 9;9 sequence for Windows Terminal directory tracking - # This enables "Duplicate Tab" and "Split Pane" to preserve the working directory - # Only active in Windows Terminal ($env:WT_SESSION) or ConEmu ($env:ConEmuPID) - $loc = $executionContext.SessionState.Path.CurrentLocation - if (($env:WT_SESSION -or $env:ConEmuPID) -and $loc.Provider.Name -eq "FileSystem") { - Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]27)]9;9;`"$($loc.ProviderPath)`"$([char]27)\" - } - - # Emit OSC 133;A sequence for Windows Terminal shell integration - # This marks the start of the prompt - # Enables features like command navigation, selection, and visual separators - # Only active in Windows Terminal ($env:WT_SESSION) - if ($env:WT_SESSION) { - Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]27)]133;A$([char]7)" - } - - $host.UI.RawUI.WindowTitle = Microsoft.PowerShell.Management\Split-Path $pwd.ProviderPath -Leaf - Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x200B)`r$([char]0x1B)[K" - if ($lastSUCCESS -or ($LastExitCode -ne 0)) { - Microsoft.PowerShell.Utility\Write-Host - } - PrePrompt | Microsoft.PowerShell.Utility\Write-Host -NoNewline - CmderPrompt - PostPrompt | Microsoft.PowerShell.Utility\Write-Host -NoNewline - - # Emit OSC 133;B sequence for Windows Terminal shell integration - # This marks the start of command input (after prompt, before user types) - if ($env:WT_SESSION) { - Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]27)]133;B$([char]7)" - } - - $global:LastExitCode = $realLastExitCode - return " " - } - - # Once Created these code blocks cannot be overwritten - # if (-not $(Get-Command PrePrompt).Options -match 'Constant') {Set-Item -Path function:\PrePrompt -Value $PrePrompt -Options Constant} - # if (-not $(Get-Command CmderPrompt).Options -match 'Constant') {Set-Item -Path function:\CmderPrompt -Value $CmderPrompt -Options Constant} - # if (-not $(Get-Command PostPrompt).Options -match 'Constant') {Set-Item -Path function:\PostPrompt -Value $PostPrompt -Options Constant} - - Set-Item -Path function:\PrePrompt -Value $PrePrompt -Options Constant - Set-Item -Path function:\CmderPrompt -Value $CmderPrompt -Options Constant - Set-Item -Path function:\PostPrompt -Value $PostPrompt -Options Constant - - # Functions can be made constant only at creation time - # ReadOnly at least requires `-force` to be overwritten - # if (!$(Get-Command Prompt).Options -match 'ReadOnly') {Set-Item -Path function:\prompt -Value $Prompt -Options ReadOnly} - Set-Item -Path function:\prompt -Value $Prompt -Options ReadOnly -} - -$CMDER_INIT_END = Get-Date - -$ElapsedTime = New-TimeSpan -Start $CMDER_INIT_START -End $CMDER_INIT_END - -Write-Verbose "Elapsed Time: $($ElapsedTime.TotalSeconds) seconds total" +# Init Script for PowerShell +# Created as part of Cmder project +# NOTE: This file must be saved using UTF-8 with BOM encoding for prompt symbol to work correctly. + +# !!! THIS FILE IS OVERWRITTEN WHEN CMDER IS UPDATED +# !!! Use "%CMDER_ROOT%\config\user_profile.ps1" to add your own startup commands + +$CMDER_INIT_START = Get-Date + +# Compatibility with PS major versions <= 2 +if (!$PSScriptRoot) { + $PSScriptRoot = Split-Path $Script:MyInvocation.MyCommand.Path +} + +if ($ENV:CMDER_USER_CONFIG) { + Write-Verbose "CMDER IS ALSO USING INDIVIDUAL USER CONFIG FROM '$ENV:CMDER_USER_CONFIG'!" +} + +# We do this for Powershell as Admin Sessions because CMDER_ROOT is not being set. +if (!$ENV:CMDER_ROOT) { + if ($ENV:ConEmuDir) { + $ENV:CMDER_ROOT = Resolve-Path($ENV:ConEmuDir + "\..\..") + } else { + $ENV:CMDER_ROOT = Resolve-Path($PSScriptRoot + "\..") + } +} + +# Remove trailing '\' +$ENV:CMDER_ROOT = ($ENV:CMDER_ROOT).TrimEnd("\") + +# Recent PowerShell versions include PowerShellGet out of the box +$moduleInstallerAvailable = [bool](Get-Command -Name 'Install-Module' -ErrorAction SilentlyContinue) + +# Add Cmder modules directory to the autoload path. +$CmderModulePath = Join-path $PSScriptRoot "psmodules/" + +# Import Cmder functions +$CmderFunctions = Join-Path $CmderModulePath "Cmder.ps1" +. $CmderFunctions + +# Configure PSModulePath to include Cmder modules if not already present +if (-not $moduleInstallerAvailable -and -not $env:PSModulePath.Contains($CmderModulePath) ) { + $env:PSModulePath = $env:PSModulePath.Insert(0, "$CmderModulePath;") +} + +# Read vendored Git Version +$gitVersionVendor = (readGitVersion -gitPath "$ENV:CMDER_ROOT\vendor\git-for-windows\cmd") +Write-Debug "GIT VENDOR: ${gitVersionVendor}" + +# Get user installed Git version(s) if found, and compare them with vendored version. +foreach ($git in (Get-Command -ErrorAction SilentlyContinue 'git')) { + Write-Debug "GIT PATH: {$git.Path}" + $gitDir = Split-Path -Path $git.Path + $gitDir = isGitShim -gitPath $gitDir + $gitVersionUser = (readGitVersion -gitPath $gitDir) + Write-Debug "GIT USER: ${gitVersionUser}" + + $useGitVersion = compare_git_versions -userVersion $gitVersionUser -vendorVersion $gitVersionVendor + Write-Debug "Using Git Version: ${useGitVersion}" + + # Use user installed Git + if ($null -eq $gitPathUser) { + if ($gitDir -match '\\mingw32\\bin' -or $gitDir -match '\\mingw64\\bin') { + $gitPathUser = ($gitDir.subString(0,$gitDir.Length - 12)) + } else { + $gitPathUser = ($gitDir.subString(0,$gitDir.Length - 4)) + } + } + + if ($useGitVersion -eq $gitVersionUser) { + Write-Debug "Using Git Dir: ${gitDir}" + $ENV:GIT_INSTALL_ROOT = $gitPathUser + $ENV:GIT_INSTALL_TYPE = 'USER' + break + } +} + +# Use vendored Git if no user Git found or user Git is older than vendored Git +if ($null -eq $ENV:GIT_INSTALL_ROOT -and $null -ne $gitVersionVendor) { + $ENV:GIT_INSTALL_ROOT = "$ENV:CMDER_ROOT\vendor\git-for-windows" + $ENV:GIT_INSTALL_TYPE = 'VENDOR' +} + +Write-Debug "GIT_INSTALL_ROOT: ${ENV:GIT_INSTALL_ROOT}" +Write-Debug "GIT_INSTALL_TYPE: ${ENV:GIT_INSTALL_TYPE}" + +if ($null -ne $ENV:GIT_INSTALL_ROOT) { + $env:Path = Configure-Git -gitRoot "$ENV:GIT_INSTALL_ROOT" -gitType $ENV:GIT_INSTALL_TYPE -gitPathUser $gitPathUser +} + +# Create 'vi' alias for 'vim' if vim is available +if (Get-Command -Name "vim" -ErrorAction SilentlyContinue) { + New-Alias -name "vi" -value vim +} + +# PSReadline configuration +if (Get-Module PSReadline -ErrorAction "SilentlyContinue") { + # Display an extra prompt line between the prompt and the command input + Set-PSReadlineOption -ExtraPromptLineCount 1 + + # Add OSC 133;C support for Windows Terminal shell integration + # This marks the start of command output (emitted when Enter is pressed) + if ($env:WT_SESSION) { + Set-PSReadLineKeyHandler -Key Enter -ScriptBlock { + # Get the current command line + $line = $null + $cursor = $null + [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor) + + # Accept the line first + [Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine() + + # Emit OSC 133;C sequence to mark start of command output + # This is written directly to the console after the command is accepted + [Console]::Write("$([char]0x1B)]133;C$([char]7)") + } + } +} + +# Pre-assign default prompt hooks so the first run of Cmder gets a working prompt +$env:gitLoaded = $null +[ScriptBlock]$PrePrompt = {} +[ScriptBlock]$PostPrompt = {} +[ScriptBlock]$CmderPrompt = { + # Check if we're currently running under Admin privileges + $identity = [Security.Principal.WindowsIdentity]::GetCurrent() + $principal = [Security.Principal.WindowsPrincipal] $identity + $adminRole = [Security.Principal.WindowsBuiltInRole]::Administrator + $color = "White" + if ($principal.IsInRole($adminRole)) { $color = "Red" } + $Host.UI.RawUI.ForegroundColor = "White" + Microsoft.PowerShell.Utility\Write-Host "PS " -NoNewline -ForegroundColor $color + Microsoft.PowerShell.Utility\Write-Host $pwd.ProviderPath -NoNewLine -ForegroundColor Green + checkGit($pwd.ProviderPath) + Microsoft.PowerShell.Utility\Write-Host "`nλ" -NoNewLine -ForegroundColor "DarkGray" +} + +# Enhance Path +$env:Path = "$Env:CMDER_ROOT\bin;$Env:CMDER_ROOT\vendor\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 -PathType container "$ENV:CMDER_ROOT\config\profile.d")) { + New-Item -ItemType Directory -Path "$ENV:CMDER_ROOT\config\profile.d" +} + +Push-Location $ENV:CMDER_ROOT\config\profile.d +foreach ($x in Get-ChildItem *.psm1) { + Write-Verbose "Sourcing $x" + Import-Module $x +} +foreach ($x in Get-ChildItem *.ps1) { + Write-Verbose "Sourcing $x" + . $x +} +Pop-Location + +# Drop *.ps1 files into "$ENV:CMDER_USER_CONFIG\config\profile.d" +# to source them at startup. Requires using cmder.exe /C [cmder_user_root_path] argument +if ($ENV:CMDER_USER_CONFIG -ne "" -and (Test-Path "$ENV:CMDER_USER_CONFIG\profile.d")) { + Push-Location $ENV:CMDER_USER_CONFIG\profile.d + foreach ($x in Get-ChildItem *.psm1) { + Write-Verbose "Sourcing $x" + Import-Module $x + } + foreach ($x in Get-ChildItem *.ps1) { + Write-Verbose "Sourcing $x" + . $x + } + Pop-Location +} + +# Renaming to "config\user_profile.ps1" to "user_profile.ps1" for consistency. +if (Test-Path "$env:CMDER_ROOT\config\user-profile.ps1") { + Rename-Item "$env:CMDER_ROOT\config\user-profile.ps1" user_profile.ps1 +} + +$CmderUserProfilePath = Join-Path $env:CMDER_ROOT "config\user_profile.ps1" +if (Test-Path $CmderUserProfilePath) { + # Create this file and place your own command in there. + . "$CmderUserProfilePath" # user_profile.ps1 is not a module DO NOT USE import-module +} + +if ($ENV:CMDER_USER_CONFIG) { + # Renaming to "$env:CMDER_USER_CONFIG\user-profile.ps1" to "user_profile.ps1" for consistency. + if (Test-Path "$env:CMDER_USER_CONFIG\user-profile.ps1") { + Rename-Item "$env:CMDER_USER_CONFIG\user-profile.ps1" user_profile.ps1 + } + + $env:Path = "$Env:CMDER_USER_CONFIG\bin;$env:Path" + + $CmderUserProfilePath = Join-Path $ENV:CMDER_USER_CONFIG "user_profile.ps1" + if (Test-Path $CmderUserProfilePath) { + . "$CmderUserProfilePath" # user_profile.ps1 is not a module DO NOT USE import-module + } +} + +if (-not (Test-Path $CmderUserProfilePath)) { + $CmderUserProfilePath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($CmderUserProfilePath) + Write-Host -NoNewline "`r" + Write-Host -BackgroundColor Green -ForegroundColor Black "First Run: Creating user startup file: $CmderUserProfilePath" + Copy-Item "$env:CMDER_ROOT\vendor\user_profile.ps1.default" -Destination $CmderUserProfilePath +} + +# +# Prompt Section +# Users should modify their user_profile.ps1 as it will be safe from updates. +# + +# Only set the prompt if it is currently set to the default +# This allows users to configure the prompt in their user_profile.ps1 or config\profile.d\*.ps1 +if ( $(Get-Command prompt).Definition -match 'PS \$\(\$executionContext.SessionState.Path.CurrentLocation\)\$\(' -and ` + $(Get-Command prompt).Definition -match '\(\$nestedPromptLevel \+ 1\)\) ";') { + + <# + This scriptblock runs every time the prompt is returned. + Explicitly use functions from MS namespace to protect from being overridden in the user session. + Custom prompt functions are loaded in as constants to get the same behaviour + #> + [ScriptBlock]$Prompt = { + $lastSUCCESS = $? + $realLastExitCode = $LastExitCode + + # Emit OSC 9;9 sequence for Windows Terminal directory tracking + # This enables "Duplicate Tab" and "Split Pane" to preserve the working directory + # Only active in Windows Terminal ($env:WT_SESSION) or ConEmu ($env:ConEmuPID) + $loc = $executionContext.SessionState.Path.CurrentLocation + if (($env:WT_SESSION -or $env:ConEmuPID) -and $loc.Provider.Name -eq "FileSystem") { + Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]9;9;`"$($loc.ProviderPath)`"$([char]0x1B)\" + } + + # Emit OSC 133;A sequence for Windows Terminal shell integration + # This marks the start of the prompt + # Enables features like command navigation, selection, and visual separators + # Only active in Windows Terminal ($env:WT_SESSION) + if ($env:WT_SESSION) { + Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;A$([char]7)" + } + + $host.UI.RawUI.WindowTitle = Microsoft.PowerShell.Management\Split-Path $pwd.ProviderPath -Leaf + Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x200B)`r$([char]0x1B)[K" + if ($lastSUCCESS -or ($LastExitCode -ne 0)) { + Microsoft.PowerShell.Utility\Write-Host + } + PrePrompt | Microsoft.PowerShell.Utility\Write-Host -NoNewline + CmderPrompt + PostPrompt | Microsoft.PowerShell.Utility\Write-Host -NoNewline + + # Emit OSC 133;B sequence for Windows Terminal shell integration + # This marks the start of command input (after prompt, before user types) + if ($env:WT_SESSION) { + Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;B$([char]7)" + } + + $global:LastExitCode = $realLastExitCode + return " " + } + + # Once Created these code blocks cannot be overwritten + # if (-not $(Get-Command PrePrompt).Options -match 'Constant') {Set-Item -Path function:\PrePrompt -Value $PrePrompt -Options Constant} + # if (-not $(Get-Command CmderPrompt).Options -match 'Constant') {Set-Item -Path function:\CmderPrompt -Value $CmderPrompt -Options Constant} + # if (-not $(Get-Command PostPrompt).Options -match 'Constant') {Set-Item -Path function:\PostPrompt -Value $PostPrompt -Options Constant} + + Set-Item -Path function:\PrePrompt -Value $PrePrompt -Options Constant + Set-Item -Path function:\CmderPrompt -Value $CmderPrompt -Options Constant + Set-Item -Path function:\PostPrompt -Value $PostPrompt -Options Constant + + # Functions can be made constant only at creation time + # ReadOnly at least requires `-force` to be overwritten + # if (!$(Get-Command Prompt).Options -match 'ReadOnly') {Set-Item -Path function:\prompt -Value $Prompt -Options ReadOnly} + Set-Item -Path function:\prompt -Value $Prompt -Options ReadOnly +} + +$CMDER_INIT_END = Get-Date + +$ElapsedTime = New-TimeSpan -Start $CMDER_INIT_START -End $CMDER_INIT_END + +Write-Verbose "Elapsed Time: $($ElapsedTime.TotalSeconds) seconds total" diff --git a/vendor/psmodules/Cmder.ps1 b/vendor/psmodules/Cmder.ps1 index e3c48d4..79c249b 100644 --- a/vendor/psmodules/Cmder.ps1 +++ b/vendor/psmodules/Cmder.ps1 @@ -1,179 +1,179 @@ -function readVersion($gitPath) { - $gitExecutable = "${gitPath}\git.exe" - - if (-not (Test-Path "$gitExecutable")) { - return $null - } - - $gitVersion = (cmd /c "${gitExecutable}" --version) - - if ($gitVersion -match 'git version') { - ($trash1, $trash2, $gitVersion) = $gitVersion.split(' ', 3) - } else { - pause - return $null - } - - return $gitVersion.toString() -} - -function isGitShim($gitPath) { - # check if there is a shim file - if yes, read the actual executable path - # See: github.com/ScoopInstaller/Shim - - if (Test-Path "${gitPath}\git.shim") { - $shim = (get-content "${gitPath}\git.shim") - ($trash, $gitPath) = $shim.replace(' ', '').split('=') - - $gitPath = $gitPath.replace('\git.exe', '') - } - - return $gitPath.toString() -} - -function compareVersions($userVersion, $vendorVersion) { - if ($null -ne $userVersion) { - ($userMajor, $userMinor, $userPatch, $userBuild) = $userVersion.split('.', 4) - } else { - return -1 - } - - if ($null -ne $vendorVersion) { - ($vendorMajor, $vendorMinor, $vendorPatch, $vendorBuild) = $vendorVersion.split('.', 4) - } else { - return 1 - } - - if (($userMajor -eq $vendorMajor) -and ($userMinor -eq $vendorMinor) -and ($userPatch -eq $vendorPatch) -and ($userBuild -eq $vendorBuild)) { - return 1 - } - - if ($userMajor -gt $vendorMajor) { return 1 } - if ($userMajor -lt $vendorMajor) { return -1 } - - if ($userMinor -gt $vendorMinor) { return 1 } - if ($userMinor -lt $vendorMinor) { return -1 } - - if ($userPatch -gt $vendorPatch) { return 1 } - if ($userPatch -lt $vendorPatch) { return -1 } - - if ($userBuild -gt $vendorBuild) { return 1 } - if ($userBuild -lt $vendorBuild) { return -1 } - - return 0 -} - -function compare_git_versions($userVersion, $vendorVersion) { - $result = compareVersions -userVersion $userVersion -vendorVersion $vendorVersion - - Write-Debug "Compare Versions Result: ${result}" - if ($result -ge 0) { - return $userVersion - } - else { - return $vendorVersion - } -} - -function Configure-Git($gitRoot, $gitType, $gitPathUser) { - # Proposed Behavior - - # Modify the path if we are using VENDORED Git, do nothing if using USER Git. - # If User Git is installed but is older, match its path config adding paths - # in the same path positions allowing a user to configure Cmder Git path - # using locally installed Git Path Config. - if ($gitType -eq 'VENDOR') { - # If User Git is installed replace its path config with Newer Vendored Git Path - if (($null -ne $gitPathUser) -and ($gitPathUser -ne '')) { - Write-Verbose "Cmder 'profile.ps1': Replacing older user Git path '$gitPathUser' with newer vendored Git path '$gitRoot' in the system path..." - - $newPath = ($env:path -ireplace [regex]::Escape($gitPathUser), $gitRoot) - } - else { - if (-not ($env:Path -match [regex]::Escape("$gitRoot\cmd"))) { - Write-Debug "Adding $gitRoot\cmd to the path" - $newPath = $($gitRoot + "\cmd" + ";" + $env:Path) - } - - # Add "$gitRoot\mingw[32|64]\bin" to the path if exists and not done already - if ((Test-Path "$gitRoot\mingw32\bin") -and -not ($env:path -match [regex]::Escape("$gitRoot\mingw32\bin"))) { - Write-Debug "Adding $gitRoot\mingw32\bin to the path" - $newPath = "$newPath;$gitRoot\mingw32\bin" - } - elseif ((Test-Path "$gitRoot\mingw64\bin") -and -not ($env:path -match [regex]::Escape("$gitRoot\mingw64\bin"))) { - Write-Debug "Adding $gitRoot\mingw64\bin to the path" - $newPath = "$newPath;$gitRoot\mingw64\bin" - } - - # Add "$gitRoot\usr\bin" to the path if exists and not done already - if ((Test-Path "$gitRoot\usr\bin") -and -not ($env:path -match [regex]::Escape("$gitRoot\usr\bin"))) { - Write-Debug "Adding $gitRoot\usr\bin to the path" - $newPath = "$newPath;$gitRoot\usr\bin" - } - } - - return $newPath - } - - return $env:path -} - -function Import-Git() { - $GitModule = Get-Module -Name Posh-Git -ListAvailable - if ($GitModule | Select-Object version | Where-Object version -le ([version]"0.6.1.20160330")) { - Import-Module Posh-Git > $null - } - if ($GitModule | Select-Object version | Where-Object version -ge ([version]"1.0.0")) { - Import-Module Posh-Git > $null - $GitPromptSettings.AnsiConsole = $false - } - if (-not $GitModule) { - Write-Host -NoNewline "`r`n" - Write-Warning "Missing git support, install posh-git with 'Install-Module posh-git' and restart Cmder." - Write-Host -NoNewline "`r$([char]0x1B)[A" - return $false - } - # Make sure we only run once by always returning true - return $true -} - -function checkGit($Path) { - if (-not (Get-Command git -ErrorAction SilentlyContinue)) { - return - } - if (-not (Test-Path -Path (Join-Path $Path '.git'))) { - $SplitPath = Split-Path $path - if ($SplitPath) { checkGit($SplitPath) } - return - } - if (getGitStatusSetting -eq $true) { - if ($null -eq $env:gitLoaded) { - $env:gitLoaded = Import-Git - } - if ($env:gitLoaded -eq $true) { - Write-VcsStatus - } - } - else { - $headContent = Get-Content (Join-Path $Path '.git/HEAD') - if ($headContent -like "ref: refs/heads/*") { - $branchName = $headContent.Substring(16) - } - else { - $branchName = "HEAD detached at $($headContent.Substring(0, 7))" - } - Write-Host " [$branchName]" -NoNewline -ForegroundColor White - } -} - -function getGitStatusSetting() { - $gitStatus = (git --no-pager config -l) | Out-String - - foreach ($line in $($gitStatus -split "`r`n")) { - if (($line -match 'cmder.status=false') -or ($line -match 'cmder.psstatus=false')) { - return $false - } - } - - return $true -} +function readGitVersion($gitPath) { + $gitExecutable = "${gitPath}\git.exe" + + if (-not (Test-Path "$gitExecutable")) { + return $null + } + + $gitVersion = (cmd /c "${gitExecutable}" --version) + + if ($gitVersion -match 'git version') { + ($trash1, $trash2, $gitVersion) = $gitVersion.split(' ', 3) + } else { + pause + return $null + } + + return $gitVersion.toString() +} + +function isGitShim($gitPath) { + # Check if there is a shim file - if yes, read the actual executable path + # See: github.com/ScoopInstaller/Shim + + if (Test-Path "${gitPath}\git.shim") { + $shim = (get-content "${gitPath}\git.shim") + ($trash, $gitPath) = $shim.replace(' ', '').split('=') + + $gitPath = $gitPath.replace('\git.exe', '') + } + + return $gitPath.toString() +} + +function compareVersions($userVersion, $vendorVersion) { + if ($null -ne $userVersion) { + ($userMajor, $userMinor, $userPatch, $userBuild) = $userVersion.split('.', 4) + } else { + return -1 + } + + if ($null -ne $vendorVersion) { + ($vendorMajor, $vendorMinor, $vendorPatch, $vendorBuild) = $vendorVersion.split('.', 4) + } else { + return 1 + } + + if (($userMajor -eq $vendorMajor) -and ($userMinor -eq $vendorMinor) -and ($userPatch -eq $vendorPatch) -and ($userBuild -eq $vendorBuild)) { + return 1 + } + + if ($userMajor -gt $vendorMajor) { return 1 } + if ($userMajor -lt $vendorMajor) { return -1 } + + if ($userMinor -gt $vendorMinor) { return 1 } + if ($userMinor -lt $vendorMinor) { return -1 } + + if ($userPatch -gt $vendorPatch) { return 1 } + if ($userPatch -lt $vendorPatch) { return -1 } + + if ($userBuild -gt $vendorBuild) { return 1 } + if ($userBuild -lt $vendorBuild) { return -1 } + + return 0 +} + +function compare_git_versions($userVersion, $vendorVersion) { + $result = compareVersions -userVersion $userVersion -vendorVersion $vendorVersion + + Write-Debug "Compare Versions Result: ${result}" + if ($result -ge 0) { + return $userVersion + } + else { + return $vendorVersion + } +} + +function Configure-Git($gitRoot, $gitType, $gitPathUser) { + # Proposed Behavior + + # Modify the path if we are using VENDORED Git, do nothing if using USER Git. + # If User Git is installed but is older, match its path config adding paths + # in the same path positions allowing a user to configure Cmder Git path + # using locally installed Git Path Config. + if ($gitType -eq 'VENDOR') { + # If User Git is installed replace its path config with Newer Vendored Git Path + if (($null -ne $gitPathUser) -and ($gitPathUser -ne '')) { + Write-Verbose "Cmder 'profile.ps1': Replacing older user Git path '$gitPathUser' with newer vendored Git path '$gitRoot' in the system path..." + + $newPath = ($env:path -ireplace [regex]::Escape($gitPathUser), $gitRoot) + } + else { + if (-not ($env:Path -match [regex]::Escape("$gitRoot\cmd"))) { + Write-Debug "Adding $gitRoot\cmd to the path" + $newPath = $($gitRoot + "\cmd" + ";" + $env:Path) + } + + # Add "$gitRoot\mingw[32|64]\bin" to the path if exists and not done already + if ((Test-Path "$gitRoot\mingw32\bin") -and -not ($env:path -match [regex]::Escape("$gitRoot\mingw32\bin"))) { + Write-Debug "Adding $gitRoot\mingw32\bin to the path" + $newPath = "$newPath;$gitRoot\mingw32\bin" + } + elseif ((Test-Path "$gitRoot\mingw64\bin") -and -not ($env:path -match [regex]::Escape("$gitRoot\mingw64\bin"))) { + Write-Debug "Adding $gitRoot\mingw64\bin to the path" + $newPath = "$newPath;$gitRoot\mingw64\bin" + } + + # Add "$gitRoot\usr\bin" to the path if exists and not done already + if ((Test-Path "$gitRoot\usr\bin") -and -not ($env:path -match [regex]::Escape("$gitRoot\usr\bin"))) { + Write-Debug "Adding $gitRoot\usr\bin to the path" + $newPath = "$newPath;$gitRoot\usr\bin" + } + } + + return $newPath + } + + return $env:path +} + +function Import-Git() { + $GitModule = Get-Module -Name Posh-Git -ListAvailable + if ($GitModule | Select-Object version | Where-Object version -le ([version]"0.6.1.20160330")) { + Import-Module Posh-Git > $null + } + if ($GitModule | Select-Object version | Where-Object version -ge ([version]"1.0.0")) { + Import-Module Posh-Git > $null + $GitPromptSettings.AnsiConsole = $false + } + if (-not $GitModule) { + Write-Host -NoNewline "`r`n" + Write-Warning "Missing git support, install posh-git with 'Install-Module posh-git' and restart Cmder." + Write-Host -NoNewline "`r$([char]0x1B)[A" + return $false + } + # Make sure we only run once by always returning true + return $true +} + +function checkGit($Path) { + if (-not (Get-Command git -ErrorAction SilentlyContinue)) { + return + } + if (-not (Test-Path -Path (Join-Path $Path '.git'))) { + $SplitPath = Split-Path $path + if ($SplitPath) { checkGit($SplitPath) } + return + } + if (getGitStatusSetting -eq $true) { + if ($null -eq $env:gitLoaded) { + $env:gitLoaded = Import-Git + } + if ($env:gitLoaded -eq $true) { + Write-VcsStatus + } + } + else { + $headContent = Get-Content (Join-Path $Path '.git/HEAD') + if ($headContent -like "ref: refs/heads/*") { + $branchName = $headContent.Substring(16) + } + else { + $branchName = "HEAD detached at $($headContent.Substring(0, 7))" + } + Write-Host " [$branchName]" -NoNewline -ForegroundColor White + } +} + +function getGitStatusSetting() { + $gitStatus = (git --no-pager config -l) | Out-String + + foreach ($line in $($gitStatus -split "`r`n")) { + if (($line -match 'cmder.status=false') -or ($line -match 'cmder.psstatus=false')) { + return $false + } + } + + return $true +} From a0d085f93eaa69c22449d0217e8daf9eaea2b180 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sat, 8 Nov 2025 20:48:07 +0330 Subject: [PATCH 50/84] fix line endings --- vendor/profile.ps1 | 556 ++++++++++++++++++------------------- vendor/psmodules/Cmder.ps1 | 358 ++++++++++++------------ 2 files changed, 457 insertions(+), 457 deletions(-) diff --git a/vendor/profile.ps1 b/vendor/profile.ps1 index 977b8c5..c77e81a 100644 --- a/vendor/profile.ps1 +++ b/vendor/profile.ps1 @@ -1,278 +1,278 @@ -# Init Script for PowerShell -# Created as part of Cmder project -# NOTE: This file must be saved using UTF-8 with BOM encoding for prompt symbol to work correctly. - -# !!! THIS FILE IS OVERWRITTEN WHEN CMDER IS UPDATED -# !!! Use "%CMDER_ROOT%\config\user_profile.ps1" to add your own startup commands - -$CMDER_INIT_START = Get-Date - -# Compatibility with PS major versions <= 2 -if (!$PSScriptRoot) { - $PSScriptRoot = Split-Path $Script:MyInvocation.MyCommand.Path -} - -if ($ENV:CMDER_USER_CONFIG) { - Write-Verbose "CMDER IS ALSO USING INDIVIDUAL USER CONFIG FROM '$ENV:CMDER_USER_CONFIG'!" -} - -# We do this for Powershell as Admin Sessions because CMDER_ROOT is not being set. -if (!$ENV:CMDER_ROOT) { - if ($ENV:ConEmuDir) { - $ENV:CMDER_ROOT = Resolve-Path($ENV:ConEmuDir + "\..\..") - } else { - $ENV:CMDER_ROOT = Resolve-Path($PSScriptRoot + "\..") - } -} - -# Remove trailing '\' -$ENV:CMDER_ROOT = ($ENV:CMDER_ROOT).TrimEnd("\") - -# Recent PowerShell versions include PowerShellGet out of the box -$moduleInstallerAvailable = [bool](Get-Command -Name 'Install-Module' -ErrorAction SilentlyContinue) - -# Add Cmder modules directory to the autoload path. -$CmderModulePath = Join-path $PSScriptRoot "psmodules/" - -# Import Cmder functions -$CmderFunctions = Join-Path $CmderModulePath "Cmder.ps1" -. $CmderFunctions - -# Configure PSModulePath to include Cmder modules if not already present -if (-not $moduleInstallerAvailable -and -not $env:PSModulePath.Contains($CmderModulePath) ) { - $env:PSModulePath = $env:PSModulePath.Insert(0, "$CmderModulePath;") -} - -# Read vendored Git Version -$gitVersionVendor = (readGitVersion -gitPath "$ENV:CMDER_ROOT\vendor\git-for-windows\cmd") -Write-Debug "GIT VENDOR: ${gitVersionVendor}" - -# Get user installed Git version(s) if found, and compare them with vendored version. -foreach ($git in (Get-Command -ErrorAction SilentlyContinue 'git')) { - Write-Debug "GIT PATH: {$git.Path}" - $gitDir = Split-Path -Path $git.Path - $gitDir = isGitShim -gitPath $gitDir - $gitVersionUser = (readGitVersion -gitPath $gitDir) - Write-Debug "GIT USER: ${gitVersionUser}" - - $useGitVersion = compare_git_versions -userVersion $gitVersionUser -vendorVersion $gitVersionVendor - Write-Debug "Using Git Version: ${useGitVersion}" - - # Use user installed Git - if ($null -eq $gitPathUser) { - if ($gitDir -match '\\mingw32\\bin' -or $gitDir -match '\\mingw64\\bin') { - $gitPathUser = ($gitDir.subString(0,$gitDir.Length - 12)) - } else { - $gitPathUser = ($gitDir.subString(0,$gitDir.Length - 4)) - } - } - - if ($useGitVersion -eq $gitVersionUser) { - Write-Debug "Using Git Dir: ${gitDir}" - $ENV:GIT_INSTALL_ROOT = $gitPathUser - $ENV:GIT_INSTALL_TYPE = 'USER' - break - } -} - -# Use vendored Git if no user Git found or user Git is older than vendored Git -if ($null -eq $ENV:GIT_INSTALL_ROOT -and $null -ne $gitVersionVendor) { - $ENV:GIT_INSTALL_ROOT = "$ENV:CMDER_ROOT\vendor\git-for-windows" - $ENV:GIT_INSTALL_TYPE = 'VENDOR' -} - -Write-Debug "GIT_INSTALL_ROOT: ${ENV:GIT_INSTALL_ROOT}" -Write-Debug "GIT_INSTALL_TYPE: ${ENV:GIT_INSTALL_TYPE}" - -if ($null -ne $ENV:GIT_INSTALL_ROOT) { - $env:Path = Configure-Git -gitRoot "$ENV:GIT_INSTALL_ROOT" -gitType $ENV:GIT_INSTALL_TYPE -gitPathUser $gitPathUser -} - -# Create 'vi' alias for 'vim' if vim is available -if (Get-Command -Name "vim" -ErrorAction SilentlyContinue) { - New-Alias -name "vi" -value vim -} - -# PSReadline configuration -if (Get-Module PSReadline -ErrorAction "SilentlyContinue") { - # Display an extra prompt line between the prompt and the command input - Set-PSReadlineOption -ExtraPromptLineCount 1 - - # Add OSC 133;C support for Windows Terminal shell integration - # This marks the start of command output (emitted when Enter is pressed) - if ($env:WT_SESSION) { - Set-PSReadLineKeyHandler -Key Enter -ScriptBlock { - # Get the current command line - $line = $null - $cursor = $null - [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor) - - # Accept the line first - [Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine() - - # Emit OSC 133;C sequence to mark start of command output - # This is written directly to the console after the command is accepted - [Console]::Write("$([char]0x1B)]133;C$([char]7)") - } - } -} - -# Pre-assign default prompt hooks so the first run of Cmder gets a working prompt -$env:gitLoaded = $null -[ScriptBlock]$PrePrompt = {} -[ScriptBlock]$PostPrompt = {} -[ScriptBlock]$CmderPrompt = { - # Check if we're currently running under Admin privileges - $identity = [Security.Principal.WindowsIdentity]::GetCurrent() - $principal = [Security.Principal.WindowsPrincipal] $identity - $adminRole = [Security.Principal.WindowsBuiltInRole]::Administrator - $color = "White" - if ($principal.IsInRole($adminRole)) { $color = "Red" } - $Host.UI.RawUI.ForegroundColor = "White" - Microsoft.PowerShell.Utility\Write-Host "PS " -NoNewline -ForegroundColor $color - Microsoft.PowerShell.Utility\Write-Host $pwd.ProviderPath -NoNewLine -ForegroundColor Green - checkGit($pwd.ProviderPath) - Microsoft.PowerShell.Utility\Write-Host "`nλ" -NoNewLine -ForegroundColor "DarkGray" -} - -# Enhance Path -$env:Path = "$Env:CMDER_ROOT\bin;$Env:CMDER_ROOT\vendor\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 -PathType container "$ENV:CMDER_ROOT\config\profile.d")) { - New-Item -ItemType Directory -Path "$ENV:CMDER_ROOT\config\profile.d" -} - -Push-Location $ENV:CMDER_ROOT\config\profile.d -foreach ($x in Get-ChildItem *.psm1) { - Write-Verbose "Sourcing $x" - Import-Module $x -} -foreach ($x in Get-ChildItem *.ps1) { - Write-Verbose "Sourcing $x" - . $x -} -Pop-Location - -# Drop *.ps1 files into "$ENV:CMDER_USER_CONFIG\config\profile.d" -# to source them at startup. Requires using cmder.exe /C [cmder_user_root_path] argument -if ($ENV:CMDER_USER_CONFIG -ne "" -and (Test-Path "$ENV:CMDER_USER_CONFIG\profile.d")) { - Push-Location $ENV:CMDER_USER_CONFIG\profile.d - foreach ($x in Get-ChildItem *.psm1) { - Write-Verbose "Sourcing $x" - Import-Module $x - } - foreach ($x in Get-ChildItem *.ps1) { - Write-Verbose "Sourcing $x" - . $x - } - Pop-Location -} - -# Renaming to "config\user_profile.ps1" to "user_profile.ps1" for consistency. -if (Test-Path "$env:CMDER_ROOT\config\user-profile.ps1") { - Rename-Item "$env:CMDER_ROOT\config\user-profile.ps1" user_profile.ps1 -} - -$CmderUserProfilePath = Join-Path $env:CMDER_ROOT "config\user_profile.ps1" -if (Test-Path $CmderUserProfilePath) { - # Create this file and place your own command in there. - . "$CmderUserProfilePath" # user_profile.ps1 is not a module DO NOT USE import-module -} - -if ($ENV:CMDER_USER_CONFIG) { - # Renaming to "$env:CMDER_USER_CONFIG\user-profile.ps1" to "user_profile.ps1" for consistency. - if (Test-Path "$env:CMDER_USER_CONFIG\user-profile.ps1") { - Rename-Item "$env:CMDER_USER_CONFIG\user-profile.ps1" user_profile.ps1 - } - - $env:Path = "$Env:CMDER_USER_CONFIG\bin;$env:Path" - - $CmderUserProfilePath = Join-Path $ENV:CMDER_USER_CONFIG "user_profile.ps1" - if (Test-Path $CmderUserProfilePath) { - . "$CmderUserProfilePath" # user_profile.ps1 is not a module DO NOT USE import-module - } -} - -if (-not (Test-Path $CmderUserProfilePath)) { - $CmderUserProfilePath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($CmderUserProfilePath) - Write-Host -NoNewline "`r" - Write-Host -BackgroundColor Green -ForegroundColor Black "First Run: Creating user startup file: $CmderUserProfilePath" - Copy-Item "$env:CMDER_ROOT\vendor\user_profile.ps1.default" -Destination $CmderUserProfilePath -} - -# -# Prompt Section -# Users should modify their user_profile.ps1 as it will be safe from updates. -# - -# Only set the prompt if it is currently set to the default -# This allows users to configure the prompt in their user_profile.ps1 or config\profile.d\*.ps1 -if ( $(Get-Command prompt).Definition -match 'PS \$\(\$executionContext.SessionState.Path.CurrentLocation\)\$\(' -and ` - $(Get-Command prompt).Definition -match '\(\$nestedPromptLevel \+ 1\)\) ";') { - - <# - This scriptblock runs every time the prompt is returned. - Explicitly use functions from MS namespace to protect from being overridden in the user session. - Custom prompt functions are loaded in as constants to get the same behaviour - #> - [ScriptBlock]$Prompt = { - $lastSUCCESS = $? - $realLastExitCode = $LastExitCode - - # Emit OSC 9;9 sequence for Windows Terminal directory tracking - # This enables "Duplicate Tab" and "Split Pane" to preserve the working directory - # Only active in Windows Terminal ($env:WT_SESSION) or ConEmu ($env:ConEmuPID) - $loc = $executionContext.SessionState.Path.CurrentLocation - if (($env:WT_SESSION -or $env:ConEmuPID) -and $loc.Provider.Name -eq "FileSystem") { - Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]9;9;`"$($loc.ProviderPath)`"$([char]0x1B)\" - } - - # Emit OSC 133;A sequence for Windows Terminal shell integration - # This marks the start of the prompt - # Enables features like command navigation, selection, and visual separators - # Only active in Windows Terminal ($env:WT_SESSION) - if ($env:WT_SESSION) { - Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;A$([char]7)" - } - - $host.UI.RawUI.WindowTitle = Microsoft.PowerShell.Management\Split-Path $pwd.ProviderPath -Leaf - Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x200B)`r$([char]0x1B)[K" - if ($lastSUCCESS -or ($LastExitCode -ne 0)) { - Microsoft.PowerShell.Utility\Write-Host - } - PrePrompt | Microsoft.PowerShell.Utility\Write-Host -NoNewline - CmderPrompt - PostPrompt | Microsoft.PowerShell.Utility\Write-Host -NoNewline - - # Emit OSC 133;B sequence for Windows Terminal shell integration - # This marks the start of command input (after prompt, before user types) - if ($env:WT_SESSION) { - Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;B$([char]7)" - } - - $global:LastExitCode = $realLastExitCode - return " " - } - - # Once Created these code blocks cannot be overwritten - # if (-not $(Get-Command PrePrompt).Options -match 'Constant') {Set-Item -Path function:\PrePrompt -Value $PrePrompt -Options Constant} - # if (-not $(Get-Command CmderPrompt).Options -match 'Constant') {Set-Item -Path function:\CmderPrompt -Value $CmderPrompt -Options Constant} - # if (-not $(Get-Command PostPrompt).Options -match 'Constant') {Set-Item -Path function:\PostPrompt -Value $PostPrompt -Options Constant} - - Set-Item -Path function:\PrePrompt -Value $PrePrompt -Options Constant - Set-Item -Path function:\CmderPrompt -Value $CmderPrompt -Options Constant - Set-Item -Path function:\PostPrompt -Value $PostPrompt -Options Constant - - # Functions can be made constant only at creation time - # ReadOnly at least requires `-force` to be overwritten - # if (!$(Get-Command Prompt).Options -match 'ReadOnly') {Set-Item -Path function:\prompt -Value $Prompt -Options ReadOnly} - Set-Item -Path function:\prompt -Value $Prompt -Options ReadOnly -} - -$CMDER_INIT_END = Get-Date - -$ElapsedTime = New-TimeSpan -Start $CMDER_INIT_START -End $CMDER_INIT_END - -Write-Verbose "Elapsed Time: $($ElapsedTime.TotalSeconds) seconds total" +# Init Script for PowerShell +# Created as part of Cmder project +# NOTE: This file must be saved using UTF-8 with BOM encoding for prompt symbol to work correctly. + +# !!! THIS FILE IS OVERWRITTEN WHEN CMDER IS UPDATED +# !!! Use "%CMDER_ROOT%\config\user_profile.ps1" to add your own startup commands + +$CMDER_INIT_START = Get-Date + +# Compatibility with PS major versions <= 2 +if (!$PSScriptRoot) { + $PSScriptRoot = Split-Path $Script:MyInvocation.MyCommand.Path +} + +if ($ENV:CMDER_USER_CONFIG) { + Write-Verbose "CMDER IS ALSO USING INDIVIDUAL USER CONFIG FROM '$ENV:CMDER_USER_CONFIG'!" +} + +# We do this for Powershell as Admin Sessions because CMDER_ROOT is not being set. +if (!$ENV:CMDER_ROOT) { + if ($ENV:ConEmuDir) { + $ENV:CMDER_ROOT = Resolve-Path($ENV:ConEmuDir + "\..\..") + } else { + $ENV:CMDER_ROOT = Resolve-Path($PSScriptRoot + "\..") + } +} + +# Remove trailing '\' +$ENV:CMDER_ROOT = ($ENV:CMDER_ROOT).TrimEnd("\") + +# Recent PowerShell versions include PowerShellGet out of the box +$moduleInstallerAvailable = [bool](Get-Command -Name 'Install-Module' -ErrorAction SilentlyContinue) + +# Add Cmder modules directory to the autoload path. +$CmderModulePath = Join-path $PSScriptRoot "psmodules/" + +# Import Cmder functions +$CmderFunctions = Join-Path $CmderModulePath "Cmder.ps1" +. $CmderFunctions + +# Configure PSModulePath to include Cmder modules if not already present +if (-not $moduleInstallerAvailable -and -not $env:PSModulePath.Contains($CmderModulePath) ) { + $env:PSModulePath = $env:PSModulePath.Insert(0, "$CmderModulePath;") +} + +# Read vendored Git Version +$gitVersionVendor = (readGitVersion -gitPath "$ENV:CMDER_ROOT\vendor\git-for-windows\cmd") +Write-Debug "GIT VENDOR: ${gitVersionVendor}" + +# Get user installed Git version(s) if found, and compare them with vendored version. +foreach ($git in (Get-Command -ErrorAction SilentlyContinue 'git')) { + Write-Debug "GIT PATH: {$git.Path}" + $gitDir = Split-Path -Path $git.Path + $gitDir = isGitShim -gitPath $gitDir + $gitVersionUser = (readGitVersion -gitPath $gitDir) + Write-Debug "GIT USER: ${gitVersionUser}" + + $useGitVersion = compare_git_versions -userVersion $gitVersionUser -vendorVersion $gitVersionVendor + Write-Debug "Using Git Version: ${useGitVersion}" + + # Use user installed Git + if ($null -eq $gitPathUser) { + if ($gitDir -match '\\mingw32\\bin' -or $gitDir -match '\\mingw64\\bin') { + $gitPathUser = ($gitDir.subString(0,$gitDir.Length - 12)) + } else { + $gitPathUser = ($gitDir.subString(0,$gitDir.Length - 4)) + } + } + + if ($useGitVersion -eq $gitVersionUser) { + Write-Debug "Using Git Dir: ${gitDir}" + $ENV:GIT_INSTALL_ROOT = $gitPathUser + $ENV:GIT_INSTALL_TYPE = 'USER' + break + } +} + +# Use vendored Git if no user Git found or user Git is older than vendored Git +if ($null -eq $ENV:GIT_INSTALL_ROOT -and $null -ne $gitVersionVendor) { + $ENV:GIT_INSTALL_ROOT = "$ENV:CMDER_ROOT\vendor\git-for-windows" + $ENV:GIT_INSTALL_TYPE = 'VENDOR' +} + +Write-Debug "GIT_INSTALL_ROOT: ${ENV:GIT_INSTALL_ROOT}" +Write-Debug "GIT_INSTALL_TYPE: ${ENV:GIT_INSTALL_TYPE}" + +if ($null -ne $ENV:GIT_INSTALL_ROOT) { + $env:Path = Configure-Git -gitRoot "$ENV:GIT_INSTALL_ROOT" -gitType $ENV:GIT_INSTALL_TYPE -gitPathUser $gitPathUser +} + +# Create 'vi' alias for 'vim' if vim is available +if (Get-Command -Name "vim" -ErrorAction SilentlyContinue) { + New-Alias -name "vi" -value vim +} + +# PSReadline configuration +if (Get-Module PSReadline -ErrorAction "SilentlyContinue") { + # Display an extra prompt line between the prompt and the command input + Set-PSReadlineOption -ExtraPromptLineCount 1 + + # Add OSC 133;C support for Windows Terminal shell integration + # This marks the start of command output (emitted when Enter is pressed) + if ($env:WT_SESSION) { + Set-PSReadLineKeyHandler -Key Enter -ScriptBlock { + # Get the current command line + $line = $null + $cursor = $null + [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor) + + # Accept the line first + [Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine() + + # Emit OSC 133;C sequence to mark start of command output + # This is written directly to the console after the command is accepted + [Console]::Write("$([char]0x1B)]133;C$([char]7)") + } + } +} + +# Pre-assign default prompt hooks so the first run of Cmder gets a working prompt +$env:gitLoaded = $null +[ScriptBlock]$PrePrompt = {} +[ScriptBlock]$PostPrompt = {} +[ScriptBlock]$CmderPrompt = { + # Check if we're currently running under Admin privileges + $identity = [Security.Principal.WindowsIdentity]::GetCurrent() + $principal = [Security.Principal.WindowsPrincipal] $identity + $adminRole = [Security.Principal.WindowsBuiltInRole]::Administrator + $color = "White" + if ($principal.IsInRole($adminRole)) { $color = "Red" } + $Host.UI.RawUI.ForegroundColor = "White" + Microsoft.PowerShell.Utility\Write-Host "PS " -NoNewline -ForegroundColor $color + Microsoft.PowerShell.Utility\Write-Host $pwd.ProviderPath -NoNewLine -ForegroundColor Green + checkGit($pwd.ProviderPath) + Microsoft.PowerShell.Utility\Write-Host "`nλ" -NoNewLine -ForegroundColor "DarkGray" +} + +# Enhance Path +$env:Path = "$Env:CMDER_ROOT\bin;$Env:CMDER_ROOT\vendor\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 -PathType container "$ENV:CMDER_ROOT\config\profile.d")) { + New-Item -ItemType Directory -Path "$ENV:CMDER_ROOT\config\profile.d" +} + +Push-Location $ENV:CMDER_ROOT\config\profile.d +foreach ($x in Get-ChildItem *.psm1) { + Write-Verbose "Sourcing $x" + Import-Module $x +} +foreach ($x in Get-ChildItem *.ps1) { + Write-Verbose "Sourcing $x" + . $x +} +Pop-Location + +# Drop *.ps1 files into "$ENV:CMDER_USER_CONFIG\config\profile.d" +# to source them at startup. Requires using cmder.exe /C [cmder_user_root_path] argument +if ($ENV:CMDER_USER_CONFIG -ne "" -and (Test-Path "$ENV:CMDER_USER_CONFIG\profile.d")) { + Push-Location $ENV:CMDER_USER_CONFIG\profile.d + foreach ($x in Get-ChildItem *.psm1) { + Write-Verbose "Sourcing $x" + Import-Module $x + } + foreach ($x in Get-ChildItem *.ps1) { + Write-Verbose "Sourcing $x" + . $x + } + Pop-Location +} + +# Renaming to "config\user_profile.ps1" to "user_profile.ps1" for consistency. +if (Test-Path "$env:CMDER_ROOT\config\user-profile.ps1") { + Rename-Item "$env:CMDER_ROOT\config\user-profile.ps1" user_profile.ps1 +} + +$CmderUserProfilePath = Join-Path $env:CMDER_ROOT "config\user_profile.ps1" +if (Test-Path $CmderUserProfilePath) { + # Create this file and place your own command in there. + . "$CmderUserProfilePath" # user_profile.ps1 is not a module DO NOT USE import-module +} + +if ($ENV:CMDER_USER_CONFIG) { + # Renaming to "$env:CMDER_USER_CONFIG\user-profile.ps1" to "user_profile.ps1" for consistency. + if (Test-Path "$env:CMDER_USER_CONFIG\user-profile.ps1") { + Rename-Item "$env:CMDER_USER_CONFIG\user-profile.ps1" user_profile.ps1 + } + + $env:Path = "$Env:CMDER_USER_CONFIG\bin;$env:Path" + + $CmderUserProfilePath = Join-Path $ENV:CMDER_USER_CONFIG "user_profile.ps1" + if (Test-Path $CmderUserProfilePath) { + . "$CmderUserProfilePath" # user_profile.ps1 is not a module DO NOT USE import-module + } +} + +if (-not (Test-Path $CmderUserProfilePath)) { + $CmderUserProfilePath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($CmderUserProfilePath) + Write-Host -NoNewline "`r" + Write-Host -BackgroundColor Green -ForegroundColor Black "First Run: Creating user startup file: $CmderUserProfilePath" + Copy-Item "$env:CMDER_ROOT\vendor\user_profile.ps1.default" -Destination $CmderUserProfilePath +} + +# +# Prompt Section +# Users should modify their user_profile.ps1 as it will be safe from updates. +# + +# Only set the prompt if it is currently set to the default +# This allows users to configure the prompt in their user_profile.ps1 or config\profile.d\*.ps1 +if ( $(Get-Command prompt).Definition -match 'PS \$\(\$executionContext.SessionState.Path.CurrentLocation\)\$\(' -and ` + $(Get-Command prompt).Definition -match '\(\$nestedPromptLevel \+ 1\)\) ";') { + + <# + This scriptblock runs every time the prompt is returned. + Explicitly use functions from MS namespace to protect from being overridden in the user session. + Custom prompt functions are loaded in as constants to get the same behaviour + #> + [ScriptBlock]$Prompt = { + $lastSUCCESS = $? + $realLastExitCode = $LastExitCode + + # Emit OSC 9;9 sequence for Windows Terminal directory tracking + # This enables "Duplicate Tab" and "Split Pane" to preserve the working directory + # Only active in Windows Terminal ($env:WT_SESSION) or ConEmu ($env:ConEmuPID) + $loc = $executionContext.SessionState.Path.CurrentLocation + if (($env:WT_SESSION -or $env:ConEmuPID) -and $loc.Provider.Name -eq "FileSystem") { + Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]9;9;`"$($loc.ProviderPath)`"$([char]0x1B)\" + } + + # Emit OSC 133;A sequence for Windows Terminal shell integration + # This marks the start of the prompt + # Enables features like command navigation, selection, and visual separators + # Only active in Windows Terminal ($env:WT_SESSION) + if ($env:WT_SESSION) { + Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;A$([char]7)" + } + + $host.UI.RawUI.WindowTitle = Microsoft.PowerShell.Management\Split-Path $pwd.ProviderPath -Leaf + Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x200B)`r$([char]0x1B)[K" + if ($lastSUCCESS -or ($LastExitCode -ne 0)) { + Microsoft.PowerShell.Utility\Write-Host + } + PrePrompt | Microsoft.PowerShell.Utility\Write-Host -NoNewline + CmderPrompt + PostPrompt | Microsoft.PowerShell.Utility\Write-Host -NoNewline + + # Emit OSC 133;B sequence for Windows Terminal shell integration + # This marks the start of command input (after prompt, before user types) + if ($env:WT_SESSION) { + Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;B$([char]7)" + } + + $global:LastExitCode = $realLastExitCode + return " " + } + + # Once Created these code blocks cannot be overwritten + # if (-not $(Get-Command PrePrompt).Options -match 'Constant') {Set-Item -Path function:\PrePrompt -Value $PrePrompt -Options Constant} + # if (-not $(Get-Command CmderPrompt).Options -match 'Constant') {Set-Item -Path function:\CmderPrompt -Value $CmderPrompt -Options Constant} + # if (-not $(Get-Command PostPrompt).Options -match 'Constant') {Set-Item -Path function:\PostPrompt -Value $PostPrompt -Options Constant} + + Set-Item -Path function:\PrePrompt -Value $PrePrompt -Options Constant + Set-Item -Path function:\CmderPrompt -Value $CmderPrompt -Options Constant + Set-Item -Path function:\PostPrompt -Value $PostPrompt -Options Constant + + # Functions can be made constant only at creation time + # ReadOnly at least requires `-force` to be overwritten + # if (!$(Get-Command Prompt).Options -match 'ReadOnly') {Set-Item -Path function:\prompt -Value $Prompt -Options ReadOnly} + Set-Item -Path function:\prompt -Value $Prompt -Options ReadOnly +} + +$CMDER_INIT_END = Get-Date + +$ElapsedTime = New-TimeSpan -Start $CMDER_INIT_START -End $CMDER_INIT_END + +Write-Verbose "Elapsed Time: $($ElapsedTime.TotalSeconds) seconds total" diff --git a/vendor/psmodules/Cmder.ps1 b/vendor/psmodules/Cmder.ps1 index 79c249b..a72da65 100644 --- a/vendor/psmodules/Cmder.ps1 +++ b/vendor/psmodules/Cmder.ps1 @@ -1,179 +1,179 @@ -function readGitVersion($gitPath) { - $gitExecutable = "${gitPath}\git.exe" - - if (-not (Test-Path "$gitExecutable")) { - return $null - } - - $gitVersion = (cmd /c "${gitExecutable}" --version) - - if ($gitVersion -match 'git version') { - ($trash1, $trash2, $gitVersion) = $gitVersion.split(' ', 3) - } else { - pause - return $null - } - - return $gitVersion.toString() -} - -function isGitShim($gitPath) { - # Check if there is a shim file - if yes, read the actual executable path - # See: github.com/ScoopInstaller/Shim - - if (Test-Path "${gitPath}\git.shim") { - $shim = (get-content "${gitPath}\git.shim") - ($trash, $gitPath) = $shim.replace(' ', '').split('=') - - $gitPath = $gitPath.replace('\git.exe', '') - } - - return $gitPath.toString() -} - -function compareVersions($userVersion, $vendorVersion) { - if ($null -ne $userVersion) { - ($userMajor, $userMinor, $userPatch, $userBuild) = $userVersion.split('.', 4) - } else { - return -1 - } - - if ($null -ne $vendorVersion) { - ($vendorMajor, $vendorMinor, $vendorPatch, $vendorBuild) = $vendorVersion.split('.', 4) - } else { - return 1 - } - - if (($userMajor -eq $vendorMajor) -and ($userMinor -eq $vendorMinor) -and ($userPatch -eq $vendorPatch) -and ($userBuild -eq $vendorBuild)) { - return 1 - } - - if ($userMajor -gt $vendorMajor) { return 1 } - if ($userMajor -lt $vendorMajor) { return -1 } - - if ($userMinor -gt $vendorMinor) { return 1 } - if ($userMinor -lt $vendorMinor) { return -1 } - - if ($userPatch -gt $vendorPatch) { return 1 } - if ($userPatch -lt $vendorPatch) { return -1 } - - if ($userBuild -gt $vendorBuild) { return 1 } - if ($userBuild -lt $vendorBuild) { return -1 } - - return 0 -} - -function compare_git_versions($userVersion, $vendorVersion) { - $result = compareVersions -userVersion $userVersion -vendorVersion $vendorVersion - - Write-Debug "Compare Versions Result: ${result}" - if ($result -ge 0) { - return $userVersion - } - else { - return $vendorVersion - } -} - -function Configure-Git($gitRoot, $gitType, $gitPathUser) { - # Proposed Behavior - - # Modify the path if we are using VENDORED Git, do nothing if using USER Git. - # If User Git is installed but is older, match its path config adding paths - # in the same path positions allowing a user to configure Cmder Git path - # using locally installed Git Path Config. - if ($gitType -eq 'VENDOR') { - # If User Git is installed replace its path config with Newer Vendored Git Path - if (($null -ne $gitPathUser) -and ($gitPathUser -ne '')) { - Write-Verbose "Cmder 'profile.ps1': Replacing older user Git path '$gitPathUser' with newer vendored Git path '$gitRoot' in the system path..." - - $newPath = ($env:path -ireplace [regex]::Escape($gitPathUser), $gitRoot) - } - else { - if (-not ($env:Path -match [regex]::Escape("$gitRoot\cmd"))) { - Write-Debug "Adding $gitRoot\cmd to the path" - $newPath = $($gitRoot + "\cmd" + ";" + $env:Path) - } - - # Add "$gitRoot\mingw[32|64]\bin" to the path if exists and not done already - if ((Test-Path "$gitRoot\mingw32\bin") -and -not ($env:path -match [regex]::Escape("$gitRoot\mingw32\bin"))) { - Write-Debug "Adding $gitRoot\mingw32\bin to the path" - $newPath = "$newPath;$gitRoot\mingw32\bin" - } - elseif ((Test-Path "$gitRoot\mingw64\bin") -and -not ($env:path -match [regex]::Escape("$gitRoot\mingw64\bin"))) { - Write-Debug "Adding $gitRoot\mingw64\bin to the path" - $newPath = "$newPath;$gitRoot\mingw64\bin" - } - - # Add "$gitRoot\usr\bin" to the path if exists and not done already - if ((Test-Path "$gitRoot\usr\bin") -and -not ($env:path -match [regex]::Escape("$gitRoot\usr\bin"))) { - Write-Debug "Adding $gitRoot\usr\bin to the path" - $newPath = "$newPath;$gitRoot\usr\bin" - } - } - - return $newPath - } - - return $env:path -} - -function Import-Git() { - $GitModule = Get-Module -Name Posh-Git -ListAvailable - if ($GitModule | Select-Object version | Where-Object version -le ([version]"0.6.1.20160330")) { - Import-Module Posh-Git > $null - } - if ($GitModule | Select-Object version | Where-Object version -ge ([version]"1.0.0")) { - Import-Module Posh-Git > $null - $GitPromptSettings.AnsiConsole = $false - } - if (-not $GitModule) { - Write-Host -NoNewline "`r`n" - Write-Warning "Missing git support, install posh-git with 'Install-Module posh-git' and restart Cmder." - Write-Host -NoNewline "`r$([char]0x1B)[A" - return $false - } - # Make sure we only run once by always returning true - return $true -} - -function checkGit($Path) { - if (-not (Get-Command git -ErrorAction SilentlyContinue)) { - return - } - if (-not (Test-Path -Path (Join-Path $Path '.git'))) { - $SplitPath = Split-Path $path - if ($SplitPath) { checkGit($SplitPath) } - return - } - if (getGitStatusSetting -eq $true) { - if ($null -eq $env:gitLoaded) { - $env:gitLoaded = Import-Git - } - if ($env:gitLoaded -eq $true) { - Write-VcsStatus - } - } - else { - $headContent = Get-Content (Join-Path $Path '.git/HEAD') - if ($headContent -like "ref: refs/heads/*") { - $branchName = $headContent.Substring(16) - } - else { - $branchName = "HEAD detached at $($headContent.Substring(0, 7))" - } - Write-Host " [$branchName]" -NoNewline -ForegroundColor White - } -} - -function getGitStatusSetting() { - $gitStatus = (git --no-pager config -l) | Out-String - - foreach ($line in $($gitStatus -split "`r`n")) { - if (($line -match 'cmder.status=false') -or ($line -match 'cmder.psstatus=false')) { - return $false - } - } - - return $true -} +function readGitVersion($gitPath) { + $gitExecutable = "${gitPath}\git.exe" + + if (-not (Test-Path "$gitExecutable")) { + return $null + } + + $gitVersion = (cmd /c "${gitExecutable}" --version) + + if ($gitVersion -match 'git version') { + ($trash1, $trash2, $gitVersion) = $gitVersion.split(' ', 3) + } else { + pause + return $null + } + + return $gitVersion.toString() +} + +function isGitShim($gitPath) { + # Check if there is a shim file - if yes, read the actual executable path + # See: github.com/ScoopInstaller/Shim + + if (Test-Path "${gitPath}\git.shim") { + $shim = (get-content "${gitPath}\git.shim") + ($trash, $gitPath) = $shim.replace(' ', '').split('=') + + $gitPath = $gitPath.replace('\git.exe', '') + } + + return $gitPath.toString() +} + +function compareVersions($userVersion, $vendorVersion) { + if ($null -ne $userVersion) { + ($userMajor, $userMinor, $userPatch, $userBuild) = $userVersion.split('.', 4) + } else { + return -1 + } + + if ($null -ne $vendorVersion) { + ($vendorMajor, $vendorMinor, $vendorPatch, $vendorBuild) = $vendorVersion.split('.', 4) + } else { + return 1 + } + + if (($userMajor -eq $vendorMajor) -and ($userMinor -eq $vendorMinor) -and ($userPatch -eq $vendorPatch) -and ($userBuild -eq $vendorBuild)) { + return 1 + } + + if ($userMajor -gt $vendorMajor) { return 1 } + if ($userMajor -lt $vendorMajor) { return -1 } + + if ($userMinor -gt $vendorMinor) { return 1 } + if ($userMinor -lt $vendorMinor) { return -1 } + + if ($userPatch -gt $vendorPatch) { return 1 } + if ($userPatch -lt $vendorPatch) { return -1 } + + if ($userBuild -gt $vendorBuild) { return 1 } + if ($userBuild -lt $vendorBuild) { return -1 } + + return 0 +} + +function compare_git_versions($userVersion, $vendorVersion) { + $result = compareVersions -userVersion $userVersion -vendorVersion $vendorVersion + + Write-Debug "Compare Versions Result: ${result}" + if ($result -ge 0) { + return $userVersion + } + else { + return $vendorVersion + } +} + +function Configure-Git($gitRoot, $gitType, $gitPathUser) { + # Proposed Behavior + + # Modify the path if we are using VENDORED Git, do nothing if using USER Git. + # If User Git is installed but is older, match its path config adding paths + # in the same path positions allowing a user to configure Cmder Git path + # using locally installed Git Path Config. + if ($gitType -eq 'VENDOR') { + # If User Git is installed replace its path config with Newer Vendored Git Path + if (($null -ne $gitPathUser) -and ($gitPathUser -ne '')) { + Write-Verbose "Cmder 'profile.ps1': Replacing older user Git path '$gitPathUser' with newer vendored Git path '$gitRoot' in the system path..." + + $newPath = ($env:path -ireplace [regex]::Escape($gitPathUser), $gitRoot) + } + else { + if (-not ($env:Path -match [regex]::Escape("$gitRoot\cmd"))) { + Write-Debug "Adding $gitRoot\cmd to the path" + $newPath = $($gitRoot + "\cmd" + ";" + $env:Path) + } + + # Add "$gitRoot\mingw[32|64]\bin" to the path if exists and not done already + if ((Test-Path "$gitRoot\mingw32\bin") -and -not ($env:path -match [regex]::Escape("$gitRoot\mingw32\bin"))) { + Write-Debug "Adding $gitRoot\mingw32\bin to the path" + $newPath = "$newPath;$gitRoot\mingw32\bin" + } + elseif ((Test-Path "$gitRoot\mingw64\bin") -and -not ($env:path -match [regex]::Escape("$gitRoot\mingw64\bin"))) { + Write-Debug "Adding $gitRoot\mingw64\bin to the path" + $newPath = "$newPath;$gitRoot\mingw64\bin" + } + + # Add "$gitRoot\usr\bin" to the path if exists and not done already + if ((Test-Path "$gitRoot\usr\bin") -and -not ($env:path -match [regex]::Escape("$gitRoot\usr\bin"))) { + Write-Debug "Adding $gitRoot\usr\bin to the path" + $newPath = "$newPath;$gitRoot\usr\bin" + } + } + + return $newPath + } + + return $env:path +} + +function Import-Git() { + $GitModule = Get-Module -Name Posh-Git -ListAvailable + if ($GitModule | Select-Object version | Where-Object version -le ([version]"0.6.1.20160330")) { + Import-Module Posh-Git > $null + } + if ($GitModule | Select-Object version | Where-Object version -ge ([version]"1.0.0")) { + Import-Module Posh-Git > $null + $GitPromptSettings.AnsiConsole = $false + } + if (-not $GitModule) { + Write-Host -NoNewline "`r`n" + Write-Warning "Missing git support, install posh-git with 'Install-Module posh-git' and restart Cmder." + Write-Host -NoNewline "`r$([char]0x1B)[A" + return $false + } + # Make sure we only run once by always returning true + return $true +} + +function checkGit($Path) { + if (-not (Get-Command git -ErrorAction SilentlyContinue)) { + return + } + if (-not (Test-Path -Path (Join-Path $Path '.git'))) { + $SplitPath = Split-Path $path + if ($SplitPath) { checkGit($SplitPath) } + return + } + if (getGitStatusSetting -eq $true) { + if ($null -eq $env:gitLoaded) { + $env:gitLoaded = Import-Git + } + if ($env:gitLoaded -eq $true) { + Write-VcsStatus + } + } + else { + $headContent = Get-Content (Join-Path $Path '.git/HEAD') + if ($headContent -like "ref: refs/heads/*") { + $branchName = $headContent.Substring(16) + } + else { + $branchName = "HEAD detached at $($headContent.Substring(0, 7))" + } + Write-Host " [$branchName]" -NoNewline -ForegroundColor White + } +} + +function getGitStatusSetting() { + $gitStatus = (git --no-pager config -l) | Out-String + + foreach ($line in $($gitStatus -split "`r`n")) { + if (($line -match 'cmder.status=false') -or ($line -match 'cmder.psstatus=false')) { + return $false + } + } + + return $true +} From ca068f569675b8bc4d8e68210476e584fb417f92 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 17:22:50 +0000 Subject: [PATCH 51/84] Initial plan From 96842bf09e78e9f94636074c086160dcfec358e2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 17:29:08 +0000 Subject: [PATCH 52/84] Refactor Cmder.ps1 with PowerShell naming conventions and optimizations Co-authored-by: DRSDavidSoft <4673812+DRSDavidSoft@users.noreply.github.com> --- vendor/profile.ps1 | 12 +- vendor/psmodules/Cmder.ps1 | 259 ++++++++++++++++++++----------------- 2 files changed, 145 insertions(+), 126 deletions(-) diff --git a/vendor/profile.ps1 b/vendor/profile.ps1 index c77e81a..99426e4 100644 --- a/vendor/profile.ps1 +++ b/vendor/profile.ps1 @@ -44,18 +44,18 @@ if (-not $moduleInstallerAvailable -and -not $env:PSModulePath.Contains($CmderMo } # Read vendored Git Version -$gitVersionVendor = (readGitVersion -gitPath "$ENV:CMDER_ROOT\vendor\git-for-windows\cmd") +$gitVersionVendor = Get-GitVersion -GitPath "$ENV:CMDER_ROOT\vendor\git-for-windows\cmd" Write-Debug "GIT VENDOR: ${gitVersionVendor}" # Get user installed Git version(s) if found, and compare them with vendored version. foreach ($git in (Get-Command -ErrorAction SilentlyContinue 'git')) { Write-Debug "GIT PATH: {$git.Path}" $gitDir = Split-Path -Path $git.Path - $gitDir = isGitShim -gitPath $gitDir - $gitVersionUser = (readGitVersion -gitPath $gitDir) + $gitDir = Get-GitShimPath -GitPath $gitDir + $gitVersionUser = Get-GitVersion -GitPath $gitDir Write-Debug "GIT USER: ${gitVersionUser}" - $useGitVersion = compare_git_versions -userVersion $gitVersionUser -vendorVersion $gitVersionVendor + $useGitVersion = Compare-GitVersion -UserVersion $gitVersionUser -VendorVersion $gitVersionVendor Write-Debug "Using Git Version: ${useGitVersion}" # Use user installed Git @@ -85,7 +85,7 @@ Write-Debug "GIT_INSTALL_ROOT: ${ENV:GIT_INSTALL_ROOT}" Write-Debug "GIT_INSTALL_TYPE: ${ENV:GIT_INSTALL_TYPE}" if ($null -ne $ENV:GIT_INSTALL_ROOT) { - $env:Path = Configure-Git -gitRoot "$ENV:GIT_INSTALL_ROOT" -gitType $ENV:GIT_INSTALL_TYPE -gitPathUser $gitPathUser + $env:Path = Set-GitPath -GitRoot "$ENV:GIT_INSTALL_ROOT" -GitType $ENV:GIT_INSTALL_TYPE -GitPathUser $gitPathUser } # Create 'vi' alias for 'vim' if vim is available @@ -131,7 +131,7 @@ $env:gitLoaded = $null $Host.UI.RawUI.ForegroundColor = "White" Microsoft.PowerShell.Utility\Write-Host "PS " -NoNewline -ForegroundColor $color Microsoft.PowerShell.Utility\Write-Host $pwd.ProviderPath -NoNewLine -ForegroundColor Green - checkGit($pwd.ProviderPath) + Show-GitStatus -Path $pwd.ProviderPath Microsoft.PowerShell.Utility\Write-Host "`nλ" -NoNewLine -ForegroundColor "DarkGray" } diff --git a/vendor/psmodules/Cmder.ps1 b/vendor/psmodules/Cmder.ps1 index a72da65..fb703a5 100644 --- a/vendor/psmodules/Cmder.ps1 +++ b/vendor/psmodules/Cmder.ps1 @@ -1,178 +1,197 @@ -function readGitVersion($gitPath) { - $gitExecutable = "${gitPath}\git.exe" +function Get-GitVersion { + param( + [Parameter(Mandatory = $true)] + [string]$GitPath + ) - if (-not (Test-Path "$gitExecutable")) { + $gitExecutable = Join-Path $GitPath "git.exe" + + if (-not (Test-Path $gitExecutable)) { return $null } - $gitVersion = (cmd /c "${gitExecutable}" --version) + $gitVersion = & $gitExecutable --version 2>$null - if ($gitVersion -match 'git version') { - ($trash1, $trash2, $gitVersion) = $gitVersion.split(' ', 3) - } else { - pause - return $null + if ($gitVersion -match 'git version\s+(\S+)') { + return $Matches[1] } - return $gitVersion.toString() + return $null } -function isGitShim($gitPath) { - # Check if there is a shim file - if yes, read the actual executable path - # See: github.com/ScoopInstaller/Shim +function Get-GitShimPath { + param( + [Parameter(Mandatory = $true)] + [string]$GitPath + ) - if (Test-Path "${gitPath}\git.shim") { - $shim = (get-content "${gitPath}\git.shim") - ($trash, $gitPath) = $shim.replace(' ', '').split('=') - - $gitPath = $gitPath.replace('\git.exe', '') + $shimFile = Join-Path $GitPath "git.shim" + if (Test-Path $shimFile) { + $shimContent = Get-Content $shimFile -Raw + if ($shimContent -match 'path\s*=\s*(.+)') { + $GitPath = $Matches[1].Trim().Replace('\git.exe', '') + } } - return $gitPath.toString() + return $GitPath } -function compareVersions($userVersion, $vendorVersion) { - if ($null -ne $userVersion) { - ($userMajor, $userMinor, $userPatch, $userBuild) = $userVersion.split('.', 4) - } else { - return -1 +function Compare-Version { + param( + [Parameter(Mandatory = $false)] + [AllowNull()] + [string]$UserVersion, + [Parameter(Mandatory = $false)] + [AllowNull()] + [string]$VendorVersion + ) + + if ($null -eq $UserVersion) { return -1 } + if ($null -eq $VendorVersion) { return 1 } + + try { + $userVer = [version]$UserVersion + $vendorVer = [version]$VendorVersion + return $userVer.CompareTo($vendorVer) + } catch { + # Fallback to string comparison if version parsing fails + return [string]::Compare($UserVersion, $VendorVersion) } - - if ($null -ne $vendorVersion) { - ($vendorMajor, $vendorMinor, $vendorPatch, $vendorBuild) = $vendorVersion.split('.', 4) - } else { - return 1 - } - - if (($userMajor -eq $vendorMajor) -and ($userMinor -eq $vendorMinor) -and ($userPatch -eq $vendorPatch) -and ($userBuild -eq $vendorBuild)) { - return 1 - } - - if ($userMajor -gt $vendorMajor) { return 1 } - if ($userMajor -lt $vendorMajor) { return -1 } - - if ($userMinor -gt $vendorMinor) { return 1 } - if ($userMinor -lt $vendorMinor) { return -1 } - - if ($userPatch -gt $vendorPatch) { return 1 } - if ($userPatch -lt $vendorPatch) { return -1 } - - if ($userBuild -gt $vendorBuild) { return 1 } - if ($userBuild -lt $vendorBuild) { return -1 } - - return 0 } -function compare_git_versions($userVersion, $vendorVersion) { - $result = compareVersions -userVersion $userVersion -vendorVersion $vendorVersion +function Compare-GitVersion { + param( + [Parameter(Mandatory = $false)] + [AllowNull()] + [string]$UserVersion, + [Parameter(Mandatory = $false)] + [AllowNull()] + [string]$VendorVersion + ) - Write-Debug "Compare Versions Result: ${result}" + $result = Compare-Version -UserVersion $UserVersion -VendorVersion $VendorVersion + + Write-Debug "Compare Versions Result: $result" if ($result -ge 0) { - return $userVersion - } - else { - return $vendorVersion + return $UserVersion } + return $VendorVersion } -function Configure-Git($gitRoot, $gitType, $gitPathUser) { - # Proposed Behavior +function Set-GitPath { + param( + [Parameter(Mandatory = $true)] + [string]$GitRoot, + [Parameter(Mandatory = $true)] + [string]$GitType, + [Parameter(Mandatory = $false)] + [string]$GitPathUser + ) - # Modify the path if we are using VENDORED Git, do nothing if using USER Git. - # If User Git is installed but is older, match its path config adding paths - # in the same path positions allowing a user to configure Cmder Git path - # using locally installed Git Path Config. - if ($gitType -eq 'VENDOR') { - # If User Git is installed replace its path config with Newer Vendored Git Path - if (($null -ne $gitPathUser) -and ($gitPathUser -ne '')) { - Write-Verbose "Cmder 'profile.ps1': Replacing older user Git path '$gitPathUser' with newer vendored Git path '$gitRoot' in the system path..." + if ($GitType -ne 'VENDOR') { + return $env:Path + } - $newPath = ($env:path -ireplace [regex]::Escape($gitPathUser), $gitRoot) + $newPath = $env:Path + + # Replace user Git path with vendored Git if user path exists + if ($GitPathUser) { + Write-Verbose "Cmder 'profile.ps1': Replacing older user Git path '$GitPathUser' with newer vendored Git path '$GitRoot' in the system path..." + $newPath = $newPath -ireplace [regex]::Escape($GitPathUser), $GitRoot + } else { + # Add Git cmd directory + $gitCmd = Join-Path $GitRoot "cmd" + if (-not ($newPath -match [regex]::Escape($gitCmd))) { + Write-Debug "Adding $gitCmd to the path" + $newPath = "$gitCmd;$newPath" } - else { - if (-not ($env:Path -match [regex]::Escape("$gitRoot\cmd"))) { - Write-Debug "Adding $gitRoot\cmd to the path" - $newPath = $($gitRoot + "\cmd" + ";" + $env:Path) - } - # Add "$gitRoot\mingw[32|64]\bin" to the path if exists and not done already - if ((Test-Path "$gitRoot\mingw32\bin") -and -not ($env:path -match [regex]::Escape("$gitRoot\mingw32\bin"))) { - Write-Debug "Adding $gitRoot\mingw32\bin to the path" - $newPath = "$newPath;$gitRoot\mingw32\bin" - } - elseif ((Test-Path "$gitRoot\mingw64\bin") -and -not ($env:path -match [regex]::Escape("$gitRoot\mingw64\bin"))) { - Write-Debug "Adding $gitRoot\mingw64\bin to the path" - $newPath = "$newPath;$gitRoot\mingw64\bin" - } - - # Add "$gitRoot\usr\bin" to the path if exists and not done already - if ((Test-Path "$gitRoot\usr\bin") -and -not ($env:path -match [regex]::Escape("$gitRoot\usr\bin"))) { - Write-Debug "Adding $gitRoot\usr\bin to the path" - $newPath = "$newPath;$gitRoot\usr\bin" + # Add mingw bin directory + foreach ($mingw in @('mingw64', 'mingw32')) { + $mingwBin = Join-Path $GitRoot "$mingw\bin" + if ((Test-Path $mingwBin) -and -not ($newPath -match [regex]::Escape($mingwBin))) { + Write-Debug "Adding $mingwBin to the path" + $newPath = "$newPath;$mingwBin" + break } } - return $newPath + # Add usr bin directory + $usrBin = Join-Path $GitRoot "usr\bin" + if ((Test-Path $usrBin) -and -not ($newPath -match [regex]::Escape($usrBin))) { + Write-Debug "Adding $usrBin to the path" + $newPath = "$newPath;$usrBin" + } } - return $env:path + return $newPath } -function Import-Git() { - $GitModule = Get-Module -Name Posh-Git -ListAvailable - if ($GitModule | Select-Object version | Where-Object version -le ([version]"0.6.1.20160330")) { - Import-Module Posh-Git > $null - } - if ($GitModule | Select-Object version | Where-Object version -ge ([version]"1.0.0")) { - Import-Module Posh-Git > $null - $GitPromptSettings.AnsiConsole = $false - } - if (-not $GitModule) { - Write-Host -NoNewline "`r`n" +function Import-Git { + $gitModule = Get-Module -Name Posh-Git -ListAvailable + + if (-not $gitModule) { + Microsoft.PowerShell.Utility\Write-Host -NoNewline "`r`n" Write-Warning "Missing git support, install posh-git with 'Install-Module posh-git' and restart Cmder." - Write-Host -NoNewline "`r$([char]0x1B)[A" + Microsoft.PowerShell.Utility\Write-Host -NoNewline "`r$([char]0x1B)[A" return $false } - # Make sure we only run once by always returning true + + Import-Module Posh-Git -ErrorAction SilentlyContinue | Out-Null + + if (($gitModule.Version -ge [version]"1.0.0") -and (Get-Variable -Name GitPromptSettings -ErrorAction SilentlyContinue)) { + $GitPromptSettings.AnsiConsole = $false + } + return $true } -function checkGit($Path) { +function Show-GitStatus { + param( + [Parameter(Mandatory = $true)] + [string]$Path + ) + if (-not (Get-Command git -ErrorAction SilentlyContinue)) { return } - if (-not (Test-Path -Path (Join-Path $Path '.git'))) { - $SplitPath = Split-Path $path - if ($SplitPath) { checkGit($SplitPath) } + + $gitDir = Join-Path $Path '.git' + if (-not (Test-Path $gitDir)) { + $parentPath = Split-Path $Path + if ($parentPath) { + Show-GitStatus -Path $parentPath + } return } - if (getGitStatusSetting -eq $true) { + + if (Get-GitStatusSetting) { if ($null -eq $env:gitLoaded) { $env:gitLoaded = Import-Git } if ($env:gitLoaded -eq $true) { Write-VcsStatus } - } - else { - $headContent = Get-Content (Join-Path $Path '.git/HEAD') - if ($headContent -like "ref: refs/heads/*") { - $branchName = $headContent.Substring(16) + } else { + $headFile = Join-Path $gitDir 'HEAD' + if (Test-Path $headFile) { + $headContent = Get-Content $headFile -Raw + if ($headContent -match 'ref: refs/heads/(.+)') { + $branchName = $Matches[1].Trim() + } else { + $shortHash = $headContent.Substring(0, [Math]::Min(7, $headContent.Length)) + $branchName = "HEAD detached at $shortHash" + } + Microsoft.PowerShell.Utility\Write-Host " [$branchName]" -NoNewline -ForegroundColor White } - else { - $branchName = "HEAD detached at $($headContent.Substring(0, 7))" - } - Write-Host " [$branchName]" -NoNewline -ForegroundColor White } } -function getGitStatusSetting() { - $gitStatus = (git --no-pager config -l) | Out-String +function Get-GitStatusSetting { + $gitConfig = git --no-pager config -l 2>$null | Out-String - foreach ($line in $($gitStatus -split "`r`n")) { - if (($line -match 'cmder.status=false') -or ($line -match 'cmder.psstatus=false')) { - return $false - } + if ($gitConfig -match 'cmder\.(ps)?status=false') { + return $false } return $true From b0ab14d29f943b04d82e070e6e182572cce3167f Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sat, 8 Nov 2025 21:06:07 +0330 Subject: [PATCH 53/84] Ignore whitespace-only .ps1 commits in blame --- .git-blame-ignore-revs | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .git-blame-ignore-revs diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 0000000..a0fc1c3 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,10 @@ +46f6f677dc362c0695607be5f28b8b94114fc4bc +58db4e3419bf1e5cc1bb61fcd7ce2ebbca89243a +efb3338f5cf0eec21e8a75abc62ee14965cb4a7e +efb3338f5cf0eec21e8a75abc62ee14965cb4a7e +3859f6ffc088b2ae78748abc84986f4adcadcd41 +d6569192fc91167f555c3eff58402ff01f1197ea +67de97a492c9389f95499db38f9474a1c20ec585 +a0d085f93eaa69c22449d0217e8daf9eaea2b180 +a0d085f93eaa69c22449d0217e8daf9eaea2b180 +1cfba25beb46c74bb1debca2bcfe7ac470e96172 From 081e818465d904ef3b22eff87b08e22df0d2b3c5 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sat, 8 Nov 2025 21:07:27 +0330 Subject: [PATCH 54/84] Ignore whitespace-only .cmd commits in blame --- .git-blame-ignore-revs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index a0fc1c3..6768f0c 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -8,3 +8,12 @@ d6569192fc91167f555c3eff58402ff01f1197ea a0d085f93eaa69c22449d0217e8daf9eaea2b180 a0d085f93eaa69c22449d0217e8daf9eaea2b180 1cfba25beb46c74bb1debca2bcfe7ac470e96172 +f6bc623284914489e891bbac923feb774c862b99 +abbab3f8b477e917d0a175d0de23cce121096631 +f6bc623284914489e891bbac923feb774c862b99 +e3d9f81e25b6b6062c372e6461dbeb1d19751a03 +f6bc623284914489e891bbac923feb774c862b99 +126347025f9cade241beff182738b2527da7535e +e3d9f81e25b6b6062c372e6461dbeb1d19751a03 +f6bc623284914489e891bbac923feb774c862b99 +e3d9f81e25b6b6062c372e6461dbeb1d19751a03 From f91d0bd5baa606cfe38c733fc26dbc9da295403a Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sat, 8 Nov 2025 21:14:51 +0330 Subject: [PATCH 55/84] Refactor .git-blame-ignore-revs for clarity Updated the .git-blame-ignore-revs file to include comments and remove duplicate entries. --- .git-blame-ignore-revs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 6768f0c..0f94249 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1,19 +1,12 @@ -46f6f677dc362c0695607be5f28b8b94114fc4bc +# List of whitespace-only commits to ignore in the Git blame; +# to improve tracking changes and avoid noise 58db4e3419bf1e5cc1bb61fcd7ce2ebbca89243a efb3338f5cf0eec21e8a75abc62ee14965cb4a7e -efb3338f5cf0eec21e8a75abc62ee14965cb4a7e 3859f6ffc088b2ae78748abc84986f4adcadcd41 d6569192fc91167f555c3eff58402ff01f1197ea 67de97a492c9389f95499db38f9474a1c20ec585 a0d085f93eaa69c22449d0217e8daf9eaea2b180 -a0d085f93eaa69c22449d0217e8daf9eaea2b180 1cfba25beb46c74bb1debca2bcfe7ac470e96172 f6bc623284914489e891bbac923feb774c862b99 abbab3f8b477e917d0a175d0de23cce121096631 -f6bc623284914489e891bbac923feb774c862b99 -e3d9f81e25b6b6062c372e6461dbeb1d19751a03 -f6bc623284914489e891bbac923feb774c862b99 126347025f9cade241beff182738b2527da7535e -e3d9f81e25b6b6062c372e6461dbeb1d19751a03 -f6bc623284914489e891bbac923feb774c862b99 -e3d9f81e25b6b6062c372e6461dbeb1d19751a03 From 96f0bc9c6e888493496d24c4e5bfc851b3270b01 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sat, 8 Nov 2025 21:16:24 +0330 Subject: [PATCH 56/84] ignore commit --- .git-blame-ignore-revs | 1 + 1 file changed, 1 insertion(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 0f94249..eba1853 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -10,3 +10,4 @@ a0d085f93eaa69c22449d0217e8daf9eaea2b180 f6bc623284914489e891bbac923feb774c862b99 abbab3f8b477e917d0a175d0de23cce121096631 126347025f9cade241beff182738b2527da7535e +4740b836f300658b27e6ad4d79efac63c9c24c24 From 7df73096d6a2a6b6674d5455af6331e62548ce81 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 18:38:59 +0000 Subject: [PATCH 57/84] Fix regex to match whole lines only in Get-GitStatusSetting Co-authored-by: DRSDavidSoft <4673812+DRSDavidSoft@users.noreply.github.com> --- vendor/psmodules/Cmder.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/psmodules/Cmder.ps1 b/vendor/psmodules/Cmder.ps1 index fb703a5..548c324 100644 --- a/vendor/psmodules/Cmder.ps1 +++ b/vendor/psmodules/Cmder.ps1 @@ -190,7 +190,7 @@ function Show-GitStatus { function Get-GitStatusSetting { $gitConfig = git --no-pager config -l 2>$null | Out-String - if ($gitConfig -match 'cmder\.(ps)?status=false') { + if ($gitConfig -match '(?m)^cmder\.(ps)?status=false') { return $false } From bc970e7f78a6f56806704c1469ca9a8cfd7642ff Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 19:00:56 +0000 Subject: [PATCH 58/84] Add end-of-line anchor and explanatory comment to Get-GitStatusSetting regex Co-authored-by: DRSDavidSoft <4673812+DRSDavidSoft@users.noreply.github.com> --- vendor/psmodules/Cmder.ps1 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/vendor/psmodules/Cmder.ps1 b/vendor/psmodules/Cmder.ps1 index 548c324..18075e0 100644 --- a/vendor/psmodules/Cmder.ps1 +++ b/vendor/psmodules/Cmder.ps1 @@ -190,7 +190,10 @@ function Show-GitStatus { function Get-GitStatusSetting { $gitConfig = git --no-pager config -l 2>$null | Out-String - if ($gitConfig -match '(?m)^cmder\.(ps)?status=false') { + # Check if git status display is disabled via config + # Matches: cmder.status=false or cmder.psstatus=false (PowerShell-specific) + # Anchored to match complete lines only to avoid false positives + if ($gitConfig -match '(?m)^cmder\.(ps)?status=false$') { return $false } From 9b64482f37c04e626072ff5fb36f6587b01dd07d Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sat, 8 Nov 2025 23:50:52 +0330 Subject: [PATCH 59/84] add the same message from lib_git.cmd in PS1 script --- vendor/psmodules/Cmder.ps1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vendor/psmodules/Cmder.ps1 b/vendor/psmodules/Cmder.ps1 index 18075e0..8d7790a 100644 --- a/vendor/psmodules/Cmder.ps1 +++ b/vendor/psmodules/Cmder.ps1 @@ -16,6 +16,10 @@ function Get-GitVersion { return $Matches[1] } + Write-Debug "Git executable path: $gitExecutable" + Write-Error "'git --version' returned an improper version string!" + Write-Error "Unable to determine Git version from output: $gitVersion" + return $null } From 60045d8c4fb261528301d555d78c3eb2c1a92074 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sat, 8 Nov 2025 23:52:45 +0330 Subject: [PATCH 60/84] simplification --- vendor/psmodules/Cmder.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/vendor/psmodules/Cmder.ps1 b/vendor/psmodules/Cmder.ps1 index 8d7790a..aff6425 100644 --- a/vendor/psmodules/Cmder.ps1 +++ b/vendor/psmodules/Cmder.ps1 @@ -196,7 +196,6 @@ function Get-GitStatusSetting { # Check if git status display is disabled via config # Matches: cmder.status=false or cmder.psstatus=false (PowerShell-specific) - # Anchored to match complete lines only to avoid false positives if ($gitConfig -match '(?m)^cmder\.(ps)?status=false$') { return $false } From c039d977c2b484fc921b266b76e120c4afd3dc12 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 20:52:58 +0000 Subject: [PATCH 61/84] Skip mingw64 check on 32-bit systems for better performance Co-authored-by: DRSDavidSoft <4673812+DRSDavidSoft@users.noreply.github.com> --- vendor/psmodules/Cmder.ps1 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/vendor/psmodules/Cmder.ps1 b/vendor/psmodules/Cmder.ps1 index aff6425..1564a3b 100644 --- a/vendor/psmodules/Cmder.ps1 +++ b/vendor/psmodules/Cmder.ps1 @@ -111,7 +111,11 @@ function Set-GitPath { } # Add mingw bin directory - foreach ($mingw in @('mingw64', 'mingw32')) { + # Prefer mingw64 on 64-bit systems, mingw32 on 32-bit systems + $is64Bit = [Environment]::Is64BitOperatingSystem + $mingwDirs = if ($is64Bit) { @('mingw64', 'mingw32') } else { @('mingw32') } + + foreach ($mingw in $mingwDirs) { $mingwBin = Join-Path $GitRoot "$mingw\bin" if ((Test-Path $mingwBin) -and -not ($newPath -match [regex]::Escape($mingwBin))) { Write-Debug "Adding $mingwBin to the path" From f6adae5fb27dd44bb5ce70f5dc1fe2b17f34c95a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 21:00:30 +0000 Subject: [PATCH 62/84] Fix version comparison to handle Git version strings correctly Co-authored-by: DRSDavidSoft <4673812+DRSDavidSoft@users.noreply.github.com> --- vendor/psmodules/Cmder.ps1 | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/vendor/psmodules/Cmder.ps1 b/vendor/psmodules/Cmder.ps1 index 1564a3b..0eeed5c 100644 --- a/vendor/psmodules/Cmder.ps1 +++ b/vendor/psmodules/Cmder.ps1 @@ -53,14 +53,22 @@ function Compare-Version { if ($null -eq $UserVersion) { return -1 } if ($null -eq $VendorVersion) { return 1 } - try { - $userVer = [version]$UserVersion - $vendorVer = [version]$VendorVersion - return $userVer.CompareTo($vendorVer) - } catch { - # Fallback to string comparison if version parsing fails - return [string]::Compare($UserVersion, $VendorVersion) + # Extract all numeric parts from version strings (e.g., "2.49.0.windows.1" -> 2, 49, 0, 1) + # This handles Git version strings like "2.49.0.windows.1" correctly + $userParts = [regex]::Matches($UserVersion, '\d+') | ForEach-Object { [int]$_.Value } + $vendorParts = [regex]::Matches($VendorVersion, '\d+') | ForEach-Object { [int]$_.Value } + + # Compare each numeric part sequentially + $maxLength = [Math]::Max($userParts.Count, $vendorParts.Count) + for ($i = 0; $i -lt $maxLength; $i++) { + $userPart = if ($i -lt $userParts.Count) { $userParts[$i] } else { 0 } + $vendorPart = if ($i -lt $vendorParts.Count) { $vendorParts[$i] } else { 0 } + + if ($userPart -gt $vendorPart) { return 1 } + if ($userPart -lt $vendorPart) { return -1 } } + + return 0 } function Compare-GitVersion { From 456ddcc59ed94adfe4e1ea1ba80347648f680eef Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 21:11:36 +0000 Subject: [PATCH 63/84] Improve version comparison using dot-notation segment comparison Co-authored-by: DRSDavidSoft <4673812+DRSDavidSoft@users.noreply.github.com> --- vendor/psmodules/Cmder.ps1 | 47 ++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/vendor/psmodules/Cmder.ps1 b/vendor/psmodules/Cmder.ps1 index 0eeed5c..45e3b5b 100644 --- a/vendor/psmodules/Cmder.ps1 +++ b/vendor/psmodules/Cmder.ps1 @@ -50,22 +50,45 @@ function Compare-Version { [string]$VendorVersion ) - if ($null -eq $UserVersion) { return -1 } - if ($null -eq $VendorVersion) { return 1 } + if ([string]::IsNullOrEmpty($UserVersion)) { return -1 } + if ([string]::IsNullOrEmpty($VendorVersion)) { return 1 } - # Extract all numeric parts from version strings (e.g., "2.49.0.windows.1" -> 2, 49, 0, 1) - # This handles Git version strings like "2.49.0.windows.1" correctly - $userParts = [regex]::Matches($UserVersion, '\d+') | ForEach-Object { [int]$_.Value } - $vendorParts = [regex]::Matches($VendorVersion, '\d+') | ForEach-Object { [int]$_.Value } + # Split version strings by dots to compare segment by segment + # For "2.49.0.windows.1", we get: ["2", "49", "0", "windows", "1"] + $userParts = $UserVersion -split '\.' + $vendorParts = $VendorVersion -split '\.' - # Compare each numeric part sequentially $maxLength = [Math]::Max($userParts.Count, $vendorParts.Count) - for ($i = 0; $i -lt $maxLength; $i++) { - $userPart = if ($i -lt $userParts.Count) { $userParts[$i] } else { 0 } - $vendorPart = if ($i -lt $vendorParts.Count) { $vendorParts[$i] } else { 0 } - if ($userPart -gt $vendorPart) { return 1 } - if ($userPart -lt $vendorPart) { return -1 } + for ($i = 0; $i -lt $maxLength; $i++) { + $userPart = if ($i -lt $userParts.Count) { $userParts[$i] } else { '' } + $vendorPart = if ($i -lt $vendorParts.Count) { $vendorParts[$i] } else { '' } + + # Check if both parts are purely numeric + $userIsNumeric = $userPart -match '^\d+$' + $vendorIsNumeric = $vendorPart -match '^\d+$' + + if ($userIsNumeric -and $vendorIsNumeric) { + # Both numeric: compare as integers (so 49 > 5, not lexicographic) + $userNum = [int]$userPart + $vendorNum = [int]$vendorPart + + if ($userNum -gt $vendorNum) { return 1 } + if ($userNum -lt $vendorNum) { return -1 } + } + elseif ($userIsNumeric -and -not $vendorIsNumeric) { + # Numeric segment comes before text segment (e.g., "2.0" < "2.0.rc1") + return -1 + } + elseif (-not $userIsNumeric -and $vendorIsNumeric) { + # Text segment comes after numeric segment + return 1 + } + else { + # Both are text: use case-insensitive lexicographic comparison + $cmp = [string]::Compare($userPart, $vendorPart, $true) + if ($cmp -ne 0) { return [Math]::Sign($cmp) } + } } return 0 From a1def7195e8050d0f964f292d51c695e0e07dbef Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 21:24:18 +0000 Subject: [PATCH 64/84] Restore posh-git support for all versions in Import-Git Co-authored-by: DRSDavidSoft <4673812+DRSDavidSoft@users.noreply.github.com> --- vendor/psmodules/Cmder.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vendor/psmodules/Cmder.ps1 b/vendor/psmodules/Cmder.ps1 index 45e3b5b..309edde 100644 --- a/vendor/psmodules/Cmder.ps1 +++ b/vendor/psmodules/Cmder.ps1 @@ -176,8 +176,10 @@ function Import-Git { return $false } + # Import posh-git module (works for all versions) Import-Module Posh-Git -ErrorAction SilentlyContinue | Out-Null + # Apply version-specific settings for posh-git 1.0.0+ if (($gitModule.Version -ge [version]"1.0.0") -and (Get-Variable -Name GitPromptSettings -ErrorAction SilentlyContinue)) { $GitPromptSettings.AnsiConsole = $false } From fc24040e5ea1a07b4c49d29ae8ec1ea2c09a5c38 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sun, 9 Nov 2025 01:14:28 +0330 Subject: [PATCH 65/84] adjust comments --- vendor/psmodules/Cmder.ps1 | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/vendor/psmodules/Cmder.ps1 b/vendor/psmodules/Cmder.ps1 index 309edde..0c78b6e 100644 --- a/vendor/psmodules/Cmder.ps1 +++ b/vendor/psmodules/Cmder.ps1 @@ -10,6 +10,7 @@ function Get-GitVersion { return $null } + # Execute 'git --version' and capture output $gitVersion = & $gitExecutable --version 2>$null if ($gitVersion -match 'git version\s+(\S+)') { @@ -28,11 +29,13 @@ function Get-GitShimPath { [Parameter(Mandatory = $true)] [string]$GitPath ) + # Check if there is a shim file - if yes, read the actual executable path + # See: github.com/ScoopInstaller/Shim $shimFile = Join-Path $GitPath "git.shim" if (Test-Path $shimFile) { $shimContent = Get-Content $shimFile -Raw - if ($shimContent -match 'path\s*=\s*(.+)') { + if ($shimContent -match '^\s*path\s*=\s*(.+)\s*$') { $GitPath = $Matches[1].Trim().Replace('\git.exe', '') } } @@ -123,6 +126,13 @@ function Set-GitPath { [string]$GitPathUser ) + # Proposed Behavior + + # Modify the path if we are using VENDORED Git, do nothing if using USER Git. + # If User Git is installed but is older, match its path config adding paths + # in the same path positions allowing a user to configure Cmder Git path + # using locally installed Git Path Config. + if ($GitType -ne 'VENDOR') { return $env:Path } @@ -134,19 +144,24 @@ function Set-GitPath { Write-Verbose "Cmder 'profile.ps1': Replacing older user Git path '$GitPathUser' with newer vendored Git path '$GitRoot' in the system path..." $newPath = $newPath -ireplace [regex]::Escape($GitPathUser), $GitRoot } else { - # Add Git cmd directory + # Add Git cmd directory to the path $gitCmd = Join-Path $GitRoot "cmd" if (-not ($newPath -match [regex]::Escape($gitCmd))) { Write-Debug "Adding $gitCmd to the path" $newPath = "$gitCmd;$newPath" } +<<<<<<< HEAD + # Add mingw[32|64]\bin directories to the path, if they exist and not already present + foreach ($mingw in @('mingw64', 'mingw32')) { +======= # Add mingw bin directory # Prefer mingw64 on 64-bit systems, mingw32 on 32-bit systems $is64Bit = [Environment]::Is64BitOperatingSystem $mingwDirs = if ($is64Bit) { @('mingw64', 'mingw32') } else { @('mingw32') } foreach ($mingw in $mingwDirs) { +>>>>>>> a1def7195e8050d0f964f292d51c695e0e07dbef $mingwBin = Join-Path $GitRoot "$mingw\bin" if ((Test-Path $mingwBin) -and -not ($newPath -match [regex]::Escape($mingwBin))) { Write-Debug "Adding $mingwBin to the path" @@ -155,7 +170,7 @@ function Set-GitPath { } } - # Add usr bin directory + # Add usr\bin directory to the path $usrBin = Join-Path $GitRoot "usr\bin" if ((Test-Path $usrBin) -and -not ($newPath -match [regex]::Escape($usrBin))) { Write-Debug "Adding $usrBin to the path" From 304b8c7a055bd967046bfb921c6311d28448ae80 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sun, 9 Nov 2025 01:48:05 +0330 Subject: [PATCH 66/84] simplify regex --- vendor/git-prompt.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vendor/git-prompt.sh b/vendor/git-prompt.sh index 1b67e76..a35b9f9 100644 --- a/vendor/git-prompt.sh +++ b/vendor/git-prompt.sh @@ -5,9 +5,9 @@ function getGitStatusSetting() { # Get all git config entries for the current repository without pager gitConfig=$(git --no-pager config -l 2>/dev/null) || return 0 # treat failure as enabled - # Check if git status for Cmder is disabled - if [[ $gitConfig =~ (^|$'\n')cmder\.status=false($|$'\n') ]] || \ - [[ $gitConfig =~ (^|$'\n')cmder\.shstatus=false($|$'\n') ]] + # Check if git status display for Cmder is disabled via config + # Matches: cmder.status=false or cmder.shstatus=false (Bash-specific) + if [[ $gitConfig =~ (^|$'\n')cmder\.(sh)?status=false($|$'\n') ]] then return 1 # disabled fi From a8d897f633d7da4ea0156964f892a55bec18c7e0 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sun, 9 Nov 2025 01:49:20 +0330 Subject: [PATCH 67/84] adjust comments --- vendor/git-prompt.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vendor/git-prompt.sh b/vendor/git-prompt.sh index a35b9f9..a37400b 100644 --- a/vendor/git-prompt.sh +++ b/vendor/git-prompt.sh @@ -47,7 +47,7 @@ then . ~/.config/git/git-prompt.sh fi else - # Taken parts from https://github.com/git-for-windows/build-extra/blob/main/git-extra/git-prompt.sh + # Source: github.com/git-for-windows/build-extra/blob/main/git-extra/git-prompt.sh PS1='\[\033]0;${TITLEPREFIX:+$TITLEPREFIX:}${PWD//[^[:ascii:]]/?}\007\]' # set window title to TITLEPREFIX (if set) and current working directory # PS1="$PS1"'\n' # new line (disabled) PS1="$PS1"'\[\033[32m\]' # change to green and bold @@ -70,7 +70,7 @@ else PS1="$PS1"'\[\033[36m\]' # change color to cyan PS1="$PS1"'`__git_ps1`' # bash function else - PS1="$PS1"'\[\033[37;1m\]' # change color to white + PS1="$PS1"'\[\033[37;1m\]' # change color to white PS1="$PS1"'`getSimpleGitBranch`' fi fi @@ -82,7 +82,7 @@ else PS1="$PS1"'\[\033[0m\]' # reset color fi -MSYS2_PS1="$PS1" # for detection by MSYS2 SDK's bash.basrc +MSYS2_PS1="$PS1" # for detection by MSYS2 SDK's bash.basrc # Evaluate all user-specific Bash completion scripts (if any) if test -z "$WINELOADERNOEXEC" From b9246177c04d8912c82fde77b60ddf397abbcd8c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 22:24:31 +0000 Subject: [PATCH 68/84] Initial plan From bbd7507b4ed6345749d6148b7fba29af9cede01d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 22:27:38 +0000 Subject: [PATCH 69/84] Add OSC 133;D support for command exit code tracking Co-authored-by: DRSDavidSoft <4673812+DRSDavidSoft@users.noreply.github.com> --- README.md | 2 +- vendor/profile.ps1 | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c45e254..661ba39 100644 --- a/README.md +++ b/README.md @@ -354,7 +354,7 @@ However, Cmder can in fact run in a variety of other terminal emulators, and eve ⚠ *Note:* Cmder includes built-in support for Windows Terminal directory tracking via OSC 9;9 sequences. This enables "Duplicate Tab" and "Split Pane" features to preserve the current working directory for both `cmd.exe` and PowerShell sessions. -⚠ *Note:* Cmder also includes built-in support for [Windows Terminal shell integration](https://learn.microsoft.com/en-us/windows/terminal/tutorials/shell-integration) via OSC 133 sequences (A, B, C) for PowerShell sessions. This enables features like command navigation (jump between commands), command selection, visual command separators, and improved command history management in Windows Terminal. +⚠ *Note:* Cmder also includes built-in support for [Windows Terminal shell integration](https://learn.microsoft.com/en-us/windows/terminal/tutorials/shell-integration) via OSC 133 sequences (A, B, C, D) for PowerShell sessions. This enables features like command navigation (jump between commands), command selection, visual command separators, command exit code tracking, and improved command history management in Windows Terminal. For instructions on how to integrate Cmder with your IDE, please read our [Wiki section](https://github.com/cmderdev/cmder/wiki#cmder-integration). diff --git a/vendor/profile.ps1 b/vendor/profile.ps1 index c77e81a..42728e2 100644 --- a/vendor/profile.ps1 +++ b/vendor/profile.ps1 @@ -221,6 +221,14 @@ if ( $(Get-Command prompt).Definition -match 'PS \$\(\$executionContext.SessionS $lastSUCCESS = $? $realLastExitCode = $LastExitCode + # Emit OSC 133;D sequence for Windows Terminal shell integration + # This marks the end of command execution with the exit code + # Must be emitted before OSC 133;A (start of next prompt) + # Only active in Windows Terminal ($env:WT_SESSION) + if ($env:WT_SESSION) { + Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;D;$realLastExitCode$([char]7)" + } + # Emit OSC 9;9 sequence for Windows Terminal directory tracking # This enables "Duplicate Tab" and "Split Pane" to preserve the working directory # Only active in Windows Terminal ($env:WT_SESSION) or ConEmu ($env:ConEmuPID) From 4d259ba84c10727bcb8c769c1cfd849865e12e5f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 22:41:26 +0000 Subject: [PATCH 70/84] Consolidate terminal conditionals and add shell integration for bash and cmd.exe Co-authored-by: DRSDavidSoft <4673812+DRSDavidSoft@users.noreply.github.com> --- vendor/git-prompt.sh | 33 +++++++++++++++++++++++++++++++++ vendor/init.bat | 7 ++++++- vendor/profile.ps1 | 42 ++++++++++++++++++------------------------ 3 files changed, 57 insertions(+), 25 deletions(-) diff --git a/vendor/git-prompt.sh b/vendor/git-prompt.sh index a37400b..27da0de 100644 --- a/vendor/git-prompt.sh +++ b/vendor/git-prompt.sh @@ -48,6 +48,34 @@ then fi else # Source: github.com/git-for-windows/build-extra/blob/main/git-extra/git-prompt.sh + + # Setup OSC 133 shell integration for Windows Terminal + if [ -n "$WT_SESSION" ]; then + __cmder_prompt_command() { + local exit_code=$? + # OSC 133;D - Mark end of command execution with exit code + printf '\e]133;D;%s\a' "$exit_code" + # OSC 133;A - Mark start of prompt + printf '\e]133;A\a' + return $exit_code + } + + # OSC 133;C - Mark start of command output (emitted right before command execution) + __cmder_preexec() { + printf '\e]133;C\a' + } + + # Append to PROMPT_COMMAND to emit sequences before each prompt + if [ -z "$PROMPT_COMMAND" ]; then + PROMPT_COMMAND="__cmder_prompt_command" + else + PROMPT_COMMAND="__cmder_prompt_command;$PROMPT_COMMAND" + fi + + # Use DEBUG trap to emit OSC 133;C before command execution + trap '__cmder_preexec' DEBUG + fi + PS1='\[\033]0;${TITLEPREFIX:+$TITLEPREFIX:}${PWD//[^[:ascii:]]/?}\007\]' # set window title to TITLEPREFIX (if set) and current working directory # PS1="$PS1"'\n' # new line (disabled) PS1="$PS1"'\[\033[32m\]' # change to green and bold @@ -80,6 +108,11 @@ else PS1="$PS1"'\[\033[30;1m\]' # change color to grey in bold PS1="$PS1"'λ ' # prompt: Cmder uses λ PS1="$PS1"'\[\033[0m\]' # reset color + + # OSC 133;B - Mark start of command input (Windows Terminal only) + if [ -n "$WT_SESSION" ]; then + PS1="$PS1"'\[\e]133;B\a\]' + fi fi MSYS2_PS1="$PS1" # for detection by MSYS2 SDK's bash.basrc diff --git a/vendor/init.bat b/vendor/init.bat index 3d82855..70e05d5 100644 --- a/vendor/init.bat +++ b/vendor/init.bat @@ -221,7 +221,12 @@ goto :SKIP_CLINK chcp 65001>nul :: Revert back to plain cmd.exe prompt without clink - prompt $E[1;32;49m$P$S$_$E[1;30;49mλ$S$E[0m + :: With Windows Terminal shell integration support (OSC 133 sequences) + if defined WT_SESSION ( + prompt $e]133;D$e\$e]133;A$e\$e]9;9;$P$e\$E[1;32;49m$P$S$_$E[1;30;49mλ$S$E[0m$e]133;B$e\ + ) else ( + prompt $E[1;32;49m$P$S$_$E[1;30;49mλ$S$E[0m + ) chcp %cp%>nul diff --git a/vendor/profile.ps1 b/vendor/profile.ps1 index 42728e2..1339077 100644 --- a/vendor/profile.ps1 +++ b/vendor/profile.ps1 @@ -221,28 +221,23 @@ if ( $(Get-Command prompt).Definition -match 'PS \$\(\$executionContext.SessionS $lastSUCCESS = $? $realLastExitCode = $LastExitCode - # Emit OSC 133;D sequence for Windows Terminal shell integration - # This marks the end of command execution with the exit code - # Must be emitted before OSC 133;A (start of next prompt) - # Only active in Windows Terminal ($env:WT_SESSION) - if ($env:WT_SESSION) { - Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;D;$realLastExitCode$([char]7)" - } - - # Emit OSC 9;9 sequence for Windows Terminal directory tracking - # This enables "Duplicate Tab" and "Split Pane" to preserve the working directory - # Only active in Windows Terminal ($env:WT_SESSION) or ConEmu ($env:ConEmuPID) - $loc = $executionContext.SessionState.Path.CurrentLocation - if (($env:WT_SESSION -or $env:ConEmuPID) -and $loc.Provider.Name -eq "FileSystem") { - Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]9;9;`"$($loc.ProviderPath)`"$([char]0x1B)\" - } - - # Emit OSC 133;A sequence for Windows Terminal shell integration - # This marks the start of the prompt - # Enables features like command navigation, selection, and visual separators - # Only active in Windows Terminal ($env:WT_SESSION) - if ($env:WT_SESSION) { - Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;A$([char]7)" + # Emit terminal-specific escape sequences for Windows Terminal and ConEmu + if ($env:WT_SESSION -or $env:ConEmuPID) { + # OSC 133;D - Mark end of command execution with exit code (Windows Terminal only) + if ($env:WT_SESSION) { + Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;D;$realLastExitCode$([char]7)" + } + + # OSC 9;9 - Enable directory tracking for "Duplicate Tab" and "Split Pane" + $loc = $executionContext.SessionState.Path.CurrentLocation + if ($loc.Provider.Name -eq "FileSystem") { + Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]9;9;`"$($loc.ProviderPath)`"$([char]0x1B)\" + } + + # OSC 133;A - Mark start of prompt (Windows Terminal only) + if ($env:WT_SESSION) { + Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;A$([char]7)" + } } $host.UI.RawUI.WindowTitle = Microsoft.PowerShell.Management\Split-Path $pwd.ProviderPath -Leaf @@ -254,8 +249,7 @@ if ( $(Get-Command prompt).Definition -match 'PS \$\(\$executionContext.SessionS CmderPrompt PostPrompt | Microsoft.PowerShell.Utility\Write-Host -NoNewline - # Emit OSC 133;B sequence for Windows Terminal shell integration - # This marks the start of command input (after prompt, before user types) + # OSC 133;B - Mark start of command input (Windows Terminal only) if ($env:WT_SESSION) { Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;B$([char]7)" } From 5dfa14ccce600fbe3e967cca150d6cd398c5a6c4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 22:55:15 +0000 Subject: [PATCH 71/84] Avoid duplicating cmd.exe prompt definition Co-authored-by: DRSDavidSoft <4673812+DRSDavidSoft@users.noreply.github.com> --- vendor/init.bat | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/vendor/init.bat b/vendor/init.bat index 70e05d5..2eabb6e 100644 --- a/vendor/init.bat +++ b/vendor/init.bat @@ -221,12 +221,10 @@ goto :SKIP_CLINK chcp 65001>nul :: Revert back to plain cmd.exe prompt without clink - :: With Windows Terminal shell integration support (OSC 133 sequences) - if defined WT_SESSION ( - prompt $e]133;D$e\$e]133;A$e\$e]9;9;$P$e\$E[1;32;49m$P$S$_$E[1;30;49mλ$S$E[0m$e]133;B$e\ - ) else ( - prompt $E[1;32;49m$P$S$_$E[1;30;49mλ$S$E[0m - ) + prompt $E[1;32;49m$P$S$_$E[1;30;49mλ$S$E[0m + + :: Add Windows Terminal shell integration support (OSC 133 sequences) + if defined WT_SESSION (prompt $e]133;D$e\$e]133;A$e\$e]9;9;$P$e\%PROMPT%$e]133;B$e\) chcp %cp%>nul From 2ce0146d6eac72e62878b64ec0974393a33e13d4 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sun, 9 Nov 2025 02:45:06 +0330 Subject: [PATCH 72/84] adjust comments --- vendor/git-prompt.sh | 29 ++++++++++++++++------------- vendor/profile.ps1 | 17 +++++++++-------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/vendor/git-prompt.sh b/vendor/git-prompt.sh index 27da0de..8149695 100644 --- a/vendor/git-prompt.sh +++ b/vendor/git-prompt.sh @@ -47,25 +47,21 @@ then . ~/.config/git/git-prompt.sh fi else - # Source: github.com/git-for-windows/build-extra/blob/main/git-extra/git-prompt.sh - + # Setup OSC 133 shell integration for Windows Terminal if [ -n "$WT_SESSION" ]; then __cmder_prompt_command() { local exit_code=$? - # OSC 133;D - Mark end of command execution with exit code + # Emit OSC 133;D to mark the end of command execution with exit code printf '\e]133;D;%s\a' "$exit_code" - # OSC 133;A - Mark start of prompt - printf '\e]133;A\a' return $exit_code } - - # OSC 133;C - Mark start of command output (emitted right before command execution) + __cmder_preexec() { - printf '\e]133;C\a' + printf '\e]133;C\a' # Emit OSC 133;C to mark the start of command execution } - - # Append to PROMPT_COMMAND to emit sequences before each prompt + + # Append to PROMPT_COMMAND to emit sequences just before each prompt if [ -z "$PROMPT_COMMAND" ]; then PROMPT_COMMAND="__cmder_prompt_command" else @@ -75,9 +71,16 @@ else # Use DEBUG trap to emit OSC 133;C before command execution trap '__cmder_preexec' DEBUG fi - + + # Source: github.com/git-for-windows/build-extra/blob/main/git-extra/git-prompt.sh PS1='\[\033]0;${TITLEPREFIX:+$TITLEPREFIX:}${PWD//[^[:ascii:]]/?}\007\]' # set window title to TITLEPREFIX (if set) and current working directory # PS1="$PS1"'\n' # new line (disabled) + + if [ -n "$WT_SESSION" ]; then + # Emit OSC 133;A to mark the start of prompt + PS1="$PS1"'\e]133;A\a' + fi + PS1="$PS1"'\[\033[32m\]' # change to green and bold PS1="$PS1"'\u@\h ' # user@host PS1="$PS1${MSYSTEM:+\[\033[35m\]$MSYSTEM }" # show MSYSTEM in purple (if set) @@ -108,9 +111,9 @@ else PS1="$PS1"'\[\033[30;1m\]' # change color to grey in bold PS1="$PS1"'λ ' # prompt: Cmder uses λ PS1="$PS1"'\[\033[0m\]' # reset color - - # OSC 133;B - Mark start of command input (Windows Terminal only) + if [ -n "$WT_SESSION" ]; then + # Emit OSC 133;B to mark the end of prompt PS1="$PS1"'\[\e]133;B\a\]' fi fi diff --git a/vendor/profile.ps1 b/vendor/profile.ps1 index 1339077..8e20d0c 100644 --- a/vendor/profile.ps1 +++ b/vendor/profile.ps1 @@ -98,8 +98,7 @@ if (Get-Module PSReadline -ErrorAction "SilentlyContinue") { # Display an extra prompt line between the prompt and the command input Set-PSReadlineOption -ExtraPromptLineCount 1 - # Add OSC 133;C support for Windows Terminal shell integration - # This marks the start of command output (emitted when Enter is pressed) + # Invoked when Enter is pressed to submit a command if ($env:WT_SESSION) { Set-PSReadLineKeyHandler -Key Enter -ScriptBlock { # Get the current command line @@ -110,7 +109,7 @@ if (Get-Module PSReadline -ErrorAction "SilentlyContinue") { # Accept the line first [Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine() - # Emit OSC 133;C sequence to mark start of command output + # Emit OSC 133;C to mark start of command output # This is written directly to the console after the command is accepted [Console]::Write("$([char]0x1B)]133;C$([char]7)") } @@ -221,20 +220,22 @@ if ( $(Get-Command prompt).Definition -match 'PS \$\(\$executionContext.SessionS $lastSUCCESS = $? $realLastExitCode = $LastExitCode - # Emit terminal-specific escape sequences for Windows Terminal and ConEmu + # Terminal-specific escape sequences for Windows Terminal and ConEmu if ($env:WT_SESSION -or $env:ConEmuPID) { - # OSC 133;D - Mark end of command execution with exit code (Windows Terminal only) + # Emit OSC 133;D to mark the end of command execution with exit code if ($env:WT_SESSION) { Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;D;$realLastExitCode$([char]7)" } - # OSC 9;9 - Enable directory tracking for "Duplicate Tab" and "Split Pane" + # Emit OSC 9;9 to mark the start of the prompt + # Enables directory tracking for "Duplicate Tab" and "Split Pane" $loc = $executionContext.SessionState.Path.CurrentLocation if ($loc.Provider.Name -eq "FileSystem") { Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]9;9;`"$($loc.ProviderPath)`"$([char]0x1B)\" } - # OSC 133;A - Mark start of prompt (Windows Terminal only) + # Emit OSC 133;A to mark the start of the prompt + # Enables features like command navigation, selection, and visual separators if ($env:WT_SESSION) { Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;A$([char]7)" } @@ -249,7 +250,7 @@ if ( $(Get-Command prompt).Definition -match 'PS \$\(\$executionContext.SessionS CmderPrompt PostPrompt | Microsoft.PowerShell.Utility\Write-Host -NoNewline - # OSC 133;B - Mark start of command input (Windows Terminal only) + # Emit OSC 133;B to mark the start of command input (after prompt, before user types) if ($env:WT_SESSION) { Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;B$([char]7)" } From 697c122faf88791f134b9538671862820e92040e Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sun, 9 Nov 2025 02:48:02 +0330 Subject: [PATCH 73/84] adjust comments --- vendor/psmodules/Cmder.ps1 | 5 ----- 1 file changed, 5 deletions(-) diff --git a/vendor/psmodules/Cmder.ps1 b/vendor/psmodules/Cmder.ps1 index 0c78b6e..6de808e 100644 --- a/vendor/psmodules/Cmder.ps1 +++ b/vendor/psmodules/Cmder.ps1 @@ -151,17 +151,12 @@ function Set-GitPath { $newPath = "$gitCmd;$newPath" } -<<<<<<< HEAD # Add mingw[32|64]\bin directories to the path, if they exist and not already present - foreach ($mingw in @('mingw64', 'mingw32')) { -======= - # Add mingw bin directory # Prefer mingw64 on 64-bit systems, mingw32 on 32-bit systems $is64Bit = [Environment]::Is64BitOperatingSystem $mingwDirs = if ($is64Bit) { @('mingw64', 'mingw32') } else { @('mingw32') } foreach ($mingw in $mingwDirs) { ->>>>>>> a1def7195e8050d0f964f292d51c695e0e07dbef $mingwBin = Join-Path $GitRoot "$mingw\bin" if ((Test-Path $mingwBin) -and -not ($newPath -match [regex]::Escape($mingwBin))) { Write-Debug "Adding $mingwBin to the path" From 7b248bc9a3668b3b7ac56993d32b09e00e18eee9 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sun, 9 Nov 2025 02:50:47 +0330 Subject: [PATCH 74/84] adjust comments --- vendor/git-prompt.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vendor/git-prompt.sh b/vendor/git-prompt.sh index 8149695..e64f906 100644 --- a/vendor/git-prompt.sh +++ b/vendor/git-prompt.sh @@ -58,7 +58,8 @@ else } __cmder_preexec() { - printf '\e]133;C\a' # Emit OSC 133;C to mark the start of command execution + # Emit OSC 133;C to mark the start of command execution + printf '\e]133;C\a' } # Append to PROMPT_COMMAND to emit sequences just before each prompt @@ -67,7 +68,7 @@ else else PROMPT_COMMAND="__cmder_prompt_command;$PROMPT_COMMAND" fi - + # Use DEBUG trap to emit OSC 133;C before command execution trap '__cmder_preexec' DEBUG fi From eabadf96dc66be16091d2fc33c147f239d5a940d Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sun, 9 Nov 2025 02:57:19 +0330 Subject: [PATCH 75/84] fix incorrect comment --- vendor/profile.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vendor/profile.ps1 b/vendor/profile.ps1 index 8e20d0c..359c9d3 100644 --- a/vendor/profile.ps1 +++ b/vendor/profile.ps1 @@ -227,8 +227,8 @@ if ( $(Get-Command prompt).Definition -match 'PS \$\(\$executionContext.SessionS Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;D;$realLastExitCode$([char]7)" } - # Emit OSC 9;9 to mark the start of the prompt - # Enables directory tracking for "Duplicate Tab" and "Split Pane" + # Emit OSC 9;9 to enable directory tracking + # Enables "Duplicate Tab" and "Split Pane" to preserve the working directory $loc = $executionContext.SessionState.Path.CurrentLocation if ($loc.Provider.Name -eq "FileSystem") { Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]9;9;`"$($loc.ProviderPath)`"$([char]0x1B)\" From 3172771f15f2a1e0b4f973703b4e9349ee5d4aef Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sun, 9 Nov 2025 03:24:58 +0330 Subject: [PATCH 76/84] Modify PowerShell test command for debug output * Update PowerShell command to include debug preference. * Remove un-needed `Invoke-Expression` --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f2bf770..12633d3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -48,7 +48,7 @@ jobs: cmd /c vendor\init.bat /v /d /t - name: Testing PowerShell run: | - PowerShell.exe -ExecutionPolicy Bypass -NoLogo -NoProfile -Command "Invoke-Expression '. ''vendor\profile.ps1'''" + PowerShell.exe -ExecutionPolicy Bypass -NoLogo -NoProfile -Command "$DebugPreference='Continue'; . 'vendor\profile.ps1' 5>&1" - name: Testing Bash run: | bash vendor/cmder.sh From a824b721cb6a3079fa6a8c864775bc0546e61596 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sun, 9 Nov 2025 03:46:29 +0330 Subject: [PATCH 77/84] improve CI PowrShell profile test debug/verbose output --- .github/workflows/tests.yml | 4 +++- vendor/profile.ps1 | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 12633d3..9b3cce6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -47,8 +47,10 @@ jobs: run: | cmd /c vendor\init.bat /v /d /t - name: Testing PowerShell + env: + CMDER_DEBUG: '1' run: | - PowerShell.exe -ExecutionPolicy Bypass -NoLogo -NoProfile -Command "$DebugPreference='Continue'; . 'vendor\profile.ps1' 5>&1" + PowerShell.exe -ExecutionPolicy Bypass -NoLogo -NoProfile -Command "'vendor\profile.ps1'" - name: Testing Bash run: | bash vendor/cmder.sh diff --git a/vendor/profile.ps1 b/vendor/profile.ps1 index bbd385b..8cc1a45 100644 --- a/vendor/profile.ps1 +++ b/vendor/profile.ps1 @@ -5,6 +5,11 @@ # !!! THIS FILE IS OVERWRITTEN WHEN CMDER IS UPDATED # !!! Use "%CMDER_ROOT%\config\user_profile.ps1" to add your own startup commands +if ($env:CMDER_DEBUG -and ($env:CMDER_DEBUG -match '^(1|true)$')) { + $DebugPreference = 'Continue' + $VerbosePreference = 'Continue' +} + $CMDER_INIT_START = Get-Date # Compatibility with PS major versions <= 2 From f4e68b03884daae3f5db676957acb9b29ec50fad Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sun, 9 Nov 2025 03:48:57 +0330 Subject: [PATCH 78/84] Update PowerShell test to set CMDER_DEBUG env variable inline --- .github/workflows/tests.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9b3cce6..0f0ea75 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -47,10 +47,8 @@ jobs: run: | cmd /c vendor\init.bat /v /d /t - name: Testing PowerShell - env: - CMDER_DEBUG: '1' run: | - PowerShell.exe -ExecutionPolicy Bypass -NoLogo -NoProfile -Command "'vendor\profile.ps1'" + PowerShell.exe -ExecutionPolicy Bypass -NoLogo -NoProfile -Command "$CMDER_DEBUG = 1; 'vendor\profile.ps1'" - name: Testing Bash run: | bash vendor/cmder.sh From 4fb6bed9070901330ee707f2aa234b468c502836 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sun, 9 Nov 2025 03:55:06 +0330 Subject: [PATCH 79/84] adjust comments --- scripts/build.ps1 | 362 ++++++++++++++++----------------- scripts/pack.ps1 | 152 +++++++------- scripts/utils.ps1 | 502 +++++++++++++++++++++++----------------------- 3 files changed, 508 insertions(+), 508 deletions(-) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 640bba1..735245d 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -1,181 +1,181 @@ -<# -.Synopsis - Build Cmder -.DESCRIPTION - Use this script to build your own edition of Cmder - - This script builds dependencies from current vendor/sources.json file and unpacks them. - - You will need to make this script executable by setting your Powershell Execution Policy to Remote signed - Then unblock the script for execution with UnblockFile .\build.ps1 -.EXAMPLE - .\build.ps1 - - Executes the default build for Cmder; ConEmu, clink. This is equivalent to the "minimum" style package in the releases -.EXAMPLE - .\build.ps1 -Compile - - Recompile the launcher executable if you have the requisite build tools for C++ installed. -.EXAMPLE - .\build.ps1 -Compile -NoVendor - - Skip all downloads and only build launcher. -.EXAMPLE - .\build -verbose - - Execute the build and see what's going on. -.EXAMPLE - .\build.ps1 -SourcesPath '~/custom/vendors.json' - - Build cmder with your own packages. See vendor/sources.json for the syntax you need to copy. -.NOTES - AUTHORS - Samuel Vasko, Jack Bennett - Part of the Cmder project. -.LINK - http://cmder.app/ - Project Home -#> -[CmdletBinding(SupportsShouldProcess = $true)] -Param( - # CmdletBinding will give us; - # -verbose switch to turn on logging and - # -whatif switch to not actually make changes - - # Path to the vendor configuration source file - [string]$sourcesPath = "$PSScriptRoot\..\vendor\sources.json", - - # Vendor folder location - [string]$saveTo = "$PSScriptRoot\..\vendor\", - - # Launcher folder location - [string]$launcher = "$PSScriptRoot\..\launcher", - - # Config folder location - [string]$config = "$PSScriptRoot\..\config", - - # Using this option will skip all downloads, if you only need to build launcher - [switch]$noVendor, - - # Build launcher if you have MSBuild tools installed - [switch]$Compile -) - -# Get the scripts and cmder root dirs we are building in. -$cmder_root = Resolve-Path "$PSScriptRoot\.." - -# Dot source util functions into this scope -. "$PSScriptRoot\utils.ps1" -$ErrorActionPreference = "Stop" - -if ($Compile) { - # Check for requirements - Ensure-Executable "msbuild" - - # Get the version string - $version = Get-VersionStr - - Push-Location -Path $launcher - Create-RC $version ($launcher + '\src\version.rc2') - - Write-Verbose "Building the launcher..." - - # Reference: https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference - msbuild CmderLauncher.vcxproj /t:Clean,Build /p:configuration=Release /m - - if ($LastExitCode -ne 0) { - throw "MSBuild failed to build the launcher executable." - } - Pop-Location -} - -if (-not $noVendor) { - # Check for requirements - Ensure-Exists $sourcesPath - Ensure-Executable "7z" - - # Get the vendor sources - $sources = Get-Content $sourcesPath | Out-String | ConvertFrom-Json - - Push-Location -Path $saveTo - New-Item -Type Directory -Path (Join-Path $saveTo "/tmp/") -ErrorAction SilentlyContinue >$null - - $vend = $pwd - - # Preserve modified (by user) ConEmu setting file - if ($config -ne "") { - $ConEmuXml = Join-Path $saveTo "conemu-maximus5\ConEmu.xml" - if (Test-Path $ConEmuXml -pathType leaf) { - $ConEmuXmlSave = Join-Path $config "ConEmu.xml" - Write-Verbose "Backup '$ConEmuXml' to '$ConEmuXmlSave'" - Copy-Item $ConEmuXml $ConEmuXmlSave - } - else { $ConEmuXml = "" } - } - else { $ConEmuXml = "" } - - # Kill ssh-agent.exe if it is running from the $env:cmder_root we are building - foreach ($ssh_agent in $(Get-Process ssh-agent -ErrorAction SilentlyContinue)) { - if ([string]$($ssh_agent.path) -Match [string]$cmder_root.replace('\', '\\')) { - Write-Verbose $("Stopping " + $ssh_agent.path + "!") - Stop-Process $ssh_agent.id - } - } - - foreach ($s in $sources) { - Write-Verbose "Getting vendored $($s.name) $($s.version)..." - - # We do not care about the extensions/type of archive - $tempArchive = "tmp/$($s.name).tmp" - Delete-Existing $tempArchive - Delete-Existing $s.name - - Download-File -Url $s.url -File $vend\$tempArchive -ErrorAction Stop - Extract-Archive $tempArchive $s.name - - if ((Get-ChildItem $s.name).Count -eq 1) { - Flatten-Directory($s.name) - } - - # Write current version to .cmderver file, for later. - "$($s.version)" | Out-File "$($s.name)/.cmderver" - } - - # Restore ConEmu user configuration - if ($ConEmuXml -ne "") { - Write-Verbose "Restore '$ConEmuXmlSave' to '$ConEmuXml'" - Copy-Item $ConEmuXmlSave $ConEmuXml - } - - # Put vendor\cmder.sh in /etc/profile.d so it runs when we start bash or mintty - if ( (Test-Path $($saveTo + "git-for-windows/etc/profile.d") ) ) { - Write-Verbose "Adding cmder.sh /etc/profile.d" - Copy-Item $($saveTo + "cmder.sh") $($saveTo + "git-for-windows/etc/profile.d/cmder.sh") - } - - # Replace /etc/profile.d/git-prompt.sh with cmder lambda prompt so it runs when we start bash or mintty - if ( !(Test-Path $($saveTo + "git-for-windows/etc/profile.d/git-prompt.sh.bak") ) ) { - Write-Verbose "Replacing /etc/profile.d/git-prompt.sh with our git-prompt.sh" - Move-Item $($saveTo + "git-for-windows/etc/profile.d/git-prompt.sh") $($saveTo + "git-for-windows/etc/profile.d/git-prompt.sh.bak") - Copy-Item $($saveTo + "git-prompt.sh") $($saveTo + "git-for-windows/etc/profile.d/git-prompt.sh") - } - - Pop-Location -} - -if (-not $Compile -or $noVendor) { - Write-Warning "You are not building the full project, Use -Compile without -noVendor" - Write-Warning "This cannot be a release. Test build only!" - return -} - -Write-Verbose "Successfully built Cmder v$version!" - -if ( $Env:APPVEYOR -eq 'True' ) { - Add-AppveyorMessage -Message "Building Cmder v$version was successful." -Category Information -} - -if ( $Env:GITHUB_ACTIONS -eq 'true' ) { - Write-Output "::notice title=Build Complete::Building Cmder v$version was successful." -} - -Write-Host -ForegroundColor green "All good and done!" +<# +.Synopsis + Build Cmder +.DESCRIPTION + Use this script to build your own edition of Cmder + + This script builds dependencies from current vendor/sources.json file and unpacks them. + + You will need to make this script executable by setting your Powershell Execution Policy to Remote signed + Then unblock the script for execution with UnblockFile .\build.ps1 +.EXAMPLE + .\build.ps1 + + Executes the default build for Cmder; ConEmu, clink. This is equivalent to the "minimum" style package in the releases +.EXAMPLE + .\build.ps1 -Compile + + Recompile the launcher executable if you have the requisite build tools for C++ installed. +.EXAMPLE + .\build.ps1 -Compile -NoVendor + + Skip all downloads and only build launcher. +.EXAMPLE + .\build -verbose + + Execute the build and see what's going on. +.EXAMPLE + .\build.ps1 -SourcesPath '~/custom/vendors.json' + + Build Cmder with your own packages. See vendor/sources.json for the syntax you need to copy. +.NOTES + AUTHORS + Samuel Vasko, Jack Bennett + Part of the Cmder project. +.LINK + http://cmder.app/ - Project Home +#> +[CmdletBinding(SupportsShouldProcess = $true)] +Param( + # CmdletBinding will give us; + # -verbose switch to turn on logging and + # -whatif switch to not actually make changes + + # Path to the vendor configuration source file + [string]$sourcesPath = "$PSScriptRoot\..\vendor\sources.json", + + # Vendor folder location + [string]$saveTo = "$PSScriptRoot\..\vendor\", + + # Launcher folder location + [string]$launcher = "$PSScriptRoot\..\launcher", + + # Config folder location + [string]$config = "$PSScriptRoot\..\config", + + # Using this option will skip all downloads, if you only need to build launcher + [switch]$noVendor, + + # Build launcher if you have MSBuild tools installed + [switch]$Compile +) + +# Get the scripts and Cmder root dirs we are building in. +$cmder_root = Resolve-Path "$PSScriptRoot\.." + +# Dot source util functions into this scope +. "$PSScriptRoot\utils.ps1" +$ErrorActionPreference = "Stop" + +if ($Compile) { + # Check for requirements + Ensure-Executable "msbuild" + + # Get the version string + $version = Get-VersionStr + + Push-Location -Path $launcher + Create-RC $version ($launcher + '\src\version.rc2') + + Write-Verbose "Building the launcher..." + + # Reference: https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference + msbuild CmderLauncher.vcxproj /t:Clean,Build /p:configuration=Release /m + + if ($LastExitCode -ne 0) { + throw "MSBuild failed to build the launcher executable." + } + Pop-Location +} + +if (-not $noVendor) { + # Check for requirements + Ensure-Exists $sourcesPath + Ensure-Executable "7z" + + # Get the vendor sources + $sources = Get-Content $sourcesPath | Out-String | ConvertFrom-Json + + Push-Location -Path $saveTo + New-Item -Type Directory -Path (Join-Path $saveTo "/tmp/") -ErrorAction SilentlyContinue >$null + + $vend = $pwd + + # Preserve modified (by user) ConEmu setting file + if ($config -ne "") { + $ConEmuXml = Join-Path $saveTo "conemu-maximus5\ConEmu.xml" + if (Test-Path $ConEmuXml -pathType leaf) { + $ConEmuXmlSave = Join-Path $config "ConEmu.xml" + Write-Verbose "Backup '$ConEmuXml' to '$ConEmuXmlSave'" + Copy-Item $ConEmuXml $ConEmuXmlSave + } + else { $ConEmuXml = "" } + } + else { $ConEmuXml = "" } + + # Kill ssh-agent.exe if it is running from the $env:cmder_root we are building + foreach ($ssh_agent in $(Get-Process ssh-agent -ErrorAction SilentlyContinue)) { + if ([string]$($ssh_agent.path) -Match [string]$cmder_root.replace('\', '\\')) { + Write-Verbose $("Stopping " + $ssh_agent.path + "!") + Stop-Process $ssh_agent.id + } + } + + foreach ($s in $sources) { + Write-Verbose "Getting vendored $($s.name) $($s.version)..." + + # We do not care about the extensions/type of archive + $tempArchive = "tmp/$($s.name).tmp" + Delete-Existing $tempArchive + Delete-Existing $s.name + + Download-File -Url $s.url -File $vend\$tempArchive -ErrorAction Stop + Extract-Archive $tempArchive $s.name + + if ((Get-ChildItem $s.name).Count -eq 1) { + Flatten-Directory($s.name) + } + + # Write current version to .cmderver file, for later. + "$($s.version)" | Out-File "$($s.name)/.cmderver" + } + + # Restore ConEmu user configuration + if ($ConEmuXml -ne "") { + Write-Verbose "Restore '$ConEmuXmlSave' to '$ConEmuXml'" + Copy-Item $ConEmuXmlSave $ConEmuXml + } + + # Put vendor\cmder.sh in /etc/profile.d so it runs when we start bash or mintty + if ( (Test-Path $($saveTo + "git-for-windows/etc/profile.d") ) ) { + Write-Verbose "Adding cmder.sh /etc/profile.d" + Copy-Item $($saveTo + "cmder.sh") $($saveTo + "git-for-windows/etc/profile.d/cmder.sh") + } + + # Replace /etc/profile.d/git-prompt.sh with cmder lambda prompt so it runs when we start bash or mintty + if ( !(Test-Path $($saveTo + "git-for-windows/etc/profile.d/git-prompt.sh.bak") ) ) { + Write-Verbose "Replacing /etc/profile.d/git-prompt.sh with our git-prompt.sh" + Move-Item $($saveTo + "git-for-windows/etc/profile.d/git-prompt.sh") $($saveTo + "git-for-windows/etc/profile.d/git-prompt.sh.bak") + Copy-Item $($saveTo + "git-prompt.sh") $($saveTo + "git-for-windows/etc/profile.d/git-prompt.sh") + } + + Pop-Location +} + +if (-not $Compile -or $noVendor) { + Write-Warning "You are not building the full project, Use -Compile without -noVendor" + Write-Warning "This cannot be a release. Test build only!" + return +} + +Write-Verbose "Successfully built Cmder v$version!" + +if ( $Env:APPVEYOR -eq 'True' ) { + Add-AppveyorMessage -Message "Building Cmder v$version was successful." -Category Information +} + +if ( $Env:GITHUB_ACTIONS -eq 'true' ) { + Write-Output "::notice title=Build Complete::Building Cmder v$version was successful." +} + +Write-Host -ForegroundColor green "All good and done!" diff --git a/scripts/pack.ps1 b/scripts/pack.ps1 index 418fdcd..eaad68d 100644 --- a/scripts/pack.ps1 +++ b/scripts/pack.ps1 @@ -1,76 +1,76 @@ -<# -.Synopsis - Pack Cmder -.DESCRIPTION - Use this script to pack cmder into release archives - - You will need to make this script executable by setting your Powershell Execution Policy to Remote signed - Then unblock the script for execution with UnblockFile .\pack.ps1 -.EXAMPLE - .\pack.ps1 - - Creates default archives for cmder -.EXAMPLE - .\pack.ps1 -verbose - - Creates default archives for cmder with plenty of information -.NOTES - AUTHORS - Samuel Vasko, Jack Bennett, Martin Kemp - Part of the Cmder project. -.LINK - https://github.com/cmderdev/cmder - Project Home -#> - -[CmdletBinding(SupportsShouldProcess = $true)] -Param( - # CmdletBinding will give us; - # -verbose switch to turn on logging and - # -whatif switch to not actually make changes - - # Path to the vendor configuration source file - [string]$cmderRoot = "$PSScriptRoot\..", - - # Vendor folder locaton - [string]$saveTo = "$PSScriptRoot\..\build" -) - -$cmderRoot = Resolve-Path $cmderRoot - -. "$PSScriptRoot\utils.ps1" -$ErrorActionPreference = "Stop" -Ensure-Executable "7z" - -$targets = @{ - "cmder.7z" = "-t7z -m0=lzma2 -mx=9 -mfb=64 -md=32m -ms=on -myx=7 -mqs=on"; - "cmder.zip" = "-mm=Deflate -mfb=128 -mpass=3"; - "cmder_mini.zip" = "-xr!`"vendor\git-for-windows`""; -} - -Push-Location -Path $cmderRoot - -Delete-Existing "$cmderRoot\Version*" -Delete-Existing "$cmderRoot\build\*" - -if (-not (Test-Path -PathType container $saveTo)) { - (New-Item -ItemType Directory -Path $saveTo) | Out-Null -} - -$saveTo = Resolve-Path $saveTo - -$version = Get-VersionStr -(New-Item -ItemType file "$cmderRoot\Version $version") | Out-Null - -if ($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent) { - Write-Verbose "Packing Cmder $version in $saveTo..." - $excluded = (Get-Content -Path "$cmderRoot\packignore") -Split [System.Environment]::NewLine | Where-Object { $_ } - Get-ChildItem $cmderRoot -Force -Exclude $excluded -} - -foreach ($t in $targets.GetEnumerator()) { - Create-Archive "$cmderRoot" "$saveTo\$($t.Name)" $t.Value - $hash = (Digest-Hash "$saveTo\$($t.Name)") - Add-Content -path "$saveTo\hashes.txt" -value ($t.Name + ' ' + $hash) -} - -Pop-Location +<# +.Synopsis + Pack Cmder +.DESCRIPTION + Use this script to pack Cmder into release archives + + You will need to make this script executable by setting your Powershell Execution Policy to Remote signed + Then unblock the script for execution with UnblockFile .\pack.ps1 +.EXAMPLE + .\pack.ps1 + + Creates default archives for Cmder +.EXAMPLE + .\pack.ps1 -verbose + + Creates default archives for Cmder with plenty of information +.NOTES + AUTHORS + Samuel Vasko, Jack Bennett, Martin Kemp + Part of the Cmder project. +.LINK + https://github.com/cmderdev/cmder - Project Home +#> + +[CmdletBinding(SupportsShouldProcess = $true)] +Param( + # CmdletBinding will give us; + # -verbose switch to turn on logging and + # -whatif switch to not actually make changes + + # Path to the vendor configuration source file + [string]$cmderRoot = "$PSScriptRoot\..", + + # Vendor folder locaton + [string]$saveTo = "$PSScriptRoot\..\build" +) + +$cmderRoot = Resolve-Path $cmderRoot + +. "$PSScriptRoot\utils.ps1" +$ErrorActionPreference = "Stop" +Ensure-Executable "7z" + +$targets = @{ + "cmder.7z" = "-t7z -m0=lzma2 -mx=9 -mfb=64 -md=32m -ms=on -myx=7 -mqs=on"; + "cmder.zip" = "-mm=Deflate -mfb=128 -mpass=3"; + "cmder_mini.zip" = "-xr!`"vendor\git-for-windows`""; +} + +Push-Location -Path $cmderRoot + +Delete-Existing "$cmderRoot\Version*" +Delete-Existing "$cmderRoot\build\*" + +if (-not (Test-Path -PathType container $saveTo)) { + (New-Item -ItemType Directory -Path $saveTo) | Out-Null +} + +$saveTo = Resolve-Path $saveTo + +$version = Get-VersionStr +(New-Item -ItemType file "$cmderRoot\Version $version") | Out-Null + +if ($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent) { + Write-Verbose "Packing Cmder $version in $saveTo..." + $excluded = (Get-Content -Path "$cmderRoot\packignore") -Split [System.Environment]::NewLine | Where-Object { $_ } + Get-ChildItem $cmderRoot -Force -Exclude $excluded +} + +foreach ($t in $targets.GetEnumerator()) { + Create-Archive "$cmderRoot" "$saveTo\$($t.Name)" $t.Value + $hash = (Digest-Hash "$saveTo\$($t.Name)") + Add-Content -path "$saveTo\hashes.txt" -value ($t.Name + ' ' + $hash) +} + +Pop-Location diff --git a/scripts/utils.ps1 b/scripts/utils.ps1 index 2b81a70..0ac1bc0 100644 --- a/scripts/utils.ps1 +++ b/scripts/utils.ps1 @@ -1,251 +1,251 @@ -function Ensure-Exists($path) { - if (-not (Test-Path $path)) { - Write-Error "Missing required $path! Ensure it is installed" - exit 1 - } - return $true > $null -} - -function Ensure-Executable($command) { - try { Get-Command $command -ErrorAction Stop > $null } - catch { - if( ($command -eq "7z") -and (Test-Path "$env:programfiles\7-zip\7z.exe") ){ - Set-Alias -Name "7z" -Value "$env:programfiles\7-zip\7z.exe" -Scope script - } - elseif( ($command -eq "7z") -and (Test-Path "$env:programw6432\7-zip\7z.exe") ) { - Set-Alias -Name "7z" -Value "$env:programw6432\7-zip\7z.exe" -Scope script - } - else { - Write-Error "Missing $command! Ensure it is installed and on in the PATH" - exit 1 - } - } -} - -function Delete-Existing($path) { - if (Test-Path $path) { - Write-Verbose "Remove existing $path" - } - Remove-Item -Recurse -Force $path -ErrorAction SilentlyContinue -} - -function Extract-Archive($source, $target) { - Write-Verbose $("Extracting Archive '$cmder_root\vendor\" + $source.replace('/','\') + " to '$cmder_root\vendor\$target'") - Invoke-Expression "7z x -y -o`"$($target)`" `"$source`" > `$null" - if ($LastExitCode -ne 0) { - Write-Error "Extracting of $source failed" - } - Remove-Item $source -} - -function Create-Archive($source, $target, $params) { - $command = "7z a -x@`"$source\packignore`" $params `"$target`" `"*`" > `$null" - Write-Verbose "Creating Archive from '$source' in '$target' with parameters '$params'" - Push-Location $source - Invoke-Expression $command - Pop-Location - if ($LastExitCode -ne 0) { - Write-Error "Compressing $source failed" - } -} - -# If directory contains only one child directory -# Flatten it instead -function Flatten-Directory($name) { - $name = Resolve-Path $name - $moving = "$($name)_moving" - Rename-Item $name -NewName $moving - Write-Verbose "Flattening the '$name' directory..." - $child = (Get-ChildItem $moving)[0] | Resolve-Path - Move-Item -Path $child -Destination $name - Remove-Item -Recurse $moving -} - -function Digest-Hash($path) { - if (Get-Command Get-FileHash -ErrorAction SilentlyContinue) { - return (Get-FileHash -Algorithm SHA256 -Path $path).Hash - } - - return Invoke-Expression "md5sum $path" -} - -function Set-GHVariable { - param( - [Parameter(Mandatory = $true)] - [string]$Name, - [Parameter(Mandatory = $true)] - [string]$Value - ) - - Write-Verbose "Setting CI variable $Name to $Value" -Verbose - - if ($env:GITHUB_ENV) { - Write-Output "$Name=$Value" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 - } -} - -function Get-GHTempPath { - $temp = [System.IO.Path]::GetTempPath() - if ($env:RUNNER_TEMP) { - $temp = $env:RUNNER_TEMP - } - - Write-Verbose "Get CI Temp path: $temp" -Verbose - return $temp -} - -function Get-VersionStr { - # Clear existing variable - if ($string) { Clear-Variable -name string } - - # Determine if git is available - if (Get-Command "git.exe" -ErrorAction SilentlyContinue) { - # Determine if the current directory is a git repository - $GitPresent = Invoke-Expression "git rev-parse --is-inside-work-tree" -ErrorAction SilentlyContinue - - if ( $GitPresent -eq 'true' ) { - $string = Invoke-Expression "git describe --abbrev=0 --tags" - } - } - - # Fallback used when Git is not available - if ( -not($string) ) { - $string = Parse-Changelog ($PSScriptRoot + '\..\' + 'CHANGELOG.md') - } - - # Add build number, if AppVeyor is present - if ( $Env:APPVEYOR -eq 'True' ) { - $string = $string + '.' + $Env:APPVEYOR_BUILD_NUMBER - } - elseif ( $Env:GITHUB_ACTIONS -eq 'true' ) { - $string = $string + '.' + $Env:GITHUB_RUN_NUMBER - } - - # Remove starting 'v' characters - $string = $string -replace '^v+','' # normalize version string - - return $string -} - -function Parse-Changelog($file) { - # Define the regular expression to match the version string from changelog - [regex]$regex = '^## \[(?[\w\-\.]+)\]\([^\n()]+\)\s+\([^\n()]+\)$'; - - # Find the first match of the version string which means the latest version - $version = Select-String -Path $file -Pattern $regex | Select-Object -First 1 | ForEach-Object { $_.Matches.Groups[1].Value } - - return $version -} - -function Create-RC($string, $path) { - $version = $string + '.0.0.0.0' # padding for version string - - if ( !(Test-Path "$path.sample") ) { - throw "Invalid path provided for resources file." - } - - $resource = Get-Content -Path "$path.sample" - $pattern = @( "Cmder-Major-Version", "Cmder-Minor-Version", "Cmder-Revision-Version", "Cmder-Build-Version" ) - $index = 0 - - # Replace all non-numeric characters to dots and split to array - $version = $version -replace '[^0-9]+','.' -split '\.' - - foreach ($fragment in $version) { - if ( !$fragment ) { break } - elseif ($index -le $pattern.length) { - $resource = $resource.Replace( "{" + $pattern[$index++] + "}", $fragment ) - } - } - - # Add the version string - $resource = $resource.Replace( "{Cmder-Version-Str}", '"' + $string + '"' ) - - # Write the results - Set-Content -Path $path -Value $resource -} - -function Register-Cmder() { - [CmdletBinding()] - Param - ( - # Text for the context menu item. - $MenuText = "Cmder Here" - - , # Defaults to the current cmder directory when run from cmder. - $PathToExe = (Join-Path $env:CMDER_ROOT "cmder.exe") - - , # Commands the context menu will execute. - $Command = "%V" - - , # Defaults to the icons folder in the cmder package. - $icon = (Split-Path $PathToExe | Join-Path -ChildPath 'icons/cmder.ico') - ) - Begin - { - New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT > $null - } - Process - { - New-Item -Path "HKCR:\Directory\Shell\Cmder" -Force -Value $MenuText - New-ItemProperty -Path "HKCR:\Directory\Shell\Cmder" -Force -Name "Icon" -Value `"$icon`" - New-ItemProperty -Path "HKCR:\Directory\Shell\Cmder" -Force -Name "NoWorkingDirectory" - New-Item -Path "HKCR:\Directory\Shell\Cmder\Command" -Force -Value "`"$PathToExe`" `"$Command`" " - - New-Item -Path "HKCR:\Directory\Background\Shell\Cmder" -Force -Value $MenuText - New-ItemProperty -Path "HKCR:\Directory\Background\Shell\Cmder" -Force -Name "Icon" -Value `"$icon`" - New-ItemProperty -Path "HKCR:\Directory\Background\Shell\Cmder" -Force -Name "NoWorkingDirectory" - New-Item -Path "HKCR:\Directory\Background\Shell\Cmder\Command" -Force -Value "`"$PathToExe`" `"$Command`" " - } - End - { - Remove-PSDrive -Name HKCR - } -} - -function Unregister-Cmder { - Begin - { - New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT > $null - } - Process - { - Remove-Item -Path "HKCR:\Directory\Shell\Cmder" -Recurse - Remove-Item -Path "HKCR:\Directory\Background\Shell\Cmder" -Recurse - } - End - { - Remove-PSDrive -Name HKCR - } -} - -function Download-File { - param ( - $Url, - $File - ) - [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 - - $useBitTransfer = $null -ne (Get-Module -Name BitsTransfer -ListAvailable) -and ($PSVersionTable.PSVersion.Major -le 5) - - $File = $File -replace "/", "\" - - try { - if ($useBitTransfer) { - Start-BitsTransfer -Source $Url -Destination $File -DisplayName "Downloading '$Url' to $File" - return - } - } - catch { - Write-Error "Failed to download file using BITS, reason: $_`nUsing fallback method instead...`n" -ErrorAction:Continue - } - - Write-Verbose "Downloading from $Url to $File`n" - - $wc = New-Object System.Net.WebClient - if ($env:https_proxy) { - $wc.proxy = (New-Object System.Net.WebProxy($env:https_proxy)) - } - $wc.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials; - $wc.DownloadFile($Url, $File) -} +function Ensure-Exists($path) { + if (-not (Test-Path $path)) { + Write-Error "Missing required $path! Ensure it is installed" + exit 1 + } + return $true > $null +} + +function Ensure-Executable($command) { + try { Get-Command $command -ErrorAction Stop > $null } + catch { + if( ($command -eq "7z") -and (Test-Path "$env:programfiles\7-zip\7z.exe") ){ + Set-Alias -Name "7z" -Value "$env:programfiles\7-zip\7z.exe" -Scope script + } + elseif( ($command -eq "7z") -and (Test-Path "$env:programw6432\7-zip\7z.exe") ) { + Set-Alias -Name "7z" -Value "$env:programw6432\7-zip\7z.exe" -Scope script + } + else { + Write-Error "Missing $command! Ensure it is installed and on in the PATH" + exit 1 + } + } +} + +function Delete-Existing($path) { + if (Test-Path $path) { + Write-Verbose "Remove existing $path" + } + Remove-Item -Recurse -Force $path -ErrorAction SilentlyContinue +} + +function Extract-Archive($source, $target) { + Write-Verbose $("Extracting Archive '$cmder_root\vendor\" + $source.replace('/','\') + " to '$cmder_root\vendor\$target'") + Invoke-Expression "7z x -y -o`"$($target)`" `"$source`" > `$null" + if ($LastExitCode -ne 0) { + Write-Error "Extracting of $source failed" + } + Remove-Item $source +} + +function Create-Archive($source, $target, $params) { + $command = "7z a -x@`"$source\packignore`" $params `"$target`" `"*`" > `$null" + Write-Verbose "Creating Archive from '$source' in '$target' with parameters '$params'" + Push-Location $source + Invoke-Expression $command + Pop-Location + if ($LastExitCode -ne 0) { + Write-Error "Compressing $source failed" + } +} + +# If directory contains only one child directory +# Flatten it instead +function Flatten-Directory($name) { + $name = Resolve-Path $name + $moving = "$($name)_moving" + Rename-Item $name -NewName $moving + Write-Verbose "Flattening the '$name' directory..." + $child = (Get-ChildItem $moving)[0] | Resolve-Path + Move-Item -Path $child -Destination $name + Remove-Item -Recurse $moving +} + +function Digest-Hash($path) { + if (Get-Command Get-FileHash -ErrorAction SilentlyContinue) { + return (Get-FileHash -Algorithm SHA256 -Path $path).Hash + } + + return Invoke-Expression "md5sum $path" +} + +function Set-GHVariable { + param( + [Parameter(Mandatory = $true)] + [string]$Name, + [Parameter(Mandatory = $true)] + [string]$Value + ) + + Write-Verbose "Setting CI variable $Name to $Value" -Verbose + + if ($env:GITHUB_ENV) { + Write-Output "$Name=$Value" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 + } +} + +function Get-GHTempPath { + $temp = [System.IO.Path]::GetTempPath() + if ($env:RUNNER_TEMP) { + $temp = $env:RUNNER_TEMP + } + + Write-Verbose "Get CI Temp path: $temp" -Verbose + return $temp +} + +function Get-VersionStr { + # Clear existing variable + if ($string) { Clear-Variable -name string } + + # Determine if git is available + if (Get-Command "git.exe" -ErrorAction SilentlyContinue) { + # Determine if the current directory is a git repository + $GitPresent = Invoke-Expression "git rev-parse --is-inside-work-tree" -ErrorAction SilentlyContinue + + if ( $GitPresent -eq 'true' ) { + $string = Invoke-Expression "git describe --abbrev=0 --tags" + } + } + + # Fallback used when Git is not available + if ( -not($string) ) { + $string = Parse-Changelog ($PSScriptRoot + '\..\' + 'CHANGELOG.md') + } + + # Add build number, if AppVeyor is present + if ( $Env:APPVEYOR -eq 'True' ) { + $string = $string + '.' + $Env:APPVEYOR_BUILD_NUMBER + } + elseif ( $Env:GITHUB_ACTIONS -eq 'true' ) { + $string = $string + '.' + $Env:GITHUB_RUN_NUMBER + } + + # Remove starting 'v' characters + $string = $string -replace '^v+','' # normalize version string + + return $string +} + +function Parse-Changelog($file) { + # Define the regular expression to match the version string from changelog + [regex]$regex = '^## \[(?[\w\-\.]+)\]\([^\n()]+\)\s+\([^\n()]+\)$'; + + # Find the first match of the version string which means the latest version + $version = Select-String -Path $file -Pattern $regex | Select-Object -First 1 | ForEach-Object { $_.Matches.Groups[1].Value } + + return $version +} + +function Create-RC($string, $path) { + $version = $string + '.0.0.0.0' # padding for version string + + if ( !(Test-Path "$path.sample") ) { + throw "Invalid path provided for resources file." + } + + $resource = Get-Content -Path "$path.sample" + $pattern = @( "Cmder-Major-Version", "Cmder-Minor-Version", "Cmder-Revision-Version", "Cmder-Build-Version" ) + $index = 0 + + # Replace all non-numeric characters to dots and split to array + $version = $version -replace '[^0-9]+','.' -split '\.' + + foreach ($fragment in $version) { + if ( !$fragment ) { break } + elseif ($index -le $pattern.length) { + $resource = $resource.Replace( "{" + $pattern[$index++] + "}", $fragment ) + } + } + + # Add the version string + $resource = $resource.Replace( "{Cmder-Version-Str}", '"' + $string + '"' ) + + # Write the results + Set-Content -Path $path -Value $resource +} + +function Register-Cmder() { + [CmdletBinding()] + Param + ( + # Text for the context menu item. + $MenuText = "Cmder Here" + + , # Defaults to the current Cmder directory when run from Cmder. + $PathToExe = (Join-Path $env:CMDER_ROOT "cmder.exe") + + , # Commands the context menu will execute. + $Command = "%V" + + , # Defaults to the icons folder in the Cmder package. + $icon = (Split-Path $PathToExe | Join-Path -ChildPath 'icons/cmder.ico') + ) + Begin + { + New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT > $null + } + Process + { + New-Item -Path "HKCR:\Directory\Shell\Cmder" -Force -Value $MenuText + New-ItemProperty -Path "HKCR:\Directory\Shell\Cmder" -Force -Name "Icon" -Value `"$icon`" + New-ItemProperty -Path "HKCR:\Directory\Shell\Cmder" -Force -Name "NoWorkingDirectory" + New-Item -Path "HKCR:\Directory\Shell\Cmder\Command" -Force -Value "`"$PathToExe`" `"$Command`" " + + New-Item -Path "HKCR:\Directory\Background\Shell\Cmder" -Force -Value $MenuText + New-ItemProperty -Path "HKCR:\Directory\Background\Shell\Cmder" -Force -Name "Icon" -Value `"$icon`" + New-ItemProperty -Path "HKCR:\Directory\Background\Shell\Cmder" -Force -Name "NoWorkingDirectory" + New-Item -Path "HKCR:\Directory\Background\Shell\Cmder\Command" -Force -Value "`"$PathToExe`" `"$Command`" " + } + End + { + Remove-PSDrive -Name HKCR + } +} + +function Unregister-Cmder { + Begin + { + New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT > $null + } + Process + { + Remove-Item -Path "HKCR:\Directory\Shell\Cmder" -Recurse + Remove-Item -Path "HKCR:\Directory\Background\Shell\Cmder" -Recurse + } + End + { + Remove-PSDrive -Name HKCR + } +} + +function Download-File { + param ( + $Url, + $File + ) + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + + $useBitTransfer = $null -ne (Get-Module -Name BitsTransfer -ListAvailable) -and ($PSVersionTable.PSVersion.Major -le 5) + + $File = $File -replace "/", "\" + + try { + if ($useBitTransfer) { + Start-BitsTransfer -Source $Url -Destination $File -DisplayName "Downloading '$Url' to $File" + return + } + } + catch { + Write-Error "Failed to download file using BITS, reason: $_`nUsing fallback method instead...`n" -ErrorAction:Continue + } + + Write-Verbose "Downloading from $Url to $File`n" + + $wc = New-Object System.Net.WebClient + if ($env:https_proxy) { + $wc.proxy = (New-Object System.Net.WebProxy($env:https_proxy)) + } + $wc.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials; + $wc.DownloadFile($Url, $File) +} From be44bac95670b1cbbc91bd657882d985989846f9 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sun, 9 Nov 2025 03:59:33 +0330 Subject: [PATCH 80/84] fix line endings --- scripts/build.ps1 | 362 ++++++++++++++++----------------- scripts/pack.ps1 | 152 +++++++------- scripts/utils.ps1 | 502 +++++++++++++++++++++++----------------------- 3 files changed, 508 insertions(+), 508 deletions(-) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 735245d..d4ccb67 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -1,181 +1,181 @@ -<# -.Synopsis - Build Cmder -.DESCRIPTION - Use this script to build your own edition of Cmder - - This script builds dependencies from current vendor/sources.json file and unpacks them. - - You will need to make this script executable by setting your Powershell Execution Policy to Remote signed - Then unblock the script for execution with UnblockFile .\build.ps1 -.EXAMPLE - .\build.ps1 - - Executes the default build for Cmder; ConEmu, clink. This is equivalent to the "minimum" style package in the releases -.EXAMPLE - .\build.ps1 -Compile - - Recompile the launcher executable if you have the requisite build tools for C++ installed. -.EXAMPLE - .\build.ps1 -Compile -NoVendor - - Skip all downloads and only build launcher. -.EXAMPLE - .\build -verbose - - Execute the build and see what's going on. -.EXAMPLE - .\build.ps1 -SourcesPath '~/custom/vendors.json' - - Build Cmder with your own packages. See vendor/sources.json for the syntax you need to copy. -.NOTES - AUTHORS - Samuel Vasko, Jack Bennett - Part of the Cmder project. -.LINK - http://cmder.app/ - Project Home -#> -[CmdletBinding(SupportsShouldProcess = $true)] -Param( - # CmdletBinding will give us; - # -verbose switch to turn on logging and - # -whatif switch to not actually make changes - - # Path to the vendor configuration source file - [string]$sourcesPath = "$PSScriptRoot\..\vendor\sources.json", - - # Vendor folder location - [string]$saveTo = "$PSScriptRoot\..\vendor\", - - # Launcher folder location - [string]$launcher = "$PSScriptRoot\..\launcher", - - # Config folder location - [string]$config = "$PSScriptRoot\..\config", - - # Using this option will skip all downloads, if you only need to build launcher - [switch]$noVendor, - - # Build launcher if you have MSBuild tools installed - [switch]$Compile -) - -# Get the scripts and Cmder root dirs we are building in. -$cmder_root = Resolve-Path "$PSScriptRoot\.." - -# Dot source util functions into this scope -. "$PSScriptRoot\utils.ps1" -$ErrorActionPreference = "Stop" - -if ($Compile) { - # Check for requirements - Ensure-Executable "msbuild" - - # Get the version string - $version = Get-VersionStr - - Push-Location -Path $launcher - Create-RC $version ($launcher + '\src\version.rc2') - - Write-Verbose "Building the launcher..." - - # Reference: https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference - msbuild CmderLauncher.vcxproj /t:Clean,Build /p:configuration=Release /m - - if ($LastExitCode -ne 0) { - throw "MSBuild failed to build the launcher executable." - } - Pop-Location -} - -if (-not $noVendor) { - # Check for requirements - Ensure-Exists $sourcesPath - Ensure-Executable "7z" - - # Get the vendor sources - $sources = Get-Content $sourcesPath | Out-String | ConvertFrom-Json - - Push-Location -Path $saveTo - New-Item -Type Directory -Path (Join-Path $saveTo "/tmp/") -ErrorAction SilentlyContinue >$null - - $vend = $pwd - - # Preserve modified (by user) ConEmu setting file - if ($config -ne "") { - $ConEmuXml = Join-Path $saveTo "conemu-maximus5\ConEmu.xml" - if (Test-Path $ConEmuXml -pathType leaf) { - $ConEmuXmlSave = Join-Path $config "ConEmu.xml" - Write-Verbose "Backup '$ConEmuXml' to '$ConEmuXmlSave'" - Copy-Item $ConEmuXml $ConEmuXmlSave - } - else { $ConEmuXml = "" } - } - else { $ConEmuXml = "" } - - # Kill ssh-agent.exe if it is running from the $env:cmder_root we are building - foreach ($ssh_agent in $(Get-Process ssh-agent -ErrorAction SilentlyContinue)) { - if ([string]$($ssh_agent.path) -Match [string]$cmder_root.replace('\', '\\')) { - Write-Verbose $("Stopping " + $ssh_agent.path + "!") - Stop-Process $ssh_agent.id - } - } - - foreach ($s in $sources) { - Write-Verbose "Getting vendored $($s.name) $($s.version)..." - - # We do not care about the extensions/type of archive - $tempArchive = "tmp/$($s.name).tmp" - Delete-Existing $tempArchive - Delete-Existing $s.name - - Download-File -Url $s.url -File $vend\$tempArchive -ErrorAction Stop - Extract-Archive $tempArchive $s.name - - if ((Get-ChildItem $s.name).Count -eq 1) { - Flatten-Directory($s.name) - } - - # Write current version to .cmderver file, for later. - "$($s.version)" | Out-File "$($s.name)/.cmderver" - } - - # Restore ConEmu user configuration - if ($ConEmuXml -ne "") { - Write-Verbose "Restore '$ConEmuXmlSave' to '$ConEmuXml'" - Copy-Item $ConEmuXmlSave $ConEmuXml - } - - # Put vendor\cmder.sh in /etc/profile.d so it runs when we start bash or mintty - if ( (Test-Path $($saveTo + "git-for-windows/etc/profile.d") ) ) { - Write-Verbose "Adding cmder.sh /etc/profile.d" - Copy-Item $($saveTo + "cmder.sh") $($saveTo + "git-for-windows/etc/profile.d/cmder.sh") - } - - # Replace /etc/profile.d/git-prompt.sh with cmder lambda prompt so it runs when we start bash or mintty - if ( !(Test-Path $($saveTo + "git-for-windows/etc/profile.d/git-prompt.sh.bak") ) ) { - Write-Verbose "Replacing /etc/profile.d/git-prompt.sh with our git-prompt.sh" - Move-Item $($saveTo + "git-for-windows/etc/profile.d/git-prompt.sh") $($saveTo + "git-for-windows/etc/profile.d/git-prompt.sh.bak") - Copy-Item $($saveTo + "git-prompt.sh") $($saveTo + "git-for-windows/etc/profile.d/git-prompt.sh") - } - - Pop-Location -} - -if (-not $Compile -or $noVendor) { - Write-Warning "You are not building the full project, Use -Compile without -noVendor" - Write-Warning "This cannot be a release. Test build only!" - return -} - -Write-Verbose "Successfully built Cmder v$version!" - -if ( $Env:APPVEYOR -eq 'True' ) { - Add-AppveyorMessage -Message "Building Cmder v$version was successful." -Category Information -} - -if ( $Env:GITHUB_ACTIONS -eq 'true' ) { - Write-Output "::notice title=Build Complete::Building Cmder v$version was successful." -} - -Write-Host -ForegroundColor green "All good and done!" +<# +.Synopsis + Build Cmder +.DESCRIPTION + Use this script to build your own edition of Cmder + + This script builds dependencies from current vendor/sources.json file and unpacks them. + + You will need to make this script executable by setting your Powershell Execution Policy to Remote signed + Then unblock the script for execution with UnblockFile .\build.ps1 +.EXAMPLE + .\build.ps1 + + Executes the default build for Cmder; ConEmu, clink. This is equivalent to the "minimum" style package in the releases +.EXAMPLE + .\build.ps1 -Compile + + Recompile the launcher executable if you have the requisite build tools for C++ installed. +.EXAMPLE + .\build.ps1 -Compile -NoVendor + + Skip all downloads and only build launcher. +.EXAMPLE + .\build -verbose + + Execute the build and see what's going on. +.EXAMPLE + .\build.ps1 -SourcesPath '~/custom/vendors.json' + + Build Cmder with your own packages. See vendor/sources.json for the syntax you need to copy. +.NOTES + AUTHORS + Samuel Vasko, Jack Bennett + Part of the Cmder project. +.LINK + http://cmder.app/ - Project Home +#> +[CmdletBinding(SupportsShouldProcess = $true)] +Param( + # CmdletBinding will give us; + # -verbose switch to turn on logging and + # -whatif switch to not actually make changes + + # Path to the vendor configuration source file + [string]$sourcesPath = "$PSScriptRoot\..\vendor\sources.json", + + # Vendor folder location + [string]$saveTo = "$PSScriptRoot\..\vendor\", + + # Launcher folder location + [string]$launcher = "$PSScriptRoot\..\launcher", + + # Config folder location + [string]$config = "$PSScriptRoot\..\config", + + # Using this option will skip all downloads, if you only need to build launcher + [switch]$noVendor, + + # Build launcher if you have MSBuild tools installed + [switch]$Compile +) + +# Get the scripts and Cmder root dirs we are building in. +$cmder_root = Resolve-Path "$PSScriptRoot\.." + +# Dot source util functions into this scope +. "$PSScriptRoot\utils.ps1" +$ErrorActionPreference = "Stop" + +if ($Compile) { + # Check for requirements + Ensure-Executable "msbuild" + + # Get the version string + $version = Get-VersionStr + + Push-Location -Path $launcher + Create-RC $version ($launcher + '\src\version.rc2') + + Write-Verbose "Building the launcher..." + + # Reference: https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference + msbuild CmderLauncher.vcxproj /t:Clean,Build /p:configuration=Release /m + + if ($LastExitCode -ne 0) { + throw "MSBuild failed to build the launcher executable." + } + Pop-Location +} + +if (-not $noVendor) { + # Check for requirements + Ensure-Exists $sourcesPath + Ensure-Executable "7z" + + # Get the vendor sources + $sources = Get-Content $sourcesPath | Out-String | ConvertFrom-Json + + Push-Location -Path $saveTo + New-Item -Type Directory -Path (Join-Path $saveTo "/tmp/") -ErrorAction SilentlyContinue >$null + + $vend = $pwd + + # Preserve modified (by user) ConEmu setting file + if ($config -ne "") { + $ConEmuXml = Join-Path $saveTo "conemu-maximus5\ConEmu.xml" + if (Test-Path $ConEmuXml -pathType leaf) { + $ConEmuXmlSave = Join-Path $config "ConEmu.xml" + Write-Verbose "Backup '$ConEmuXml' to '$ConEmuXmlSave'" + Copy-Item $ConEmuXml $ConEmuXmlSave + } + else { $ConEmuXml = "" } + } + else { $ConEmuXml = "" } + + # Kill ssh-agent.exe if it is running from the $env:cmder_root we are building + foreach ($ssh_agent in $(Get-Process ssh-agent -ErrorAction SilentlyContinue)) { + if ([string]$($ssh_agent.path) -Match [string]$cmder_root.replace('\', '\\')) { + Write-Verbose $("Stopping " + $ssh_agent.path + "!") + Stop-Process $ssh_agent.id + } + } + + foreach ($s in $sources) { + Write-Verbose "Getting vendored $($s.name) $($s.version)..." + + # We do not care about the extensions/type of archive + $tempArchive = "tmp/$($s.name).tmp" + Delete-Existing $tempArchive + Delete-Existing $s.name + + Download-File -Url $s.url -File $vend\$tempArchive -ErrorAction Stop + Extract-Archive $tempArchive $s.name + + if ((Get-ChildItem $s.name).Count -eq 1) { + Flatten-Directory($s.name) + } + + # Write current version to .cmderver file, for later. + "$($s.version)" | Out-File "$($s.name)/.cmderver" + } + + # Restore ConEmu user configuration + if ($ConEmuXml -ne "") { + Write-Verbose "Restore '$ConEmuXmlSave' to '$ConEmuXml'" + Copy-Item $ConEmuXmlSave $ConEmuXml + } + + # Put vendor\cmder.sh in /etc/profile.d so it runs when we start bash or mintty + if ( (Test-Path $($saveTo + "git-for-windows/etc/profile.d") ) ) { + Write-Verbose "Adding cmder.sh /etc/profile.d" + Copy-Item $($saveTo + "cmder.sh") $($saveTo + "git-for-windows/etc/profile.d/cmder.sh") + } + + # Replace /etc/profile.d/git-prompt.sh with cmder lambda prompt so it runs when we start bash or mintty + if ( !(Test-Path $($saveTo + "git-for-windows/etc/profile.d/git-prompt.sh.bak") ) ) { + Write-Verbose "Replacing /etc/profile.d/git-prompt.sh with our git-prompt.sh" + Move-Item $($saveTo + "git-for-windows/etc/profile.d/git-prompt.sh") $($saveTo + "git-for-windows/etc/profile.d/git-prompt.sh.bak") + Copy-Item $($saveTo + "git-prompt.sh") $($saveTo + "git-for-windows/etc/profile.d/git-prompt.sh") + } + + Pop-Location +} + +if (-not $Compile -or $noVendor) { + Write-Warning "You are not building the full project, Use -Compile without -noVendor" + Write-Warning "This cannot be a release. Test build only!" + return +} + +Write-Verbose "Successfully built Cmder v$version!" + +if ( $Env:APPVEYOR -eq 'True' ) { + Add-AppveyorMessage -Message "Building Cmder v$version was successful." -Category Information +} + +if ( $Env:GITHUB_ACTIONS -eq 'true' ) { + Write-Output "::notice title=Build Complete::Building Cmder v$version was successful." +} + +Write-Host -ForegroundColor green "All good and done!" diff --git a/scripts/pack.ps1 b/scripts/pack.ps1 index eaad68d..8dccc5e 100644 --- a/scripts/pack.ps1 +++ b/scripts/pack.ps1 @@ -1,76 +1,76 @@ -<# -.Synopsis - Pack Cmder -.DESCRIPTION - Use this script to pack Cmder into release archives - - You will need to make this script executable by setting your Powershell Execution Policy to Remote signed - Then unblock the script for execution with UnblockFile .\pack.ps1 -.EXAMPLE - .\pack.ps1 - - Creates default archives for Cmder -.EXAMPLE - .\pack.ps1 -verbose - - Creates default archives for Cmder with plenty of information -.NOTES - AUTHORS - Samuel Vasko, Jack Bennett, Martin Kemp - Part of the Cmder project. -.LINK - https://github.com/cmderdev/cmder - Project Home -#> - -[CmdletBinding(SupportsShouldProcess = $true)] -Param( - # CmdletBinding will give us; - # -verbose switch to turn on logging and - # -whatif switch to not actually make changes - - # Path to the vendor configuration source file - [string]$cmderRoot = "$PSScriptRoot\..", - - # Vendor folder locaton - [string]$saveTo = "$PSScriptRoot\..\build" -) - -$cmderRoot = Resolve-Path $cmderRoot - -. "$PSScriptRoot\utils.ps1" -$ErrorActionPreference = "Stop" -Ensure-Executable "7z" - -$targets = @{ - "cmder.7z" = "-t7z -m0=lzma2 -mx=9 -mfb=64 -md=32m -ms=on -myx=7 -mqs=on"; - "cmder.zip" = "-mm=Deflate -mfb=128 -mpass=3"; - "cmder_mini.zip" = "-xr!`"vendor\git-for-windows`""; -} - -Push-Location -Path $cmderRoot - -Delete-Existing "$cmderRoot\Version*" -Delete-Existing "$cmderRoot\build\*" - -if (-not (Test-Path -PathType container $saveTo)) { - (New-Item -ItemType Directory -Path $saveTo) | Out-Null -} - -$saveTo = Resolve-Path $saveTo - -$version = Get-VersionStr -(New-Item -ItemType file "$cmderRoot\Version $version") | Out-Null - -if ($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent) { - Write-Verbose "Packing Cmder $version in $saveTo..." - $excluded = (Get-Content -Path "$cmderRoot\packignore") -Split [System.Environment]::NewLine | Where-Object { $_ } - Get-ChildItem $cmderRoot -Force -Exclude $excluded -} - -foreach ($t in $targets.GetEnumerator()) { - Create-Archive "$cmderRoot" "$saveTo\$($t.Name)" $t.Value - $hash = (Digest-Hash "$saveTo\$($t.Name)") - Add-Content -path "$saveTo\hashes.txt" -value ($t.Name + ' ' + $hash) -} - -Pop-Location +<# +.Synopsis + Pack Cmder +.DESCRIPTION + Use this script to pack Cmder into release archives + + You will need to make this script executable by setting your Powershell Execution Policy to Remote signed + Then unblock the script for execution with UnblockFile .\pack.ps1 +.EXAMPLE + .\pack.ps1 + + Creates default archives for Cmder +.EXAMPLE + .\pack.ps1 -verbose + + Creates default archives for Cmder with plenty of information +.NOTES + AUTHORS + Samuel Vasko, Jack Bennett, Martin Kemp + Part of the Cmder project. +.LINK + https://github.com/cmderdev/cmder - Project Home +#> + +[CmdletBinding(SupportsShouldProcess = $true)] +Param( + # CmdletBinding will give us; + # -verbose switch to turn on logging and + # -whatif switch to not actually make changes + + # Path to the vendor configuration source file + [string]$cmderRoot = "$PSScriptRoot\..", + + # Vendor folder locaton + [string]$saveTo = "$PSScriptRoot\..\build" +) + +$cmderRoot = Resolve-Path $cmderRoot + +. "$PSScriptRoot\utils.ps1" +$ErrorActionPreference = "Stop" +Ensure-Executable "7z" + +$targets = @{ + "cmder.7z" = "-t7z -m0=lzma2 -mx=9 -mfb=64 -md=32m -ms=on -myx=7 -mqs=on"; + "cmder.zip" = "-mm=Deflate -mfb=128 -mpass=3"; + "cmder_mini.zip" = "-xr!`"vendor\git-for-windows`""; +} + +Push-Location -Path $cmderRoot + +Delete-Existing "$cmderRoot\Version*" +Delete-Existing "$cmderRoot\build\*" + +if (-not (Test-Path -PathType container $saveTo)) { + (New-Item -ItemType Directory -Path $saveTo) | Out-Null +} + +$saveTo = Resolve-Path $saveTo + +$version = Get-VersionStr +(New-Item -ItemType file "$cmderRoot\Version $version") | Out-Null + +if ($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent) { + Write-Verbose "Packing Cmder $version in $saveTo..." + $excluded = (Get-Content -Path "$cmderRoot\packignore") -Split [System.Environment]::NewLine | Where-Object { $_ } + Get-ChildItem $cmderRoot -Force -Exclude $excluded +} + +foreach ($t in $targets.GetEnumerator()) { + Create-Archive "$cmderRoot" "$saveTo\$($t.Name)" $t.Value + $hash = (Digest-Hash "$saveTo\$($t.Name)") + Add-Content -path "$saveTo\hashes.txt" -value ($t.Name + ' ' + $hash) +} + +Pop-Location diff --git a/scripts/utils.ps1 b/scripts/utils.ps1 index 0ac1bc0..5895540 100644 --- a/scripts/utils.ps1 +++ b/scripts/utils.ps1 @@ -1,251 +1,251 @@ -function Ensure-Exists($path) { - if (-not (Test-Path $path)) { - Write-Error "Missing required $path! Ensure it is installed" - exit 1 - } - return $true > $null -} - -function Ensure-Executable($command) { - try { Get-Command $command -ErrorAction Stop > $null } - catch { - if( ($command -eq "7z") -and (Test-Path "$env:programfiles\7-zip\7z.exe") ){ - Set-Alias -Name "7z" -Value "$env:programfiles\7-zip\7z.exe" -Scope script - } - elseif( ($command -eq "7z") -and (Test-Path "$env:programw6432\7-zip\7z.exe") ) { - Set-Alias -Name "7z" -Value "$env:programw6432\7-zip\7z.exe" -Scope script - } - else { - Write-Error "Missing $command! Ensure it is installed and on in the PATH" - exit 1 - } - } -} - -function Delete-Existing($path) { - if (Test-Path $path) { - Write-Verbose "Remove existing $path" - } - Remove-Item -Recurse -Force $path -ErrorAction SilentlyContinue -} - -function Extract-Archive($source, $target) { - Write-Verbose $("Extracting Archive '$cmder_root\vendor\" + $source.replace('/','\') + " to '$cmder_root\vendor\$target'") - Invoke-Expression "7z x -y -o`"$($target)`" `"$source`" > `$null" - if ($LastExitCode -ne 0) { - Write-Error "Extracting of $source failed" - } - Remove-Item $source -} - -function Create-Archive($source, $target, $params) { - $command = "7z a -x@`"$source\packignore`" $params `"$target`" `"*`" > `$null" - Write-Verbose "Creating Archive from '$source' in '$target' with parameters '$params'" - Push-Location $source - Invoke-Expression $command - Pop-Location - if ($LastExitCode -ne 0) { - Write-Error "Compressing $source failed" - } -} - -# If directory contains only one child directory -# Flatten it instead -function Flatten-Directory($name) { - $name = Resolve-Path $name - $moving = "$($name)_moving" - Rename-Item $name -NewName $moving - Write-Verbose "Flattening the '$name' directory..." - $child = (Get-ChildItem $moving)[0] | Resolve-Path - Move-Item -Path $child -Destination $name - Remove-Item -Recurse $moving -} - -function Digest-Hash($path) { - if (Get-Command Get-FileHash -ErrorAction SilentlyContinue) { - return (Get-FileHash -Algorithm SHA256 -Path $path).Hash - } - - return Invoke-Expression "md5sum $path" -} - -function Set-GHVariable { - param( - [Parameter(Mandatory = $true)] - [string]$Name, - [Parameter(Mandatory = $true)] - [string]$Value - ) - - Write-Verbose "Setting CI variable $Name to $Value" -Verbose - - if ($env:GITHUB_ENV) { - Write-Output "$Name=$Value" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 - } -} - -function Get-GHTempPath { - $temp = [System.IO.Path]::GetTempPath() - if ($env:RUNNER_TEMP) { - $temp = $env:RUNNER_TEMP - } - - Write-Verbose "Get CI Temp path: $temp" -Verbose - return $temp -} - -function Get-VersionStr { - # Clear existing variable - if ($string) { Clear-Variable -name string } - - # Determine if git is available - if (Get-Command "git.exe" -ErrorAction SilentlyContinue) { - # Determine if the current directory is a git repository - $GitPresent = Invoke-Expression "git rev-parse --is-inside-work-tree" -ErrorAction SilentlyContinue - - if ( $GitPresent -eq 'true' ) { - $string = Invoke-Expression "git describe --abbrev=0 --tags" - } - } - - # Fallback used when Git is not available - if ( -not($string) ) { - $string = Parse-Changelog ($PSScriptRoot + '\..\' + 'CHANGELOG.md') - } - - # Add build number, if AppVeyor is present - if ( $Env:APPVEYOR -eq 'True' ) { - $string = $string + '.' + $Env:APPVEYOR_BUILD_NUMBER - } - elseif ( $Env:GITHUB_ACTIONS -eq 'true' ) { - $string = $string + '.' + $Env:GITHUB_RUN_NUMBER - } - - # Remove starting 'v' characters - $string = $string -replace '^v+','' # normalize version string - - return $string -} - -function Parse-Changelog($file) { - # Define the regular expression to match the version string from changelog - [regex]$regex = '^## \[(?[\w\-\.]+)\]\([^\n()]+\)\s+\([^\n()]+\)$'; - - # Find the first match of the version string which means the latest version - $version = Select-String -Path $file -Pattern $regex | Select-Object -First 1 | ForEach-Object { $_.Matches.Groups[1].Value } - - return $version -} - -function Create-RC($string, $path) { - $version = $string + '.0.0.0.0' # padding for version string - - if ( !(Test-Path "$path.sample") ) { - throw "Invalid path provided for resources file." - } - - $resource = Get-Content -Path "$path.sample" - $pattern = @( "Cmder-Major-Version", "Cmder-Minor-Version", "Cmder-Revision-Version", "Cmder-Build-Version" ) - $index = 0 - - # Replace all non-numeric characters to dots and split to array - $version = $version -replace '[^0-9]+','.' -split '\.' - - foreach ($fragment in $version) { - if ( !$fragment ) { break } - elseif ($index -le $pattern.length) { - $resource = $resource.Replace( "{" + $pattern[$index++] + "}", $fragment ) - } - } - - # Add the version string - $resource = $resource.Replace( "{Cmder-Version-Str}", '"' + $string + '"' ) - - # Write the results - Set-Content -Path $path -Value $resource -} - -function Register-Cmder() { - [CmdletBinding()] - Param - ( - # Text for the context menu item. - $MenuText = "Cmder Here" - - , # Defaults to the current Cmder directory when run from Cmder. - $PathToExe = (Join-Path $env:CMDER_ROOT "cmder.exe") - - , # Commands the context menu will execute. - $Command = "%V" - - , # Defaults to the icons folder in the Cmder package. - $icon = (Split-Path $PathToExe | Join-Path -ChildPath 'icons/cmder.ico') - ) - Begin - { - New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT > $null - } - Process - { - New-Item -Path "HKCR:\Directory\Shell\Cmder" -Force -Value $MenuText - New-ItemProperty -Path "HKCR:\Directory\Shell\Cmder" -Force -Name "Icon" -Value `"$icon`" - New-ItemProperty -Path "HKCR:\Directory\Shell\Cmder" -Force -Name "NoWorkingDirectory" - New-Item -Path "HKCR:\Directory\Shell\Cmder\Command" -Force -Value "`"$PathToExe`" `"$Command`" " - - New-Item -Path "HKCR:\Directory\Background\Shell\Cmder" -Force -Value $MenuText - New-ItemProperty -Path "HKCR:\Directory\Background\Shell\Cmder" -Force -Name "Icon" -Value `"$icon`" - New-ItemProperty -Path "HKCR:\Directory\Background\Shell\Cmder" -Force -Name "NoWorkingDirectory" - New-Item -Path "HKCR:\Directory\Background\Shell\Cmder\Command" -Force -Value "`"$PathToExe`" `"$Command`" " - } - End - { - Remove-PSDrive -Name HKCR - } -} - -function Unregister-Cmder { - Begin - { - New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT > $null - } - Process - { - Remove-Item -Path "HKCR:\Directory\Shell\Cmder" -Recurse - Remove-Item -Path "HKCR:\Directory\Background\Shell\Cmder" -Recurse - } - End - { - Remove-PSDrive -Name HKCR - } -} - -function Download-File { - param ( - $Url, - $File - ) - [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 - - $useBitTransfer = $null -ne (Get-Module -Name BitsTransfer -ListAvailable) -and ($PSVersionTable.PSVersion.Major -le 5) - - $File = $File -replace "/", "\" - - try { - if ($useBitTransfer) { - Start-BitsTransfer -Source $Url -Destination $File -DisplayName "Downloading '$Url' to $File" - return - } - } - catch { - Write-Error "Failed to download file using BITS, reason: $_`nUsing fallback method instead...`n" -ErrorAction:Continue - } - - Write-Verbose "Downloading from $Url to $File`n" - - $wc = New-Object System.Net.WebClient - if ($env:https_proxy) { - $wc.proxy = (New-Object System.Net.WebProxy($env:https_proxy)) - } - $wc.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials; - $wc.DownloadFile($Url, $File) -} +function Ensure-Exists($path) { + if (-not (Test-Path $path)) { + Write-Error "Missing required $path! Ensure it is installed" + exit 1 + } + return $true > $null +} + +function Ensure-Executable($command) { + try { Get-Command $command -ErrorAction Stop > $null } + catch { + if( ($command -eq "7z") -and (Test-Path "$env:programfiles\7-zip\7z.exe") ){ + Set-Alias -Name "7z" -Value "$env:programfiles\7-zip\7z.exe" -Scope script + } + elseif( ($command -eq "7z") -and (Test-Path "$env:programw6432\7-zip\7z.exe") ) { + Set-Alias -Name "7z" -Value "$env:programw6432\7-zip\7z.exe" -Scope script + } + else { + Write-Error "Missing $command! Ensure it is installed and on in the PATH" + exit 1 + } + } +} + +function Delete-Existing($path) { + if (Test-Path $path) { + Write-Verbose "Remove existing $path" + } + Remove-Item -Recurse -Force $path -ErrorAction SilentlyContinue +} + +function Extract-Archive($source, $target) { + Write-Verbose $("Extracting Archive '$cmder_root\vendor\" + $source.replace('/','\') + " to '$cmder_root\vendor\$target'") + Invoke-Expression "7z x -y -o`"$($target)`" `"$source`" > `$null" + if ($LastExitCode -ne 0) { + Write-Error "Extracting of $source failed" + } + Remove-Item $source +} + +function Create-Archive($source, $target, $params) { + $command = "7z a -x@`"$source\packignore`" $params `"$target`" `"*`" > `$null" + Write-Verbose "Creating Archive from '$source' in '$target' with parameters '$params'" + Push-Location $source + Invoke-Expression $command + Pop-Location + if ($LastExitCode -ne 0) { + Write-Error "Compressing $source failed" + } +} + +# If directory contains only one child directory +# Flatten it instead +function Flatten-Directory($name) { + $name = Resolve-Path $name + $moving = "$($name)_moving" + Rename-Item $name -NewName $moving + Write-Verbose "Flattening the '$name' directory..." + $child = (Get-ChildItem $moving)[0] | Resolve-Path + Move-Item -Path $child -Destination $name + Remove-Item -Recurse $moving +} + +function Digest-Hash($path) { + if (Get-Command Get-FileHash -ErrorAction SilentlyContinue) { + return (Get-FileHash -Algorithm SHA256 -Path $path).Hash + } + + return Invoke-Expression "md5sum $path" +} + +function Set-GHVariable { + param( + [Parameter(Mandatory = $true)] + [string]$Name, + [Parameter(Mandatory = $true)] + [string]$Value + ) + + Write-Verbose "Setting CI variable $Name to $Value" -Verbose + + if ($env:GITHUB_ENV) { + Write-Output "$Name=$Value" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 + } +} + +function Get-GHTempPath { + $temp = [System.IO.Path]::GetTempPath() + if ($env:RUNNER_TEMP) { + $temp = $env:RUNNER_TEMP + } + + Write-Verbose "Get CI Temp path: $temp" -Verbose + return $temp +} + +function Get-VersionStr { + # Clear existing variable + if ($string) { Clear-Variable -name string } + + # Determine if git is available + if (Get-Command "git.exe" -ErrorAction SilentlyContinue) { + # Determine if the current directory is a git repository + $GitPresent = Invoke-Expression "git rev-parse --is-inside-work-tree" -ErrorAction SilentlyContinue + + if ( $GitPresent -eq 'true' ) { + $string = Invoke-Expression "git describe --abbrev=0 --tags" + } + } + + # Fallback used when Git is not available + if ( -not($string) ) { + $string = Parse-Changelog ($PSScriptRoot + '\..\' + 'CHANGELOG.md') + } + + # Add build number, if AppVeyor is present + if ( $Env:APPVEYOR -eq 'True' ) { + $string = $string + '.' + $Env:APPVEYOR_BUILD_NUMBER + } + elseif ( $Env:GITHUB_ACTIONS -eq 'true' ) { + $string = $string + '.' + $Env:GITHUB_RUN_NUMBER + } + + # Remove starting 'v' characters + $string = $string -replace '^v+','' # normalize version string + + return $string +} + +function Parse-Changelog($file) { + # Define the regular expression to match the version string from changelog + [regex]$regex = '^## \[(?[\w\-\.]+)\]\([^\n()]+\)\s+\([^\n()]+\)$'; + + # Find the first match of the version string which means the latest version + $version = Select-String -Path $file -Pattern $regex | Select-Object -First 1 | ForEach-Object { $_.Matches.Groups[1].Value } + + return $version +} + +function Create-RC($string, $path) { + $version = $string + '.0.0.0.0' # padding for version string + + if ( !(Test-Path "$path.sample") ) { + throw "Invalid path provided for resources file." + } + + $resource = Get-Content -Path "$path.sample" + $pattern = @( "Cmder-Major-Version", "Cmder-Minor-Version", "Cmder-Revision-Version", "Cmder-Build-Version" ) + $index = 0 + + # Replace all non-numeric characters to dots and split to array + $version = $version -replace '[^0-9]+','.' -split '\.' + + foreach ($fragment in $version) { + if ( !$fragment ) { break } + elseif ($index -le $pattern.length) { + $resource = $resource.Replace( "{" + $pattern[$index++] + "}", $fragment ) + } + } + + # Add the version string + $resource = $resource.Replace( "{Cmder-Version-Str}", '"' + $string + '"' ) + + # Write the results + Set-Content -Path $path -Value $resource +} + +function Register-Cmder() { + [CmdletBinding()] + Param + ( + # Text for the context menu item. + $MenuText = "Cmder Here" + + , # Defaults to the current Cmder directory when run from Cmder. + $PathToExe = (Join-Path $env:CMDER_ROOT "cmder.exe") + + , # Commands the context menu will execute. + $Command = "%V" + + , # Defaults to the icons folder in the Cmder package. + $icon = (Split-Path $PathToExe | Join-Path -ChildPath 'icons/cmder.ico') + ) + Begin + { + New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT > $null + } + Process + { + New-Item -Path "HKCR:\Directory\Shell\Cmder" -Force -Value $MenuText + New-ItemProperty -Path "HKCR:\Directory\Shell\Cmder" -Force -Name "Icon" -Value `"$icon`" + New-ItemProperty -Path "HKCR:\Directory\Shell\Cmder" -Force -Name "NoWorkingDirectory" + New-Item -Path "HKCR:\Directory\Shell\Cmder\Command" -Force -Value "`"$PathToExe`" `"$Command`" " + + New-Item -Path "HKCR:\Directory\Background\Shell\Cmder" -Force -Value $MenuText + New-ItemProperty -Path "HKCR:\Directory\Background\Shell\Cmder" -Force -Name "Icon" -Value `"$icon`" + New-ItemProperty -Path "HKCR:\Directory\Background\Shell\Cmder" -Force -Name "NoWorkingDirectory" + New-Item -Path "HKCR:\Directory\Background\Shell\Cmder\Command" -Force -Value "`"$PathToExe`" `"$Command`" " + } + End + { + Remove-PSDrive -Name HKCR + } +} + +function Unregister-Cmder { + Begin + { + New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT > $null + } + Process + { + Remove-Item -Path "HKCR:\Directory\Shell\Cmder" -Recurse + Remove-Item -Path "HKCR:\Directory\Background\Shell\Cmder" -Recurse + } + End + { + Remove-PSDrive -Name HKCR + } +} + +function Download-File { + param ( + $Url, + $File + ) + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + + $useBitTransfer = $null -ne (Get-Module -Name BitsTransfer -ListAvailable) -and ($PSVersionTable.PSVersion.Major -le 5) + + $File = $File -replace "/", "\" + + try { + if ($useBitTransfer) { + Start-BitsTransfer -Source $Url -Destination $File -DisplayName "Downloading '$Url' to $File" + return + } + } + catch { + Write-Error "Failed to download file using BITS, reason: $_`nUsing fallback method instead...`n" -ErrorAction:Continue + } + + Write-Verbose "Downloading from $Url to $File`n" + + $wc = New-Object System.Net.WebClient + if ($env:https_proxy) { + $wc.proxy = (New-Object System.Net.WebProxy($env:https_proxy)) + } + $wc.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials; + $wc.DownloadFile($Url, $File) +} From 5536ea20883af7bb9b7aa85c1275eb54072c9419 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sun, 9 Nov 2025 04:05:08 +0330 Subject: [PATCH 81/84] ignore git commit --- .git-blame-ignore-revs | 1 + 1 file changed, 1 insertion(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 65220a6..0091f76 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -12,3 +12,4 @@ abbab3f8b477e917d0a175d0de23cce121096631 126347025f9cade241beff182738b2527da7535e 4740b836f300658b27e6ad4d79efac63c9c24c24 be44bac95670b1cbbc91bd657882d985989846f9 +f67e5704eda60526d495be758572181f01a6cac8 From 9c3bbe9b24611ee0b8d6df0fb3f30a5ca20bcbc8 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sun, 9 Nov 2025 04:06:50 +0330 Subject: [PATCH 82/84] Redirect Verbose and Debug stream --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0f0ea75..d22ab47 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -48,7 +48,7 @@ jobs: cmd /c vendor\init.bat /v /d /t - name: Testing PowerShell run: | - PowerShell.exe -ExecutionPolicy Bypass -NoLogo -NoProfile -Command "$CMDER_DEBUG = 1; 'vendor\profile.ps1'" + PowerShell.exe -ExecutionPolicy Bypass -NoLogo -NoProfile -Command "$CMDER_DEBUG = 1; 'vendor\profile.ps1' 4>&1 5>&1" - name: Testing Bash run: | bash vendor/cmder.sh From dc3b142b323a8099ec934803aaadbb753bf16f6a Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sun, 9 Nov 2025 04:29:32 +0330 Subject: [PATCH 83/84] Make PowerShell profile.ps1's debug and verbose working correctly --- .github/workflows/tests.yml | 1 + vendor/profile.ps1 | 52 +++++++++++++++++++++---------------- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d22ab47..f37a1c9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -49,6 +49,7 @@ jobs: - name: Testing PowerShell run: | PowerShell.exe -ExecutionPolicy Bypass -NoLogo -NoProfile -Command "$CMDER_DEBUG = 1; 'vendor\profile.ps1' 4>&1 5>&1" + PowerShell.exe -ExecutionPolicy Bypass -NoLogo -NoProfile -Command "$env:CMDER_DEBUG='1'; . 'vendor\profile.ps1'" 4>&1 5>&1 - name: Testing Bash run: | bash vendor/cmder.sh diff --git a/vendor/profile.ps1 b/vendor/profile.ps1 index 8cc1a45..d450e27 100644 --- a/vendor/profile.ps1 +++ b/vendor/profile.ps1 @@ -5,22 +5,13 @@ # !!! THIS FILE IS OVERWRITTEN WHEN CMDER IS UPDATED # !!! Use "%CMDER_ROOT%\config\user_profile.ps1" to add your own startup commands -if ($env:CMDER_DEBUG -and ($env:CMDER_DEBUG -match '^(1|true)$')) { - $DebugPreference = 'Continue' - $VerbosePreference = 'Continue' -} - $CMDER_INIT_START = Get-Date -# Compatibility with PS major versions <= 2 +# Determine the script root if not already set if (!$PSScriptRoot) { $PSScriptRoot = Split-Path $Script:MyInvocation.MyCommand.Path } -if ($ENV:CMDER_USER_CONFIG) { - Write-Verbose "CMDER IS ALSO USING INDIVIDUAL USER CONFIG FROM '$ENV:CMDER_USER_CONFIG'!" -} - # We do this for Powershell as Admin Sessions because CMDER_ROOT is not being set. if (!$ENV:CMDER_ROOT) { if ($ENV:ConEmuDir) { @@ -36,6 +27,12 @@ $ENV:CMDER_ROOT = ($ENV:CMDER_ROOT).TrimEnd("\") # Recent PowerShell versions include PowerShellGet out of the box $moduleInstallerAvailable = [bool](Get-Command -Name 'Install-Module' -ErrorAction SilentlyContinue) +# Enable Debug and Verbose output if CMDER_DEBUG environment variable is set to '1' or 'true' +if ($env:CMDER_DEBUG -and ($env:CMDER_DEBUG -match '^(1|true)$')) { + $DebugPreference = 'Continue' + $VerbosePreference = 'Continue' +} + # Add Cmder modules directory to the autoload path. $CmderModulePath = Join-path $PSScriptRoot "psmodules/" @@ -48,17 +45,26 @@ if (-not $moduleInstallerAvailable -and -not $env:PSModulePath.Contains($CmderMo $env:PSModulePath = $env:PSModulePath.Insert(0, "$CmderModulePath;") } +if ($ENV:CMDER_USER_CONFIG) { + Write-Verbose "CMDER IS ALSO USING INDIVIDUAL USER CONFIG FROM '$ENV:CMDER_USER_CONFIG'!" +} + # Read vendored Git Version -$gitVersionVendor = Get-GitVersion -GitPath "$ENV:CMDER_ROOT\vendor\git-for-windows\cmd" -Write-Debug "GIT VENDOR: ${gitVersionVendor}" +$gitVendorPath = Join-Path $ENV:CMDER_ROOT 'vendor\git-for-windows\cmd' +$gitVersionVendor = Get-GitVersion -GitPath $gitVendorPath +if (-not [string]::IsNullOrEmpty($gitVersionVendor)) { + Write-Debug "GIT VENDOR: ${gitVersionVendor}" +} else { + Write-Debug "GIT VENDOR is not present at '$gitVendorPath'" +} # Get user installed Git version(s) if found, and compare them with vendored version. foreach ($git in (Get-Command -ErrorAction SilentlyContinue 'git')) { - Write-Debug "GIT PATH: {$git.Path}" + Write-Debug "GIT USER PATH: $($git.Path)" $gitDir = Split-Path -Path $git.Path $gitDir = Get-GitShimPath -GitPath $gitDir $gitVersionUser = Get-GitVersion -GitPath $gitDir - Write-Debug "GIT USER: ${gitVersionUser}" + Write-Debug "GIT USER VERSION: ${gitVersionUser}" $useGitVersion = Compare-GitVersion -UserVersion $gitVersionUser -VendorVersion $gitVersionVendor Write-Debug "Using Git Version: ${useGitVersion}" @@ -102,7 +108,7 @@ if (Get-Command -Name "vim" -ErrorAction SilentlyContinue) { if (Get-Module PSReadline -ErrorAction "SilentlyContinue") { # Display an extra prompt line between the prompt and the command input Set-PSReadlineOption -ExtraPromptLineCount 1 - + # Invoked when Enter is pressed to submit a command if ($env:WT_SESSION) { Set-PSReadLineKeyHandler -Key Enter -ScriptBlock { @@ -110,10 +116,10 @@ if (Get-Module PSReadline -ErrorAction "SilentlyContinue") { $line = $null $cursor = $null [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor) - + # Accept the line first [Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine() - + # Emit OSC 133;C to mark start of command output # This is written directly to the console after the command is accepted [Console]::Write("$([char]0x1B)]133;C$([char]7)") @@ -224,28 +230,28 @@ if ( $(Get-Command prompt).Definition -match 'PS \$\(\$executionContext.SessionS [ScriptBlock]$Prompt = { $lastSUCCESS = $? $realLastExitCode = $LastExitCode - + # Terminal-specific escape sequences for Windows Terminal and ConEmu if ($env:WT_SESSION -or $env:ConEmuPID) { # Emit OSC 133;D to mark the end of command execution with exit code if ($env:WT_SESSION) { Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;D;$realLastExitCode$([char]7)" } - + # Emit OSC 9;9 to enable directory tracking # Enables "Duplicate Tab" and "Split Pane" to preserve the working directory $loc = $executionContext.SessionState.Path.CurrentLocation if ($loc.Provider.Name -eq "FileSystem") { Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]9;9;`"$($loc.ProviderPath)`"$([char]0x1B)\" } - + # Emit OSC 133;A to mark the start of the prompt # Enables features like command navigation, selection, and visual separators if ($env:WT_SESSION) { Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;A$([char]7)" } } - + $host.UI.RawUI.WindowTitle = Microsoft.PowerShell.Management\Split-Path $pwd.ProviderPath -Leaf Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x200B)`r$([char]0x1B)[K" if ($lastSUCCESS -or ($LastExitCode -ne 0)) { @@ -254,12 +260,12 @@ if ( $(Get-Command prompt).Definition -match 'PS \$\(\$executionContext.SessionS PrePrompt | Microsoft.PowerShell.Utility\Write-Host -NoNewline CmderPrompt PostPrompt | Microsoft.PowerShell.Utility\Write-Host -NoNewline - + # Emit OSC 133;B to mark the start of command input (after prompt, before user types) if ($env:WT_SESSION) { Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;B$([char]7)" } - + $global:LastExitCode = $realLastExitCode return " " } From 7f0cfac4989d5c9aabd576bb8f1904b26ab156b6 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Sun, 9 Nov 2025 04:36:41 +0330 Subject: [PATCH 84/84] update profile.ps1's debug output --- .github/workflows/tests.yml | 3 +-- vendor/profile.ps1 | 9 ++++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f37a1c9..0334e86 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -48,8 +48,7 @@ jobs: cmd /c vendor\init.bat /v /d /t - name: Testing PowerShell run: | - PowerShell.exe -ExecutionPolicy Bypass -NoLogo -NoProfile -Command "$CMDER_DEBUG = 1; 'vendor\profile.ps1' 4>&1 5>&1" - PowerShell.exe -ExecutionPolicy Bypass -NoLogo -NoProfile -Command "$env:CMDER_DEBUG='1'; . 'vendor\profile.ps1'" 4>&1 5>&1 + PowerShell.exe -ExecutionPolicy Bypass -NoLogo -NoProfile -Command "$env:CMDER_DEBUG='1'; . 'vendor\profile.ps1'" - name: Testing Bash run: | bash vendor/cmder.sh diff --git a/vendor/profile.ps1 b/vendor/profile.ps1 index d450e27..bc33a9b 100644 --- a/vendor/profile.ps1 +++ b/vendor/profile.ps1 @@ -45,7 +45,7 @@ if (-not $moduleInstallerAvailable -and -not $env:PSModulePath.Contains($CmderMo $env:PSModulePath = $env:PSModulePath.Insert(0, "$CmderModulePath;") } -if ($ENV:CMDER_USER_CONFIG) { +if ($env:CMDER_USER_CONFIG) { Write-Verbose "CMDER IS ALSO USING INDIVIDUAL USER CONFIG FROM '$ENV:CMDER_USER_CONFIG'!" } @@ -71,11 +71,14 @@ foreach ($git in (Get-Command -ErrorAction SilentlyContinue 'git')) { # Use user installed Git if ($null -eq $gitPathUser) { + Write-Debug "Detected Git from mingw bin directory" + Write-Debug "Git Dir: ${gitDir}" if ($gitDir -match '\\mingw32\\bin' -or $gitDir -match '\\mingw64\\bin') { - $gitPathUser = ($gitDir.subString(0,$gitDir.Length - 12)) + $gitPathUser = $gitDir.subString(0, $gitDir.Length - 12) } else { - $gitPathUser = ($gitDir.subString(0,$gitDir.Length - 4)) + $gitPathUser = $gitDir.subString(0, $gitDir.Length - 4) } + Write-Debug "Git Path User: ${gitDir}" } if ($useGitVersion -eq $gitVersionUser) {