Compare commits

..

2 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
9d17a2f4cb Fix PowerShell script inconsistencies and documentation errors
Co-authored-by: DRSDavidSoft <4673812+DRSDavidSoft@users.noreply.github.com>
2025-08-12 03:02:05 +00:00
Copilot
5c072d47e4 Initial plan 2025-08-12 02:51:18 +00:00
18 changed files with 261 additions and 458 deletions

View File

@@ -53,26 +53,26 @@ jobs:
run: .\pack.ps1 -verbose run: .\pack.ps1 -verbose
- name: Upload artifact (cmder.zip) - name: Upload artifact (cmder.zip)
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
path: build/cmder.zip path: build/cmder.zip
name: cmder.zip name: cmder.zip
if-no-files-found: error if-no-files-found: error
- name: Upload artifact (cmder.7z) - name: Upload artifact (cmder.7z)
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
path: build/cmder.7z path: build/cmder.7z
name: cmder.7z name: cmder.7z
- name: Upload artifact (cmder_mini.zip) - name: Upload artifact (cmder_mini.zip)
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
path: build/cmder_mini.zip path: build/cmder_mini.zip
name: cmder_mini.zip name: cmder_mini.zip
- name: Upload artifact (hashes.txt) - name: Upload artifact (hashes.txt)
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
path: build/hashes.txt path: build/hashes.txt
name: hashes.txt name: hashes.txt

View File

@@ -49,7 +49,7 @@ jobs:
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v4 uses: github/codeql-action/init@v3
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file. # 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 run: .\build.ps1 -Compile -verbose
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4 uses: github/codeql-action/analyze@v3
with: with:
category: "/language:${{matrix.language}}" category: "/language:${{matrix.language}}"

View File

@@ -352,10 +352,6 @@ 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. 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.
⚠ *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). For instructions on how to integrate Cmder with your IDE, please read our [Wiki section](https://github.com/cmderdev/cmder/wiki#cmder-integration).
## Upgrading ## Upgrading

View File

@@ -21,7 +21,7 @@
Skip all downloads and only build launcher. Skip all downloads and only build launcher.
.EXAMPLE .EXAMPLE
.\build -verbose .\build.ps1 -verbose
Execute the build and see what's going on. Execute the build and see what's going on.
.EXAMPLE .EXAMPLE
@@ -33,7 +33,7 @@
Samuel Vasko, Jack Bennett Samuel Vasko, Jack Bennett
Part of the Cmder project. Part of the Cmder project.
.LINK .LINK
http://cmder.app/ - Project Home https://github.com/cmderdev/cmder - Project Home
#> #>
[CmdletBinding(SupportsShouldProcess = $true)] [CmdletBinding(SupportsShouldProcess = $true)]
Param( Param(

View File

@@ -35,7 +35,7 @@ Param(
[string]$saveTo = "$PSScriptRoot\..\build" [string]$saveTo = "$PSScriptRoot\..\build"
) )
$cmderRoot = Resolve-Path $cmderRoot $cmder_root = Resolve-Path $cmderRoot
. "$PSScriptRoot\utils.ps1" . "$PSScriptRoot\utils.ps1"
$ErrorActionPreference = "Stop" $ErrorActionPreference = "Stop"
@@ -47,10 +47,10 @@ $targets = @{
"cmder_mini.zip" = "-xr!`"vendor\git-for-windows`""; "cmder_mini.zip" = "-xr!`"vendor\git-for-windows`"";
} }
Push-Location -Path $cmderRoot Push-Location -Path $cmder_root
Delete-Existing "$cmderRoot\Version*" Delete-Existing "$cmder_root\Version*"
Delete-Existing "$cmderRoot\build\*" Delete-Existing "$cmder_root\build\*"
if (-not (Test-Path -PathType container $saveTo)) { if (-not (Test-Path -PathType container $saveTo)) {
(New-Item -ItemType Directory -Path $saveTo) | Out-Null (New-Item -ItemType Directory -Path $saveTo) | Out-Null
@@ -59,16 +59,16 @@ if (-not (Test-Path -PathType container $saveTo)) {
$saveTo = Resolve-Path $saveTo $saveTo = Resolve-Path $saveTo
$version = Get-VersionStr $version = Get-VersionStr
(New-Item -ItemType file "$cmderRoot\Version $version") | Out-Null (New-Item -ItemType file "$cmder_root\Version $version") | Out-Null
if ($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent) { if ($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent) {
Write-Verbose "Packing Cmder $version in $saveTo..." Write-Verbose "Packing Cmder $version in $saveTo..."
$excluded = (Get-Content -Path "$cmderRoot\packignore") -Split [System.Environment]::NewLine | Where-Object { $_ } $excluded = (Get-Content -Path "$cmder_root\packignore") -Split [System.Environment]::NewLine | Where-Object { $_ }
Get-ChildItem $cmderRoot -Force -Exclude $excluded Get-ChildItem $cmder_root -Force -Exclude $excluded
} }
foreach ($t in $targets.GetEnumerator()) { foreach ($t in $targets.GetEnumerator()) {
Create-Archive "$cmderRoot" "$saveTo\$($t.Name)" $t.Value Create-Archive "$cmder_root" "$saveTo\$($t.Name)" $t.Value
$hash = (Digest-Hash "$saveTo\$($t.Name)") $hash = (Digest-Hash "$saveTo\$($t.Name)")
Add-Content -path "$saveTo\hashes.txt" -value ($t.Name + ' ' + $hash) Add-Content -path "$saveTo\hashes.txt" -value ($t.Name + ' ' + $hash)
} }

View File

@@ -5,17 +5,17 @@
This script updates dependencies to the latest version in vendor/sources.json file. This script updates dependencies to the latest version in vendor/sources.json file.
You will need to make this script executable by setting your Powershell Execution Policy to Remote signed 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 Then unblock the script for execution with UnblockFile .\update.ps1
.EXAMPLE .EXAMPLE
.\build.ps1 .\update.ps1
Updates the dependency sources in the default location, the vendor/sources.json file. Updates the dependency sources in the default location, the vendor/sources.json file.
.EXAMPLE .EXAMPLE
.\build -verbose .\update.ps1 -verbose
Updates the dependency sources and see what's going on. Updates the dependency sources and see what's going on.
.EXAMPLE .EXAMPLE
.\build.ps1 -SourcesPath '~/custom/vendors.json' .\update.ps1 -SourcesPath '~/custom/vendors.json'
Specify the path to update dependency sources file at. Specify the path to update dependency sources file at.
.NOTES .NOTES
@@ -23,7 +23,7 @@
David Refoua <David@Refoua.me> David Refoua <David@Refoua.me>
Part of the Cmder project. Part of the Cmder project.
.LINK .LINK
http://cmder.app/ - Project Home https://github.com/cmderdev/cmder - Project Home
#> #>
[CmdletBinding(SupportsShouldProcess = $true)] [CmdletBinding(SupportsShouldProcess = $true)]
Param( Param(
@@ -32,11 +32,7 @@ Param(
# -whatif switch to not actually make changes # -whatif switch to not actually make changes
# Path to the vendor configuration source file # 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. # Get the root directory of the cmder project.
@@ -83,39 +79,11 @@ function Match-Filenames {
return $position 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. # Uses the GitHub api in order to fetch the current download links for the latest releases of the repo.
function Fetch-DownloadUrl { function Fetch-DownloadUrl {
param ( param (
[Parameter(Mandatory = $true)] [Parameter(Mandatory = $true)]
$urlStr, $urlStr
[Parameter(Mandatory = $false)]
[bool]$includePrerelease = $false
) )
$url = [uri] $urlStr $url = [uri] $urlStr
@@ -159,13 +127,6 @@ function Fetch-DownloadUrl {
} }
:loop foreach ($i in $info) { :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 -and (Test-IsPrerelease $i)) {
Write-Verbose "Skipping pre-release version: $($i.tag_name)"
continue
}
if (-not ($i.assets -is [array])) { if (-not ($i.assets -is [array])) {
continue continue
} }
@@ -203,29 +164,15 @@ function Fetch-DownloadUrl {
# Special case for archive downloads of repository # Special case for archive downloads of repository
if (($null -eq $downloadLinks) -or (-not $downloadLinks)) { if (($null -eq $downloadLinks) -or (-not $downloadLinks)) {
if ((($p | ForEach-Object { $_.Trim('/') }) -contains "archive")) { if ((($p | ForEach-Object { $_.Trim('/') }) -contains "archive") -and $info[0].tag_name) {
# 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 -and (Test-IsPrerelease $release)) {
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++) { for ($i = 0; $i -lt $p.Length; $i++) {
if ($p[$i].Trim('/') -eq "archive") { if ($p[$i].Trim('/') -eq "archive") {
$p[$i + 1] = $selectedRelease.tag_name + ".zip" $p[$i + 1] = $info[0].tag_name + ".zip"
$downloadLinks = $url.Scheme + "://" + $url.Host + ($p -join '') $downloadLinks = $url.Scheme + "://" + $url.Host + ($p -join '')
return $downloadLinks return $downloadLinks
} }
} }
} }
}
return '' return ''
} }
@@ -268,7 +215,7 @@ foreach ($s in $sources) {
Write-Verbose "Old Link: $($s.url)" Write-Verbose "Old Link: $($s.url)"
$downloadUrl = Fetch-DownloadUrl $s.url -includePrerelease $IncludePrerelease $downloadUrl = Fetch-DownloadUrl $s.url
if (($null -eq $downloadUrl) -or ($downloadUrl -eq '')) { if (($null -eq $downloadUrl) -or ($downloadUrl -eq '')) {
Write-Verbose "No new links were found" Write-Verbose "No new links were found"

View File

@@ -1,7 +1,6 @@
function Ensure-Exists($path) { function Ensure-Exists($path) {
if (-not (Test-Path $path)) { if (-not (Test-Path $path)) {
Write-Error "Missing required $path! Ensure it is installed" throw "Missing required $path! Ensure it is installed"
exit 1
} }
return $true > $null return $true > $null
} }
@@ -16,8 +15,7 @@ function Ensure-Executable($command) {
Set-Alias -Name "7z" -Value "$env:programw6432\7-zip\7z.exe" -Scope script Set-Alias -Name "7z" -Value "$env:programw6432\7-zip\7z.exe" -Scope script
} }
else { else {
Write-Error "Missing $command! Ensure it is installed and on in the PATH" throw "Missing $command! Ensure it is installed and on in the PATH"
exit 1
} }
} }
} }

154
vendor/clink.lua vendored
View File

@@ -7,7 +7,7 @@
-- luacheck: globals uah_color cwd_color lamb_color clean_color dirty_color conflict_color unknown_color -- 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_homeSymbol prompt_lambSymbol prompt_type prompt_useHomeSymbol prompt_useUserAtHost
-- luacheck: globals prompt_singleLine prompt_includeVersionControl -- luacheck: globals prompt_singleLine prompt_includeVersionControl
-- luacheck: globals prompt_overrideGitStatusOptIn -- luacheck: globals prompt_overrideGitStatusOptIn prompt_overrideSvnStatusOptIn
-- luacheck: globals clink io.popenyield os.isdir settings.get -- luacheck: globals clink io.popenyield os.isdir settings.get
-- At first, load the original clink.lua file -- At first, load the original clink.lua file
@@ -350,8 +350,13 @@ end
-- @return {false|mercurial branch information} -- @return {false|mercurial branch information}
--- ---
local function get_hg_branch() local function get_hg_branch()
-- Return the branch information. -- Return the branch information. The default is to get just the
local file = io.popen("hg branch 2>nul") -- 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)
if not file then if not file then
return false return false
end end
@@ -419,33 +424,12 @@ local function get_git_status()
return { status = is_status, conflict = conflict_found } return { status = is_status, conflict = conflict_found }
end 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 -- Get the status of working dir
-- @return {bool} -- @return {bool}
--- ---
local function get_svn_status() local function get_svn_status()
local file = io_popenyield("svn status -q 2>nul") local file = io_popenyield("svn status -q")
if not file then if not file then
return { error = true } return { error = true }
end end
@@ -536,6 +520,14 @@ local function git_prompt_filter()
return false return false
end 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 git_dir = get_git_dir()
local color local color
if git_dir then if git_dir then
@@ -555,19 +547,18 @@ local function git_prompt_filter()
local gitConflict = gitInfo.conflict local gitConflict = gitInfo.conflict
if gitStatus == nil then if gitStatus == nil then
color = get_unknown_color() color = colors.nostatus
elseif gitStatus then elseif gitStatus then
color = get_clean_color() color = colors.clean
else else
color = get_dirty_color() color = colors.dirty
end end
if gitConflict then if gitConflict then
color = get_conflict_color() color = colors.conflict
end end
local result = " "..color.."("..branch..")" clink.prompt.value = gsub_plain(clink.prompt.value, "{git}", " "..color.."("..branch..")")
clink.prompt.value = gsub_plain(clink.prompt.value, "{git}", result)
return false return false
end end
end end
@@ -577,18 +568,6 @@ local function git_prompt_filter()
return false return false
end 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() local function hg_prompt_filter()
-- Don't do any hg processing if the prompt doesn't want to show hg info. -- Don't do any hg processing if the prompt doesn't want to show hg info.
@@ -598,30 +577,33 @@ local function hg_prompt_filter()
local hg_dir = get_hg_dir() local hg_dir = get_hg_dir()
if hg_dir then if hg_dir then
local branch = get_hg_branch() -- Colors for mercurial status
if branch and local colors = {
clean = get_clean_color(),
dirty = get_dirty_color(),
nostatus = get_unknown_color()
}
local output = get_hg_branch()
-- 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)
if branch ~= nil and
string.sub(branch,1,7) ~= "abort: " and -- not an HG working copy string.sub(branch,1,7) ~= "abort: " and -- not an HG working copy
(not string.find(branch, "is not recognized")) then -- 'hg' not in path (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 local color = colors.clean
if cached_info.hg_dir ~= hg_dir or cached_info.hg_branch ~= branch then
cached_info.hg_info = nil local pipe = io.popen("hg status -amrd 2>&1")
cached_info.hg_dir = hg_dir if pipe then
cached_info.hg_branch = branch output = pipe:read('*all')
pipe:close()
if output ~= nil and output ~= "" then color = colors.dirty end
end end
local hgInfo = get_hg_info_table() local result = color .. "(" .. branch .. ")"
clink.prompt.value = gsub_plain(clink.prompt.value, "{hg}", " "..result)
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 return false
end end
end end
@@ -630,18 +612,6 @@ local function hg_prompt_filter()
clink.prompt.value = gsub_plain(clink.prompt.value, "{hg}", "") clink.prompt.value = gsub_plain(clink.prompt.value, "{hg}", "")
end 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() local function svn_prompt_filter()
-- Don't do any svn processing if the prompt doesn't want to show svn info. -- Don't do any svn processing if the prompt doesn't want to show svn info.
@@ -649,6 +619,13 @@ local function svn_prompt_filter()
return false return false
end 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() local svn_dir = get_svn_dir()
if svn_dir then if svn_dir then
-- if we're inside of svn repo then try to detect current branch -- if we're inside of svn repo then try to detect current branch
@@ -660,16 +637,29 @@ local function svn_prompt_filter()
cached_info.svn_dir = svn_dir cached_info.svn_dir = svn_dir
cached_info.svn_branch = branch cached_info.svn_branch = branch
end end
-- Get the svn status using coroutine if available and option is enabled. Otherwise use a blocking call
local svnInfo = get_svn_info_table() 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 color local color
if not svnInfo or svnInfo.error then if not svnStatus or svnStatus.error then
color = get_unknown_color() color = colors.nostatus
elseif svnInfo.clean then elseif svnStatus.clean then
color = get_clean_color() color = colors.clean
else else
color = get_dirty_color() color = colors.dirty
end end
clink.prompt.value = gsub_plain(clink.prompt.value, "{svn}", " "..color.."("..branch..")") clink.prompt.value = gsub_plain(clink.prompt.value, "{svn}", " "..color.."("..branch..")")

View File

@@ -38,6 +38,11 @@ prompt_includeVersionControl = true
-- NOTE: This only takes effect if using Clink v1.2.10 or higher. -- NOTE: This only takes effect if using Clink v1.2.10 or higher.
prompt_overrideGitStatusOptIn = false 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 -- Prompt Attributes
-- --
-- Colors: https://github.com/cmderdev/cmder/wiki/Customization#list-of-colors -- Colors: https://github.com/cmderdev/cmder/wiki/Customization#list-of-colors

2
vendor/init.bat vendored
View File

@@ -355,7 +355,7 @@ setlocal enabledelayedexpansion
if defined git_locale ( if defined git_locale (
REM %print_debug% init.bat "Env Var - git_locale=!git_locale!" REM %print_debug% init.bat "Env Var - git_locale=!git_locale!"
if not defined LANG ( 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" set "LANG=%%F"
) )
) )

View File

@@ -4,7 +4,7 @@ set lib_base=call "%~dp0lib_base.cmd"
if "%~1" == "/h" ( if "%~1" == "/h" (
%lib_base% help "%~0" %lib_base% help "%~0"
) else if "%~1" neq "" ( ) else if "%1" neq "" (
call :%* call :%*
) )

View File

@@ -14,7 +14,7 @@ if %fast_init% gtr %verbose_output% if %fast_init% gtr %debug_output% exit /b
if "%~1" == "/h" ( if "%~1" == "/h" (
%lib_base% help "%~0" %lib_base% help "%~0"
) else if "%~1" neq "" ( ) else if "%1" neq "" (
call :%* call :%*
) )

View File

@@ -1,12 +1,12 @@
@echo off @echo off
call "%~dp0lib_base.cmd" call "%~dp0lib_base.cmd"
call "%~dp0lib_console.cmd" call "%%~dp0lib_console.cmd"
set lib_git=call "%~dp0lib_git.cmd" set lib_git=call "%~dp0lib_git.cmd"
if "%~1" == "/h" ( if "%~1" == "/h" (
%lib_base% help "%~0" %lib_base% help "%~0"
) else if "%~1" neq "" ( ) else if "%1" neq "" (
call :%* call :%*
) )

View File

@@ -1,12 +1,12 @@
@echo off @echo off
call "%~dp0lib_base.cmd" call "%~dp0lib_base.cmd"
call "%~dp0lib_console.cmd" call "%%~dp0lib_console"
set lib_path=call "%~dp0lib_path.cmd" set lib_path=call "%~dp0lib_path.cmd"
if "%~1" == "/h" ( if "%~1" == "/h" (
%lib_base% help "%~0" %lib_base% help "%~0"
) else if "%~1" neq "" ( ) else if "%1" neq "" (
call :%* call :%*
) )
@@ -48,7 +48,7 @@ exit /b
set "add_path=%~1" set "add_path=%~1"
) else ( ) else (
%print_error% "You must specify a directory to add to the path!" %print_error% "You must specify a directory to add to the path!"
exit /b 1 exit 1
) )
if "%~2" neq "" if /i "%~2" == "append" ( if "%~2" neq "" if /i "%~2" == "append" (
@@ -72,7 +72,7 @@ exit /b
set "PATH=%add_to_path%;%PATH%" set "PATH=%add_to_path%;%PATH%"
) )
goto :end_enhance_path goto :end_enhance_path
) else if "%add_to_path%" equ "" ( ) else if "add_to_path" equ "" (
goto :end_enhance_path goto :end_enhance_path
) )
@@ -84,20 +84,20 @@ exit /b
setlocal enabledelayedexpansion setlocal enabledelayedexpansion
if "!found!" == "0" ( if "!found!" == "0" (
echo "!PATH!"|!WINDIR!\System32\findstr >nul /I /R /C:";!find_query!;" echo "!path!"|!WINDIR!\System32\findstr >nul /I /R /C:";!find_query!;"
call :set_found call :set_found
) )
%print_debug% :enhance_path "Env Var INSIDE PATH !find_query! - found=!found!" %print_debug% :enhance_path "Env Var INSIDE PATH !find_query! - found=!found!"
if /i "!position!" == "append" ( if /i "!position!" == "append" (
if "!found!" == "0" ( if "!found!" == "0" (
echo "!PATH!"|!WINDIR!\System32\findstr >nul /I /R /C:";!find_query!\"$" echo "!path!"|!WINDIR!\System32\findstr >nul /I /R /C:";!find_query!\"$"
call :set_found call :set_found
) )
%print_debug% :enhance_path "Env Var END PATH !find_query! - found=!found!" %print_debug% :enhance_path "Env Var END PATH !find_query! - found=!found!"
) else ( ) else (
if "!found!" == "0" ( if "!found!" == "0" (
echo "!PATH!"|!WINDIR!\System32\findstr >nul /I /R /C:"^\"!find_query!;" echo "!path!"|!WINDIR!\System32\findstr >nul /I /R /C:"^\"!find_query!;"
call :set_found call :set_found
) )
%print_debug% :enhance_path "Env Var BEGIN PATH !find_query! - found=!found!" %print_debug% :enhance_path "Env Var BEGIN PATH !find_query! - found=!found!"
@@ -119,8 +119,7 @@ exit /b
:end_enhance_path :end_enhance_path
set "PATH=%PATH:;;=;%" set "PATH=%PATH:;;=;%"
REM echo %path%|wc -c REM echo %path%|"C:\Users\dgames\cmder - dev\vendor\git-for-windows\usr\bin\wc" -c
if "%fast_init%" == "1" exit /b if "%fast_init%" == "1" exit /b
if not "%OLD_PATH:~0,3000%" == "%OLD_PATH:~0,3001%" goto :toolong if not "%OLD_PATH:~0,3000%" == "%OLD_PATH:~0,3001%" goto :toolong
@@ -128,22 +127,15 @@ exit /b
exit /b exit /b
:toolong :toolong
set "_rand=%RANDOM%" echo "%OLD_PATH%">"%temp%\cmder_lib_pathA"
if exist "%temp%\%_rand%_cmder_lib_pathA" del "%temp%\%_rand%_cmder_lib_pathA" 2>nul 1>nul echo "%PATH%">"%temp%\cmder_lib_pathB"
if exist "%temp%\%_rand%_cmder_lib_pathB" del "%temp%\%_rand%_cmder_lib_pathB" 2>nul 1>nul fc /b "%temp%\cmder_lib_pathA" "%temp%\cmder_lib_pathB" 2>nul 1>nul
if exist "%temp%\%_rand%_cmder_lib_pathA" goto :toolong if errorlevel 1 ( del "%temp%\cmder_lib_pathA" & del "%temp%\cmder_lib_pathB" & goto :changed )
if exist "%temp%\%_rand%_cmder_lib_pathB" goto :toolong del "%temp%\cmder_lib_pathA" & del "%temp%\cmder_lib_pathB"
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%\%_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="
exit /b exit /b
:changed :changed
%print_debug% :enhance_path "END Env Var - PATH=%PATH%" %print_debug% :enhance_path "END Env Var - PATH=%path%"
%print_debug% :enhance_path "Env Var %find_query% - found=%found%" %print_debug% :enhance_path "Env Var %find_query% - found=%found%"
exit /b exit /b
@@ -187,7 +179,7 @@ exit /b
set "add_path=%~1" set "add_path=%~1"
) else ( ) else (
%print_error% "You must specify a directory to add to the path!" %print_error% "You must specify a directory to add to the path!"
exit /b 1 exit 1
) )
set "depth=%~2" set "depth=%~2"

View File

@@ -1,12 +1,12 @@
@echo off @echo off
call "%~dp0lib_base.cmd" call "%~dp0lib_base.cmd"
call "%~dp0lib_console.cmd" call "%%~dp0lib_console"
set lib_profile=call "%~dp0lib_profile.cmd" set lib_profile=call "%~dp0lib_profile.cmd"
if "%~1" == "/h" ( if "%~1" == "/h" (
%lib_base% help "%~0" %lib_base% help "%~0"
) else if "%~1" neq "" ( ) else if "%1" neq "" (
call :%* call :%*
) )

72
vendor/profile.ps1 vendored
View File

@@ -28,34 +28,31 @@ if (!$ENV:CMDER_ROOT) {
# Remove trailing '\' # Remove trailing '\'
$ENV:CMDER_ROOT = ($ENV:CMDER_ROOT).TrimEnd("\") $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) $moduleInstallerAvailable = [bool](Get-Command -Name 'Install-Module' -ErrorAction SilentlyContinue)
# Add Cmder modules directory to the autoload path. # Add Cmder modules directory to the autoload path.
$CmderModulePath = Join-path $PSScriptRoot "psmodules/" $CmderModulePath = Join-path $PSScriptRoot "psmodules/"
# Import Cmder functions
$CmderFunctions = Join-Path $CmderModulePath "Cmder.ps1" $CmderFunctions = Join-Path $CmderModulePath "Cmder.ps1"
. $CmderFunctions . $CmderFunctions
# Configure PSModulePath to include Cmder modules if not already present if(-not $moduleInstallerAvailable -and -not $env:PSModulePath.Contains($CmderModulePath) ) {
if (-not $moduleInstallerAvailable -and -not $env:PSModulePath.Contains($CmderModulePath) ) {
$env:PSModulePath = $env:PSModulePath.Insert(0, "$CmderModulePath;") $env:PSModulePath = $env:PSModulePath.Insert(0, "$CmderModulePath;")
} }
# Read vendored Git Version $gitVersionVendor = (readVersion -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}" Write-Debug "GIT VENDOR: ${gitVersionVendor}"
# Get user installed Git version(s) if found, and compare them with vendored version. # Get user installed Git Version[s] and Compare with vendored if found.
foreach ($git in (Get-Command -ErrorAction SilentlyContinue 'git')) { foreach ($git in (Get-Command -ErrorAction SilentlyContinue 'git')) {
Write-Debug "GIT PATH: {$git.Path}" Write-Debug "GIT PATH: {$git.Path}"
$gitDir = Split-Path -Path $git.Path $gitDir = Split-Path -Path $git.Path
$gitDir = Get-GitShimPath -GitPath $gitDir $gitDir = isGitShim -gitPath $gitDir
$gitVersionUser = Get-GitVersion -GitPath $gitDir $gitVersionUser = (readVersion -gitPath $gitDir)
Write-Debug "GIT USER: ${gitVersionUser}" Write-Debug "GIT USER: ${gitVersionUser}"
$useGitVersion = Compare-GitVersion -UserVersion $gitVersionUser -VendorVersion $gitVersionVendor $useGitVersion = compare_git_versions -userVersion $gitVersionUser -vendorVersion $gitVersionVendor
Write-Debug "Using Git Version: ${useGitVersion}" Write-Debug "Using Git Version: ${useGitVersion}"
# Use user installed Git # Use user installed Git
@@ -75,7 +72,7 @@ foreach ($git in (Get-Command -ErrorAction SilentlyContinue 'git')) {
} }
} }
# Use vendored Git if no user Git found or user Git is older than vendored Git # User vendored Git.
if ($null -eq $ENV:GIT_INSTALL_ROOT -and $null -ne $gitVersionVendor) { 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_ROOT = "$ENV:CMDER_ROOT\vendor\git-for-windows"
$ENV:GIT_INSTALL_TYPE = 'VENDOR' $ENV:GIT_INSTALL_TYPE = 'VENDOR'
@@ -85,44 +82,23 @@ Write-Debug "GIT_INSTALL_ROOT: ${ENV:GIT_INSTALL_ROOT}"
Write-Debug "GIT_INSTALL_TYPE: ${ENV:GIT_INSTALL_TYPE}" Write-Debug "GIT_INSTALL_TYPE: ${ENV:GIT_INSTALL_TYPE}"
if ($null -ne $ENV:GIT_INSTALL_ROOT) { if ($null -ne $ENV:GIT_INSTALL_ROOT) {
$env:Path = Set-GitPath -GitRoot "$ENV:GIT_INSTALL_ROOT" -GitType $ENV:GIT_INSTALL_TYPE -GitPathUser $gitPathUser $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) { if (Get-Command -Name "vim" -ErrorAction SilentlyContinue) {
New-Alias -name "vi" -value vim New-Alias -name "vi" -value vim
} }
# PSReadline configuration
if (Get-Module PSReadline -ErrorAction "SilentlyContinue") { if (Get-Module PSReadline -ErrorAction "SilentlyContinue") {
# Display an extra prompt line between the prompt and the command input
Set-PSReadlineOption -ExtraPromptLineCount 1 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 # Pre-assign default prompt hooks so the first run of cmder gets a working prompt.
$env:gitLoaded = $null $env:gitLoaded = $null
[ScriptBlock]$PrePrompt = {} [ScriptBlock]$PrePrompt = {}
[ScriptBlock]$PostPrompt = {} [ScriptBlock]$PostPrompt = {}
[ScriptBlock]$CmderPrompt = { [ScriptBlock]$CmderPrompt = {
# Check if we're currently running under Admin privileges # Check if we're currently running under Admin privileges.
$identity = [Security.Principal.WindowsIdentity]::GetCurrent() $identity = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = [Security.Principal.WindowsPrincipal] $identity $principal = [Security.Principal.WindowsPrincipal] $identity
$adminRole = [Security.Principal.WindowsBuiltInRole]::Administrator $adminRole = [Security.Principal.WindowsBuiltInRole]::Administrator
@@ -131,7 +107,7 @@ $env:gitLoaded = $null
$Host.UI.RawUI.ForegroundColor = "White" $Host.UI.RawUI.ForegroundColor = "White"
Microsoft.PowerShell.Utility\Write-Host "PS " -NoNewline -ForegroundColor $color Microsoft.PowerShell.Utility\Write-Host "PS " -NoNewline -ForegroundColor $color
Microsoft.PowerShell.Utility\Write-Host $pwd.ProviderPath -NoNewLine -ForegroundColor Green Microsoft.PowerShell.Utility\Write-Host $pwd.ProviderPath -NoNewLine -ForegroundColor Green
Show-GitStatus -Path $pwd.ProviderPath checkGit($pwd.ProviderPath)
Microsoft.PowerShell.Utility\Write-Host "`nλ" -NoNewLine -ForegroundColor "DarkGray" Microsoft.PowerShell.Utility\Write-Host "`nλ" -NoNewLine -ForegroundColor "DarkGray"
} }
@@ -220,23 +196,6 @@ if ( $(Get-Command prompt).Definition -match 'PS \$\(\$executionContext.SessionS
[ScriptBlock]$Prompt = { [ScriptBlock]$Prompt = {
$lastSUCCESS = $? $lastSUCCESS = $?
$realLastExitCode = $LastExitCode $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 $host.UI.RawUI.WindowTitle = Microsoft.PowerShell.Management\Split-Path $pwd.ProviderPath -Leaf
Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x200B)`r$([char]0x1B)[K" Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x200B)`r$([char]0x1B)[K"
if ($lastSUCCESS -or ($LastExitCode -ne 0)) { if ($lastSUCCESS -or ($LastExitCode -ne 0)) {
@@ -245,13 +204,6 @@ if ( $(Get-Command prompt).Definition -match 'PS \$\(\$executionContext.SessionS
PrePrompt | Microsoft.PowerShell.Utility\Write-Host -NoNewline PrePrompt | Microsoft.PowerShell.Utility\Write-Host -NoNewline
CmderPrompt CmderPrompt
PostPrompt | Microsoft.PowerShell.Utility\Write-Host -NoNewline 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 $global:LastExitCode = $realLastExitCode
return " " return " "
} }

View File

@@ -1,251 +1,179 @@
function Get-GitVersion { function readVersion($gitPath) {
param( $gitExecutable = "${gitPath}\git.exe"
[Parameter(Mandatory = $true)]
[string]$GitPath
)
$gitExecutable = Join-Path $GitPath "git.exe" if (-not (Test-Path "$gitExecutable")) {
if (-not (Test-Path $gitExecutable)) {
return $null return $null
} }
# Execute 'git --version' and capture output $gitVersion = (cmd /c "${gitExecutable}" --version)
$gitVersion = & $gitExecutable --version 2>$null
if ($gitVersion -match 'git version\s+(\S+)') { if ($gitVersion -match 'git version') {
return $Matches[1] ($trash1, $trash2, $gitVersion) = $gitVersion.split(' ', 3)
} else {
pause
return $null
} }
Write-Debug "Git executable path: $gitExecutable" return $gitVersion.toString()
Write-Error "'git --version' returned an improper version string!"
Write-Error "Unable to determine Git version from output: $gitVersion"
return $null
} }
function Get-GitShimPath { function isGitShim($gitPath) {
param( # check if there is a shim file - if yes, read the actual executable path
[Parameter(Mandatory = $true)]
[string]$GitPath
)
# Check if there is a shim file - if yes, read the actual executable path
# See: github.com/ScoopInstaller/Shim # See: github.com/ScoopInstaller/Shim
$shimFile = Join-Path $GitPath "git.shim" if (Test-Path "${gitPath}\git.shim") {
if (Test-Path $shimFile) { $shim = (get-content "${gitPath}\git.shim")
$shimContent = Get-Content $shimFile -Raw ($trash, $gitPath) = $shim.replace(' ', '').split('=')
if ($shimContent -match '^\s*path\s*=\s*(.+)\s*$') {
$GitPath = $Matches[1].Trim().Replace('\git.exe', '') $gitPath = $gitPath.replace('\git.exe', '')
}
} }
return $GitPath return $gitPath.toString()
} }
function Compare-Version { function compareVersions($userVersion, $vendorVersion) {
param( if ($null -ne $userVersion) {
[Parameter(Mandatory = $false)] ($userMajor, $userMinor, $userPatch, $userBuild) = $userVersion.split('.', 4)
[AllowNull()] } else {
[string]$UserVersion,
[Parameter(Mandatory = $false)]
[AllowNull()]
[string]$VendorVersion
)
if ([string]::IsNullOrEmpty($UserVersion)) { return -1 }
if ([string]::IsNullOrEmpty($VendorVersion)) { return 1 }
# 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 '\.'
$maxLength = [Math]::Max($userParts.Count, $vendorParts.Count)
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 return -1
} }
elseif (-not $userIsNumeric -and $vendorIsNumeric) {
# Text segment comes after numeric segment if ($null -ne $vendorVersion) {
($vendorMajor, $vendorMinor, $vendorPatch, $vendorBuild) = $vendorVersion.split('.', 4)
} else {
return 1 return 1
} }
else {
# Both are text: use case-insensitive lexicographic comparison if (($userMajor -eq $vendorMajor) -and ($userMinor -eq $vendorMinor) -and ($userPatch -eq $vendorPatch) -and ($userBuild -eq $vendorBuild)) {
$cmp = [string]::Compare($userPart, $vendorPart, $true) return 1
if ($cmp -ne 0) { return [Math]::Sign($cmp) }
}
} }
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 return 0
} }
function Compare-GitVersion { function compare_git_versions($userVersion, $vendorVersion) {
param( $result = compareVersions -userVersion $userVersion -vendorVersion $vendorVersion
[Parameter(Mandatory = $false)]
[AllowNull()]
[string]$UserVersion,
[Parameter(Mandatory = $false)]
[AllowNull()]
[string]$VendorVersion
)
$result = Compare-Version -UserVersion $UserVersion -VendorVersion $VendorVersion Write-Debug "Compare Versions Result: ${result}"
Write-Debug "Compare Versions Result: $result"
if ($result -ge 0) { if ($result -ge 0) {
return $UserVersion return $userVersion
}
else {
return $vendorVersion
} }
return $VendorVersion
} }
function Set-GitPath { function Configure-Git($gitRoot, $gitType, $gitPathUser) {
param(
[Parameter(Mandatory = $true)]
[string]$GitRoot,
[Parameter(Mandatory = $true)]
[string]$GitType,
[Parameter(Mandatory = $false)]
[string]$GitPathUser
)
# Proposed Behavior # Proposed Behavior
# Modify the path if we are using VENDORED Git, do nothing if using USER Git. # 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 # 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 # in the same path positions allowing a user to configure Cmder Git path
# using locally installed Git Path Config. # 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') { $newPath = ($env:path -ireplace [regex]::Escape($gitPathUser), $gitRoot)
return $env:Path }
else {
if (-not ($env:Path -match [regex]::Escape("$gitRoot\cmd"))) {
Write-Debug "Adding $gitRoot\cmd to the path"
$newPath = $($gitRoot + "\cmd" + ";" + $env:Path)
} }
$newPath = $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"))) {
# Replace user Git path with vendored Git if user path exists Write-Debug "Adding $gitRoot\mingw32\bin to the path"
if ($GitPathUser) { $newPath = "$newPath;$gitRoot\mingw32\bin"
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 elseif ((Test-Path "$gitRoot\mingw64\bin") -and -not ($env:path -match [regex]::Escape("$gitRoot\mingw64\bin"))) {
} else { Write-Debug "Adding $gitRoot\mingw64\bin to the path"
# Add Git cmd directory to the path $newPath = "$newPath;$gitRoot\mingw64\bin"
$gitCmd = Join-Path $GitRoot "cmd"
if (-not ($newPath -match [regex]::Escape($gitCmd))) {
Write-Debug "Adding $gitCmd to the path"
$newPath = "$gitCmd;$newPath"
} }
# Add mingw[32|64]\bin directories to the path, if they exist and not already present # Add "$gitRoot\usr\bin" to the path if exists and not done already
# Prefer mingw64 on 64-bit systems, mingw32 on 32-bit systems if ((Test-Path "$gitRoot\usr\bin") -and -not ($env:path -match [regex]::Escape("$gitRoot\usr\bin"))) {
$is64Bit = [Environment]::Is64BitOperatingSystem Write-Debug "Adding $gitRoot\usr\bin to the path"
$mingwDirs = if ($is64Bit) { @('mingw64', 'mingw32') } else { @('mingw32') } $newPath = "$newPath;$gitRoot\usr\bin"
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"
$newPath = "$newPath;$mingwBin"
break
}
}
# 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"
$newPath = "$newPath;$usrBin"
} }
} }
return $newPath return $newPath
}
return $env:path
} }
function Import-Git { function Import-Git() {
$gitModule = Get-Module -Name Posh-Git -ListAvailable $GitModule = Get-Module -Name Posh-Git -ListAvailable
if ($GitModule | Select-Object version | Where-Object version -le ([version]"0.6.1.20160330")) {
if (-not $gitModule) { Import-Module Posh-Git > $null
Microsoft.PowerShell.Utility\Write-Host -NoNewline "`r`n"
Write-Warning "Missing git support, install posh-git with 'Install-Module posh-git' and restart Cmder."
Microsoft.PowerShell.Utility\Write-Host -NoNewline "`r$([char]0x1B)[A"
return $false
} }
if ($GitModule | Select-Object version | Where-Object version -ge ([version]"1.0.0")) {
# Import posh-git module (works for all versions) Import-Module Posh-Git > $null
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 $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 return $true
} }
function Show-GitStatus { function checkGit($Path) {
param(
[Parameter(Mandatory = $true)]
[string]$Path
)
if (-not (Get-Command git -ErrorAction SilentlyContinue)) { if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
return return
} }
if (-not (Test-Path -Path (Join-Path $Path '.git'))) {
$gitDir = Join-Path $Path '.git' $SplitPath = Split-Path $path
if (-not (Test-Path $gitDir)) { if ($SplitPath) { checkGit($SplitPath) }
$parentPath = Split-Path $Path
if ($parentPath) {
Show-GitStatus -Path $parentPath
}
return return
} }
if (getGitStatusSetting -eq $true) {
if (Get-GitStatusSetting) {
if ($null -eq $env:gitLoaded) { if ($null -eq $env:gitLoaded) {
$env:gitLoaded = Import-Git $env:gitLoaded = Import-Git
} }
if ($env:gitLoaded -eq $true) { if ($env:gitLoaded -eq $true) {
Write-VcsStatus Write-VcsStatus
} }
} 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 {
$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 Get-GitStatusSetting { function getGitStatusSetting() {
$gitConfig = git --no-pager config -l 2>$null | Out-String $gitStatus = (git --no-pager config -l) | Out-String
# Check if git status display is disabled via config foreach ($line in $($gitStatus -split "`r`n")) {
# Matches: cmder.status=false or cmder.psstatus=false (PowerShell-specific) if (($line -match 'cmder.status=false') -or ($line -match 'cmder.psstatus=false')) {
if ($gitConfig -match '(?m)^cmder\.(ps)?status=false$') {
return $false return $false
} }
}
return $true return $true
} }

19
vendor/sources.json vendored
View File

@@ -1,27 +1,22 @@
[ [
{ {
"name": "git-for-windows", "name": "git-for-windows",
"version": "2.51.2.windows.1", "version": "2.49.0.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" "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", "name": "clink",
"version": "1.8.8", "version": "1.7.14",
"url": "https://github.com/chrisant996/clink/releases/download/v1.8.8/clink.1.8.8.a63364.zip" "url": "https://github.com/chrisant996/clink/releases/download/v1.7.14/clink.1.7.14.843933.zip"
}, },
{ {
"name": "conemu-maximus5", "name": "conemu-maximus5",
"version": "23.07.24", "version": "23.07.24",
"url": "https://github.com/ConEmu/ConEmu/releases/download/v23.07.24/ConEmuPack.230724.7z" "url": "https://github.com/Maximus5/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", "name": "clink-completions",
"version": "0.6.6", "version": "0.6.2",
"url": "https://github.com/vladimir-kotikov/clink-completions/archive/v0.6.6.zip" "url": "https://github.com/vladimir-kotikov/clink-completions/archive/v0.6.2.zip"
} }
] ]