diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 000000000..0091f768c --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,15 @@ +# List of whitespace-only commits to ignore in the Git blame; +# to improve tracking changes and avoid noise +58db4e3419bf1e5cc1bb61fcd7ce2ebbca89243a +efb3338f5cf0eec21e8a75abc62ee14965cb4a7e +3859f6ffc088b2ae78748abc84986f4adcadcd41 +d6569192fc91167f555c3eff58402ff01f1197ea +67de97a492c9389f95499db38f9474a1c20ec585 +a0d085f93eaa69c22449d0217e8daf9eaea2b180 +1cfba25beb46c74bb1debca2bcfe7ac470e96172 +f6bc623284914489e891bbac923feb774c862b99 +abbab3f8b477e917d0a175d0de23cce121096631 +126347025f9cade241beff182738b2527da7535e +4740b836f300658b27e6ad4d79efac63c9c24c24 +be44bac95670b1cbbc91bd657882d985989846f9 +f67e5704eda60526d495be758572181f01a6cac8 diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index e303633ff..15803553f 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -20,7 +20,7 @@ body: label: Version Information description: | Please write your Cmder and ConEmu version below. If applicable, write down your Windows edition too. - **๐Ÿ‘‰ See:** [How to find out which Cmder version I'm using](https://github.com/cmderdev/cmder/wiki/Cmder-troubleshooting) + **๐Ÿ‘‰ See:** [How to find out which Cmder version I'm using](https://github.com/daxgames/cmder/wiki/Cmder-troubleshooting) placeholder: | Cmder version: Operating system: @@ -52,13 +52,13 @@ body: | **README.md** | **Wiki** | | ------------- | -------- | - | ๐ŸŒ [Open Link](https://github.com/cmderdev/cmder/blob/master/README.md) | ๐ŸŒ [Open Link](https://github.com/cmderdev/cmder/wiki) | + | ๐ŸŒ [Open Link](https://github.com/daxgames/cmder/blob/main/README.md) | ๐ŸŒ [Open Link](https://github.com/daxgames/cmder/wiki) | (What you may be asking here could already be explained there!) - Searched for existing issues (including the **closed** ones) for similar problems here: - ๐Ÿ—ƒ https://github.com/cmderdev/cmder/issues?q=is:issue + ๐Ÿ—ƒ https://github.com/daxgames/cmder/issues?q=is:issue - Please understand that Cmder uses ConEmu as the default underlying Terminal Emulator. @@ -91,10 +91,10 @@ body: #### Prerequisites before submitting an issue - We do not support any versions older than the current release series, if you are using an older Cmder please update to the latest version first. - - Verify that the issue is not already fixed and is reproducible in the **[latest official Cmder version](https://github.com/cmderdev/cmder/releases).** - - Check the **[current issues list](https://github.com/cmderdev/cmder/issues?q=is%3Aissue)** and perform a **search of the issue tracker (including closed ones)** to avoid posting a duplicate bug report. - - Make sure this is not a support request or question, both of which are better suited for either the **[discussions section](https://github.com/cmderdev/cmder/discussions)**, or the **[questions section](https://github.com/cmderdev/cmder/issues/new?template=question.yml)**. - - Verify that the **[wiki](https://github.com/cmderdev/cmder/wiki)** did not contain a suitable solution either. + - Verify that the issue is not already fixed and is reproducible in the **[latest official Cmder version](https://github.com/daxgames/cmder/releases).** + - Check the **[current issues list](https://github.com/daxgames/cmder/issues?q=is%3Aissue)** and perform a **search of the issue tracker (including closed ones)** to avoid posting a duplicate bug report. + - Make sure this is not a support request or question, both of which are better suited for either the **[discussions section](https://github.com/daxgames/cmder/discussions)**, or the **[questions section](https://github.com/daxgames/cmder/issues/new?template=question.yml)**. + - Verify that the **[wiki](https://github.com/daxgames/cmder/wiki)** did not contain a suitable solution either. Thank you for making sure you are opening a new valid issue! โ™ฅ diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 0dd068b08..4f424ec57 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,9 +1,9 @@ blank_issues_enabled: false contact_links: - name: ๐Ÿ“„ Wiki - url: "https://github.com/cmderdev/cmder/wiki" + url: "https://github.com/daxgames/cmder/wiki" about: "Consult the wiki first, it might already contain the information you are looking for" - name: ๐Ÿ’ฌ Discussions - url: "https://github.com/cmderdev/cmder/discussions" + url: "https://github.com/daxgames/cmder/discussions" about: "Please ask questions related to usage/setup/support/non-issue development discussion in the Discussions section" diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml index b80fe0b60..ff5470364 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.yml +++ b/.github/ISSUE_TEMPLATE/feature-request.yml @@ -16,7 +16,7 @@ body: - Searched for existing issues (including the **closed** ones) for similar feature requests here: - ๐Ÿ—ƒ https://github.com/cmderdev/cmder/issues?q=is:issue + ๐Ÿ—ƒ https://github.com/daxgames/cmder/issues?q=is:issue - If you are opening the feature request regarding any of the **upstream technologies** that are used by Cmder, please open the feature request at the corresponding upstream repos instead: - **[Clink](https://github.com/chrisant996/clink)**, the default shell in Cmder @@ -28,7 +28,7 @@ body: You may already have an answer under the Guides or Questions section. - For a list of labels, visit **[๐ŸŒ Labels](https://github.com/cmderdev/cmder/labels)**. + For a list of labels, visit **[๐ŸŒ Labels](https://github.com/daxgames/cmder/labels)**. (Be sure to also check โ€œClosedโ€ issues in the labels section!) diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml index de27b37c0..3091f8473 100644 --- a/.github/ISSUE_TEMPLATE/question.yml +++ b/.github/ISSUE_TEMPLATE/question.yml @@ -13,15 +13,15 @@ body: | **README.md** | **Wiki** | **Issues** | | ------------- | -------- | ---------- | - | ๐ŸŒ [Open Link](https://github.com/cmderdev/cmder/blob/master/README.md) | ๐ŸŒ [Open Link](https://github.com/cmderdev/cmder/wiki) | ๐Ÿ—ƒ [Open Link](https://github.com/cmderdev/cmder/issues?q=is:issue) | + | ๐ŸŒ [Open Link](https://github.com/daxgames/cmder/blob/main/README.md) | ๐ŸŒ [Open Link](https://github.com/daxgames/cmder/wiki) | ๐Ÿ—ƒ [Open Link](https://github.com/daxgames/cmder/issues?q=is:issue) | (What you may be asking here could already be explained there!) - If you would like to ask for guides on how to integrate Cmder with your favorite IDE of choice, or how to perform a specific task with Cmder, make sure you visit our label section first. - You may already have an answer under the [๐Ÿ’ฌ Guides](https://github.com/cmderdev/cmder/issues?q=label%3A%22%F0%9F%92%AC+Type%3A+Guide%22), [๐Ÿ“– Documentation](https://github.com/cmderdev/cmder/issues?q=label%3A%22%F0%9F%93%96+Documentation%22) or [โ” Questions](https://github.com/cmderdev/cmder/issues?q=is%3Aissue+label%3A%22%E2%9D%94+Type%3A+Question%22) section. + You may already have an answer under the [๐Ÿ’ฌ Guides](https://github.com/daxgames/cmder/issues?q=label%3A%22%F0%9F%92%AC+Type%3A+Guide%22), [๐Ÿ“– Documentation](https://github.com/daxgames/cmder/issues?q=label%3A%22%F0%9F%93%96+Documentation%22) or [โ” Questions](https://github.com/daxgames/cmder/issues?q=is%3Aissue+label%3A%22%E2%9D%94+Type%3A+Question%22) section. - For a list of labels, visit **[Labels](https://github.com/cmderdev/cmder/labels)**. + For a list of labels, visit **[Labels](https://github.com/daxgames/cmder/labels)**. (Be sure to also check โ€œClosedโ€ issues in the labels section!) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 9ef6c2af7..b05586197 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,7 +1,12 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + version: 2 updates: # Enable version updates for GitHub Actions - - package-ecosystem: "github-actions" + - package-ecosystem: "github-actions" # See documentation for possible values directory: "/" # Location of package manifests schedule: interval: "weekly" diff --git a/.github/workflows/branches.yml b/.github/workflows/branches.yml index ff65db165..2fe2994a2 100644 --- a/.github/workflows/branches.yml +++ b/.github/workflows/branches.yml @@ -2,7 +2,7 @@ name: Update branches # Controls when the action will run. on: - # Triggers the workflow on push events for the development branch + # Triggers the workflow on push events for the dev branch push: branches: [ master ] @@ -11,8 +11,8 @@ on: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: - # This job updates the development branch with the master branch - update-development: + # This job updates the dev branch with the master branch + update-dev: # The type of runner that the job will run on runs-on: ubuntu-latest @@ -33,19 +33,19 @@ jobs: echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY echo "| --- | --- |" >> $GITHUB_STEP_SUMMARY echo "| Source Branch | \`master\` |" >> $GITHUB_STEP_SUMMARY - echo "| Target Branch | \`development\` |" >> $GITHUB_STEP_SUMMARY + echo "| Target Branch | \`dev\` |" >> $GITHUB_STEP_SUMMARY echo "| Triggered by | @${{ github.actor }} |" >> $GITHUB_STEP_SUMMARY echo "| Commit | \`${{ github.sha }}\` |" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY # Runs a single command using the runners shell - - name: Merge master into development + - name: Merge master into dev run: | git config user.name "${{ github.actor }}" git config user.email "${{ github.actor }}@users.noreply.github.com" - git checkout development + git checkout dev git merge --no-ff master - git push origin development + git push origin dev - name: Summary - Merge completed if: success() @@ -53,8 +53,8 @@ jobs: run: | echo "### โœ… Merge Successful" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY - echo "The \`master\` branch has been successfully merged into \`development\`." >> $GITHUB_STEP_SUMMARY + echo "The \`master\` branch has been successfully merged into \`dev\`." >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "**Merge type:** No fast-forward merge" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY - echo "> The development branch is now synchronized with the latest changes from master." >> $GITHUB_STEP_SUMMARY + echo "> The dev branch is now synchronized with the latest changes from master." >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 37b7b8ad0..355ade855 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,11 +7,11 @@ name: Build Cmder # Controls when the action will run. Triggers the workflow on push or pull request events but only for the main branch on: push: - branches: [ "master" ] + branches: [ "master", "main" ] tags: - "v*" pull_request: - branches: [ "master", "development" ] + branches: [ "master", "main", "development" ] #---------------------------------# # environment configuration # @@ -42,100 +42,246 @@ jobs: - name: Summary - Repository checkout shell: pwsh run: | - echo "## ๐Ÿ“ฆ Build Cmder - Workflow Summary" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "### Repository Information" >> $env:GITHUB_STEP_SUMMARY - echo "| Property | Value |" >> $env:GITHUB_STEP_SUMMARY - echo "| --- | --- |" >> $env:GITHUB_STEP_SUMMARY - echo "| Repository | \`${{ github.repository }}\` |" >> $env:GITHUB_STEP_SUMMARY - echo "| Branch | \`${{ github.ref_name }}\` |" >> $env:GITHUB_STEP_SUMMARY - echo "| Commit | \`${{ github.sha }}\` |" >> $env:GITHUB_STEP_SUMMARY - echo "| Actor | @${{ github.actor }} |" >> $env:GITHUB_STEP_SUMMARY - echo "| Workflow | \`${{ github.workflow }}\` |" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY + # Get Cmder version + . scripts/utils.ps1 + $cmderVersion = Get-VersionStr + $buildTime = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") + + # Determine branch and PR information + $refName = "${{ github.ref_name }}" + $headRef = "${{ github.head_ref }}" + $eventName = "${{ github.event_name }}" + $prNumber = $null + $actualBranchName = $refName + $branchLink = "" + $prLink = "" + + # Check if this is a PR merge ref (e.g., "3061/merge") + if ($refName -match '^(\d+)/(merge|head)$') { + $prNumber = $Matches[1] + # Use head_ref for the actual branch name if available + if ($headRef) { + $actualBranchName = $headRef + } + $branchLink = "https://github.com/${{ github.repository }}/tree/$actualBranchName" + $prLink = "https://github.com/${{ github.repository }}/pull/$prNumber" + } elseif ($eventName -eq "pull_request") { + # This is a pull request event + $prNumber = "${{ github.event.pull_request.number }}" + if ($headRef) { + $actualBranchName = $headRef + } + $branchLink = "https://github.com/${{ github.repository }}/tree/$actualBranchName" + $prLink = "https://github.com/${{ github.repository }}/pull/$prNumber" + } else { + # Regular branch, link to the branch tree + $branchLink = "https://github.com/${{ github.repository }}/tree/$refName" + } + + $summary = @" + ## ๐Ÿ“ฆ Build Cmder - Workflow Summary + + Build started: ``$buildTime`` + + ### Repository Information + | Property | Value | + | --- | --- | + | Repository | [``${{ github.repository }}``](https://github.com/${{ github.repository }}) | + | Branch | [``$actualBranchName``]($branchLink) | + $(if ($prNumber) { "| Pull Request | [#$prNumber]($prLink) |" }) + | Commit | [``${{ github.sha }}``](https://github.com/${{ github.repository }}/commit/${{ github.sha }}) | + | Actor | [@${{ github.actor }}](https://github.com/${{ github.actor }}) | + | Workflow | ``${{ github.workflow }}`` | + | Cmder Version | **$cmderVersion** | + + --- + + ### ๐Ÿ—ƒ๏ธ Vendor Packages ([sources.json](vendor/sources.json)) + | Package | Version | + | --- | --- | + "@ + + # Read vendor sources.json and add to summary + $vendorSources = Get-Content -Raw "vendor/sources.json" | ConvertFrom-Json + if ($vendorSources.Count -eq 0) { + $summary += "`n| _No vendor packages found_ | |" + } else { + foreach ($vendor in $vendorSources) { + # Create release link based on vendor package + $versionLink = "$($vendor.version)" + if ($vendor.url) { + # Extract owner/repo/tag from the URL and create release link + # Handle both /releases/download/ and /archive/ URLs + if ($vendor.url -match 'github\.com/([^/]+)/([^/]+)/(releases/download|archive)/([^/]+)') { + $owner = $Matches[1] + $repo = $Matches[2] + $pathType = $Matches[3] + $tag = $Matches[4] + if ($pathType -eq 'archive') { + $tag = $tag -replace '\.(?:tar\.gz|tgz|zip)$', '' + } + $versionLink = "[$($vendor.version)](https://github.com/$owner/$repo/releases/tag/$tag)" + } + } + $summary += "`n| ``$($vendor.name)`` | $versionLink |" + } + } + + $summary += "`n" + + $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8 - name: Add MSBuild to PATH - uses: microsoft/setup-msbuild@v2 + uses: microsoft/setup-msbuild@v3 - name: Build Cmder Launcher shell: pwsh working-directory: scripts - run: .\build.ps1 -Compile -verbose + run: .\build.ps1 -Compile -verbose -terminal -all -installPacman - name: Summary - Build completed if: success() shell: pwsh run: | - echo "### โœ… Build Status" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "Cmder launcher successfully compiled." >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY + $summary = @" + + --- + + โœ… Cmder built successfully. + + "@ + + $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8 - name: Pack the built files shell: pwsh working-directory: scripts - run: .\pack.ps1 -verbose + run: .\pack.ps1 -verbose -terminal all - - name: Summary - Package artifacts - if: success() - shell: pwsh - run: | - echo "### ๐Ÿ“ฆ Artifacts Created" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "| Artifact | Size | Hash (SHA256) |" >> $env:GITHUB_STEP_SUMMARY - echo "| --- | --- | --- |" >> $env:GITHUB_STEP_SUMMARY - $artifacts = @("cmder.zip", "cmder.7z", "cmder_mini.zip") - foreach ($artifact in $artifacts) { - $path = "build/$artifact" - if (Test-Path $path) { - $size = (Get-Item $path).Length / 1MB - # Truncate hash to first 16 chars for summary readability (full hash in hashes.txt) - $hash = (Get-FileHash $path -Algorithm SHA256).Hash.Substring(0, 16) - echo "| \`$artifact\` | $([math]::Round($size, 2)) MB | \`$hash...\` |" >> $env:GITHUB_STEP_SUMMARY - } - } - echo "" >> $env:GITHUB_STEP_SUMMARY + - name: Upload artifact (cmder_win_mini.zip) + 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@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@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@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@v4 + with: + path: build/cmder_wt.7z + name: cmder_wt.7z + + - name: Upload artifact (cmder_wt_mini.zip) + uses: actions/upload-artifact@v4 + with: + path: build/cmder_wt_mini.zip + name: cmder_wt_mini.zip - name: Upload artifact (cmder.zip) - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: path: build/cmder.zip name: cmder.zip + archive: false if-no-files-found: error - name: Upload artifact (cmder.7z) - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: path: build/cmder.7z name: cmder.7z + archive: false - name: Upload artifact (cmder_mini.zip) - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: path: build/cmder_mini.zip name: cmder_mini.zip + archive: false - name: Upload artifact (hashes.txt) - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: path: build/hashes.txt name: hashes.txt + archive: false - name: Summary - Artifacts uploaded if: success() shell: pwsh + env: + GH_TOKEN: ${{ github.token }} run: | - echo "### โ˜๏ธ Upload Status" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "All artifacts successfully uploaded to GitHub Actions:" >> $env:GITHUB_STEP_SUMMARY - echo '- โœ… `cmder.zip`' >> $env:GITHUB_STEP_SUMMARY - echo '- โœ… `cmder.7z`' >> $env:GITHUB_STEP_SUMMARY - echo '- โœ… `cmder_mini.zip`' >> $env:GITHUB_STEP_SUMMARY - echo '- โœ… `hashes.txt`' >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY + # Source utility functions + . scripts/utils.ps1 + + $summary = @" + + ### ๐Ÿ—ƒ๏ธ Artifacts + + | Artifact | Size | Hash (SHA256) | + | --- | --- | --- | + "@ + + # Get all files from the build directory (excluding directories and hidden files) + if (Test-Path "build") { + $buildFiles = Get-ChildItem -Path "build" -File | Where-Object { -not $_.Name.StartsWith('.') } | Sort-Object Name + + foreach ($file in $buildFiles) { + $artifact = $file.Name + $path = $file.FullName + $sizeFormatted = Format-FileSize -Bytes $file.Length + $hash = (Get-FileHash $path -Algorithm SHA256).Hash + + # Try to get the actual artifact download URL + $downloadUrl = Get-ArtifactDownloadUrl -ArtifactName $artifact -Repository "${{ github.repository }}" -RunId "${{ github.run_id }}" + $warning = "" + + if (-not $downloadUrl) { + # Fallback to workflow run page if artifact URL fetch fails + $downloadUrl = "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" + $warning = " โš ๏ธ" + } + + # Determine emoji based on file type + if ($artifact -match '\.txt$') { + $emoji = "๐Ÿ“„" + } elseif ($artifact -match '\.(zip|rar|7z)$') { + $emoji = "๐Ÿ—„๏ธ" + } else { + $emoji = "๐Ÿ“ฆ" + } + + $summary += "`n| $emoji [``$artifact``$warning]($downloadUrl) | $sizeFormatted | ``$hash`` |" + } + } + $summary += "`n" + + $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8 - name: Create Release - uses: softprops/action-gh-release@v2 + uses: softprops/action-gh-release@v3 with: files: | build/cmder.zip @@ -150,14 +296,20 @@ jobs: if: startsWith(github.ref, 'refs/tags/') shell: pwsh run: | - echo "### ๐Ÿš€ Release Information" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "Draft release created for tag: **\`${{ github.ref_name }}\`**" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "Release includes:" >> $env:GITHUB_STEP_SUMMARY - echo "- Full version (\`cmder.zip\`, \`cmder.7z\`)" >> $env:GITHUB_STEP_SUMMARY - echo "- Mini version (\`cmder_mini.zip\`)" >> $env:GITHUB_STEP_SUMMARY - echo "- File hashes (\`hashes.txt\`)" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "> โš ๏ธ Release is in **draft** mode. Please review and publish manually." >> $env:GITHUB_STEP_SUMMARY + $summary = @" + + --- + + ### Release Information + + ๐Ÿš€ Draft release created for tag: **``${{ github.ref_name }}``** + + Release includes: + - Full version (``cmder.zip``, ``cmder.7z``) + - Mini version (``cmder_mini.zip``) + - File hashes (``hashes.txt``) + + > โš ๏ธ Release is in **draft** mode. Please review and publish manually. + "@ + $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 1497bf9ac..7f66475f1 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -8,7 +8,7 @@ name: "CodeQL" on: push: - branches: [ "master", "development" ] + branches: [ "master", "main", "development" ] paths-ignore: - '**/*.md' - '**/*.txt' @@ -16,7 +16,7 @@ on: - '**/.gitignore' pull_request: # The branches below must be a subset of the branches above - branches: [ "master", "development" ] + branches: [ "master", "main", "development" ] paths-ignore: - '**/*.md' - '**/*.txt' @@ -50,20 +50,21 @@ jobs: - name: Summary - CodeQL analysis started shell: pwsh run: | - $summary = @( - '## ๐Ÿ”’ CodeQL Security Analysis - Workflow Summary' - '' - '### Analysis Configuration' - '' - '| Property | Value |' - '| --- | --- |' - '| Repository | `${{ github.repository }}` |' - '| Branch | `${{ github.ref_name }}` |' - '| Language | `${{ matrix.language }}` |' - '| Commit | `${{ github.sha }}` |' - '' - ) - $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY + $summary = @" + ## ๐Ÿ”’ CodeQL Security Analysis - Workflow Summary + + ### Analysis Configuration + + | Property | Value | + | --- | --- | + | Repository | ``${{ github.repository }}`` | + | Branch | ``${{ github.ref_name }}`` | + | Language | ``${{ matrix.language }}`` | + | Commit | ``${{ github.sha }}`` | + + "@ + + $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL @@ -78,7 +79,7 @@ jobs: # queries: security-extended,security-and-quality - name: Add MSBuild to PATH - uses: microsoft/setup-msbuild@v2 + uses: microsoft/setup-msbuild@v3 - name: Build Cmder Launcher shell: pwsh @@ -89,13 +90,14 @@ jobs: if: success() shell: pwsh run: | - $summary = @( - '### โœ… Build Completed' - '' - 'Cmder launcher built successfully for CodeQL analysis.' - '' - ) - $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY + $summary = @" + ### โœ… Build Completed + + Cmder launcher built successfully for CodeQL analysis. + + "@ + + $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8 - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v4 @@ -106,13 +108,14 @@ jobs: if: success() shell: pwsh run: | - $summary = @( - '### ๐Ÿ” CodeQL Analysis Results' - '' - 'โœ… CodeQL security analysis completed successfully.' - '' - '**Language analyzed:** `${{ matrix.language }}`' - '' - '> Check the Security tab for detailed findings and recommendations.' - ) - $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY + $summary = @" + ### ๐Ÿ” CodeQL Analysis Results + + โœ… CodeQL security analysis completed successfully. + + **Language analyzed:** ``${{ matrix.language }}`` + + > Check the Security tab for detailed findings and recommendations. + "@ + + $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5110ab18d..667b8e7ab 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -4,6 +4,7 @@ on: push: branches: - master + - main - development paths-ignore: - '**/*.md' @@ -13,6 +14,7 @@ on: pull_request: branches: - master + - main - development paths-ignore: - '**/*.md' @@ -39,20 +41,33 @@ jobs: steps: - uses: actions/checkout@v6 + with: + fetch-depth: 0 - name: Summary - Test execution started shell: pwsh run: | - echo "## ๐Ÿงช Run Tests - Workflow Summary" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "### Test Environment" >> $env:GITHUB_STEP_SUMMARY - echo "| Property | Value |" >> $env:GITHUB_STEP_SUMMARY - echo "| --- | --- |" >> $env:GITHUB_STEP_SUMMARY - echo "| Repository | \`${{ github.repository }}\` |" >> $env:GITHUB_STEP_SUMMARY - echo "| Branch | \`${{ github.ref_name }}\` |" >> $env:GITHUB_STEP_SUMMARY - echo "| Commit | \`${{ github.sha }}\` |" >> $env:GITHUB_STEP_SUMMARY - echo "| Runner OS | \`${{ runner.os }}\` |" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY + # Get Cmder version + . scripts/utils.ps1 + $cmderVersion = Get-VersionStr + + $summary = @" + ## โœ… Run Tests - Workflow Summary + + ### Test Environment + | Property | Value | + | --- | --- | + | Repository | ``${{ github.repository }}`` | + | Branch | ``${{ github.ref_name }}`` | + | Commit | ``${{ github.sha }}`` | + | Runner OS | ``${{ runner.os }}`` | + | Cmder Version | **$cmderVersion** | + | PowerShell Version | **$($PSVersionTable.PSVersion)** | + | Event | ``${{ github.event_name }}`` | + + "@ + + $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8 - name: Initialize vendors shell: pwsh @@ -63,53 +78,127 @@ jobs: if: success() shell: pwsh run: | - echo "### โš™๏ธ Vendor Initialization" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "โœ… Vendor dependencies initialized successfully." >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY + # Get vendor versions from sources.json + $vendorInfo = @() + $sources = Get-Content "vendor\sources.json" -Raw | ConvertFrom-Json + foreach ($source in $sources) { + $dir = $source.name + if (-not $dir) { + continue + } + $versionFile = "vendor/$dir/.cmderver" + if (Test-Path $versionFile) { + $version = Get-Content $versionFile -Raw + $vendorInfo += "- **$dir**: $($version.Trim())" + } + } + + $summary = @" + ### โš™๏ธ Vendor Initialization + + โœ… Vendor dependencies initialized successfully. + + **Vendor Versions:** + "@ + + $( + if ($vendorInfo.Count -eq 0) { + $summary += "_No vendor version information available._" + } else { + $summary += $vendorInfo -join "`n" + } + ) + + $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8 - name: Summary - Test results table header if: success() shell: pwsh run: | - echo "### ๐Ÿ“‹ Test Results" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "| Test | Status |" >> $env:GITHUB_STEP_SUMMARY - echo "| --- | --- |" >> $env:GITHUB_STEP_SUMMARY + $summary = @" + ### ๐Ÿ“‹ Test Results + + | Test | Status | Duration | + | --- | --- | --- | + "@ + + $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8 - name: Testing Clink Shell + id: test-clink + shell: pwsh run: | + $startTime = Get-Date cmd /c vendor\init.bat /v /d /t + $duration = [math]::Round(((Get-Date) - $startTime).TotalSeconds, 2) + echo "duration=$duration" >> $env:GITHUB_OUTPUT - name: Summary - Clink Shell test if: success() shell: pwsh run: | - echo "| Clink Shell | โœ… Passed |" >> $env:GITHUB_STEP_SUMMARY + $duration = "${{ steps.test-clink.outputs.duration }}" + if ($duration) { + $duration = "$duration s" + } else { + $duration = "N/A" + } + "| Clink Shell | โœ… Passed | $duration |" | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8 - name: Testing PowerShell + id: test-powershell + shell: pwsh run: | + $startTime = Get-Date PowerShell.exe -ExecutionPolicy Bypass -NoLogo -NoProfile -Command "$env:CMDER_DEBUG='1'; . 'vendor\profile.ps1'" + $duration = [math]::Round(((Get-Date) - $startTime).TotalSeconds, 2) + echo "duration=$duration" >> $env:GITHUB_OUTPUT - name: Summary - PowerShell test if: success() shell: pwsh run: | - echo "| PowerShell | โœ… Passed |" >> $env:GITHUB_STEP_SUMMARY + $duration = "${{ steps.test-powershell.outputs.duration }}" + if ($duration) { + $duration = "$duration s" + } else { + $duration = "N/A" + } + "| PowerShell | โœ… Passed | $duration |" | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8 - name: Testing Bash + id: test-bash + shell: pwsh run: | + $startTime = Get-Date bash vendor/cmder.sh + $duration = [math]::Round(((Get-Date) - $startTime).TotalSeconds, 2) + echo "duration=$duration" >> $env:GITHUB_OUTPUT - name: Summary - Bash test if: success() shell: pwsh run: | - echo "| Bash | โœ… Passed |" >> $env:GITHUB_STEP_SUMMARY + $duration = "${{ steps.test-bash.outputs.duration }}" + if ($duration) { + $duration = "$duration s" + } else { + $duration = "N/A" + } + "| Bash | โœ… Passed | $duration |" | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8 - name: Summary - All tests completed if: success() shell: pwsh run: | - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "### โœ… All Tests Completed" >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "All shell environments tested successfully!" >> $env:GITHUB_STEP_SUMMARY + $summary = @" + + ### โœ… All Tests Completed + + All shell environments tested successfully! + + **Test Coverage:** + - โœ… Clink shell environment (Windows cmd.exe with Clink) + - โœ… PowerShell environment (with Cmder profile) + - โœ… Bash environment (Git Bash integration) + "@ + + $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8 diff --git a/.github/workflows/vendor.yml b/.github/workflows/vendor.yml index ab254aedf..9c68a8a7d 100644 --- a/.github/workflows/vendor.yml +++ b/.github/workflows/vendor.yml @@ -31,87 +31,98 @@ jobs: - name: Summary - Workflow started shell: pwsh run: | - $summary = @( - '## ๐Ÿ“ฆ Update Vendor - Workflow Summary' - '' - 'Checking for vendor dependency updates...' - '' - ) - $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY + $summary = @" + ## ๐Ÿ“ฆ Update Vendor - Workflow Summary + + Checking for vendor dependency updates... + + "@ + + $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8 - id: make-changes name: Checking for updates env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - $currentVersion = (Get-Content .\vendor\sources.json | ConvertFrom-Json) - . .\scripts\update.ps1 -verbose - Set-GHVariable -Name COUNT_UPDATED -Value $count - $newVersion = (Get-Content .\vendor\sources.json | ConvertFrom-Json) - $listUpdated = "" - $updateMessage = "| Name | Old Version | New Version |`n| :--- | ---- | ---- |`n" - foreach ($s in $newVersion) { - $oldVersion = ($currentVersion | Where-Object {$_.name -eq $s.name}).version - if ($s.version -ne $oldVersion) { - $repoUrl = ($repoUrl = $s.Url.Replace("/archive/", "/releases/")).Substring(0, $repoUrl.IndexOf("/releases/")) + "/releases" - $listUpdated += "$($s.name) v$($s.version), " - $updateMessage += "| **[$($s.name)]($repoUrl)** | $oldVersion | **$($s.version)** |`n" - } + $currentVersion = (Get-Content -Raw .\vendor\sources.json | ConvertFrom-Json) + . .\scripts\update.ps1 -verbose + Set-GHVariable -Name COUNT_UPDATED -Value $count + $newVersion = (Get-Content -Raw .\vendor\sources.json | ConvertFrom-Json) + $listUpdated = "" + $updateMessage = "| Name | Old Version | New Version |`n| :--- | ---- | ---- |`n" + foreach ($s in $newVersion) { + $oldVersion = ($currentVersion | Where-Object {$_.name -eq $s.name}).version + if ($s.version -ne $oldVersion) { + $repoUrl = ($repoUrl = $s.Url.Replace("/archive/", "/releases/")).Substring(0, $repoUrl.IndexOf("/releases/")) + "/releases" + $listUpdated += "$($s.name) v$($s.version), " + $updateMessage += "| **[$($s.name)]($repoUrl)** | $oldVersion | **$($s.version)** |`n" } - if ($count -eq 0) { return } - Set-GHVariable -Name LIST_UPDATED -Value $listUpdated.Trim(', ') - echo "UPDATE_MESSAGE<< 0 + if: env.COUNT_UPDATED > 0 && (env.HAS_BREAKING_CHANGES == 'True' || env.AUTO_MERGED == 'false') with: - title: 'Updates to `${{ env.COUNT_UPDATED }}` vendored dependencies' + title: ${{ env.COUNT_UPDATED == '1' && format('โฌ†๏ธ Update {0}', env.LIST_UPDATED) || format('โฌ†๏ธ Update {0} vendored dependencies', env.COUNT_UPDATED) }} body: | - ### Automatically updated `${{ env.COUNT_UPDATED }}` dependencies: + ### ${{ env.COUNT_UPDATED == 1 && format('๐Ÿ“ฆ Updated {0} from `{1}` to `{2}`', env.SINGLE_DEP_NAME, env.SINGLE_DEP_OLD_VERSION, env.SINGLE_DEP_NEW_VERSION) || format('๐Ÿ“ฆ Automatically updated `{0}` dependencies', env.COUNT_UPDATED) }} + ${{ env.UPDATE_MESSAGE }} + + ${{ env.CHANGELOG_SECTION }} + --- - Please verify and then **Merge** the pull request to update. + + ${{ env.HAS_BREAKING_CHANGES == 'True' && 'โš ๏ธ **This update contains major version changes that may include breaking changes.**' || 'โ„น๏ธ This update only contains minor or patch changes.' }} + + Please verify and then **Merge** the pull request to apply the updates. commit-message: 'โฌ†๏ธ Update dependencies (${{ env.LIST_UPDATED }})' branch: update-vendor - base: master + base: main - name: Summary - Pull request created - if: env.COUNT_UPDATED > 0 + if: env.COUNT_UPDATED > 0 && (env.HAS_BREAKING_CHANGES == 'True' || env.AUTO_MERGED == 'false') shell: pwsh run: | - $summary = @( - '### ๐ŸŽ‰ Pull Request Created' - '' - 'A pull request has been created to update the vendor dependencies.' - '' - '**Branch:** `update-vendor`' - '' - $env:LIST_UPDATED -and "**Updated dependencies:** $env:LIST_UPDATED" -or "**Updated dependencies:** " - '' - '> Please review and merge the pull request to apply the updates.' - ) - $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY + $summary = @" + ### ๐ŸŽ‰ Pull Request Created + + A pull request has been created to update the vendor dependencies. + + **Branch:** ``update-vendor`` + + **Updated dependencies:** $env:LIST_UPDATED + + > Please review and merge the pull request to apply the updates. + "@ + + $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8 diff --git a/.gitignore b/.gitignore index 71475ec9e..8edad6f19 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,10 @@ launcher/src/version.rc2 .vs/* .vscode .idea +.vagrant/ +scripts/packer/iso/*.iso +!scripts/packer/floppy/*.exe +scripts/packer/packer_cache +scripts/packer/output-* +*.box +*.code-workspace diff --git a/CHANGELOG.md b/CHANGELOG.md index eca18db4c..517d20ce1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,33 @@ # Change Log +## [2.0.0-rc.1](https://github.com/cmderdev/cmder/tree/v2.0.0-rc.1) (2026-02-21) + +> [!IMPORTANT] +> Pre-built packages that include Conemu are no longer included. + +### Fixes + +- Improve `lib_path.cmd` path enhancement handling. +- Fix launcher overwrite/backup behavior for emulator settings. +- Add `.git-blame-ignore-revs` entries for whitespace-only changes. +- Fixes #2940 + +### Changes + +- Refresh vendored sources and defaults via `sources.json` updates. +- Update build/pack scripts and GitHub Actions workflows. + +### Adds + +- Add Pacman support to Git for Windows. +- Add Windows Terminal integration (defaults, packaging, and launch helpers). +- Cmder for Windows + - Uses Windows and Git for Windows Native Terminals. + - Does not contain a terminal emulator like ConEmu or Windows Terminal. +- Add Git Bash/Mintty launch helpers and user init template. +- Add `create-cmdercfg.ps1` and `timer.cmd` helpers. +- Add `.git-blame-ignore-revs` entries for whitespace-only changes. + ## [1.3.25](https://github.com/cmderdev/cmder/tree/v1.3.25) (2024-05-31) ### Changes @@ -35,7 +63,7 @@ ### Changes -- Handle Clink injction differently in `init.bat`. +- Handle Clink injection differently in `init.bat`. - Changes to `clink_settings.lua.default`. - Do not add commands to Clink Command Line History that begin with whitespace as a default. - This can be changed to the old behavior by setting `history_ignore_space` to `0` in `config\clink_settings.lua`. diff --git a/Cmder.bat b/Cmder.bat index d48b0eefb..423b2c8d6 100644 --- a/Cmder.bat +++ b/Cmder.bat @@ -1,20 +1,66 @@ @echo off + SET CMDER_ROOT=%~dp0 -:: Remove Trailing '\' -@if "%CMDER_ROOT:~-1%" == "\" SET CMDER_ROOT=%CMDER_ROOT:~0,-1% - -if not exist "%CMDER_ROOT%\config\user_ConEmu.xml" ( - if not exist "%CMDER_ROOT%\config" mkdir "%CMDER_ROOT%\config" 2>nul - copy "%CMDER_ROOT%\vendor\ConEmu.xml.default" "%CMDER_ROOT%\config\user_ConEmu.xml" 1>nul - if %errorlevel% neq 0 ( - echo ERROR: CMDER Initialization has Failed - exit /b 1 - ) +set CMDER_TERMINAL=conemu +if exist "%CMDER_ROOT%\vendor\windows-terminal\windowsterminal.exe" ( + SET CMDER_TERMINAL=windows-terminal ) -if exist "%~1" ( - start %~dp0/vendor/conemu-maximus5/ConEmu.exe /Icon "%CMDER_ROOT%\icons\cmder.ico" /Title Cmder /LoadCfgFile "%~1" -) else ( - start %~dp0/vendor/conemu-maximus5/ConEmu.exe /Icon "%CMDER_ROOT%\icons\cmder.ico" /Title Cmder /LoadCfgFile "%CMDER_ROOT%\config\user_ConEmu.xml" +if NOT "%~1" == "" ( + SET CMDER_TERMINAL=%~1 + shift ) + +:: Remove Trailing '\' +if "%CMDER_ROOT:~-1%" == "\" SET CMDER_ROOT=%CMDER_ROOT:~0,-1% + +if not exist "%CMDER_ROOT%\config" md "%CMDER_ROOT%\config" 2>nul + +call :%CMDER_TERMINAL% +exit /b + +:conemu + if not exist "%CMDER_ROOT%\config\user_ConEmu.xml" ( + copy "%CMDER_ROOT%\vendor\ConEmu.xml.default" "%CMDER_ROOT%\config\user_ConEmu.xml" 1>nul + if %errorlevel% neq 0 ( + echo ERROR: CMDER Initialization has Failed + exit /b 1 + ) + ) + + if exist "%~1" ( + start %cmder_root%\vendor\conemu-maximus5\ConEmu.exe /Icon "%CMDER_ROOT%\icons\cmder.ico" /Title Cmder /LoadCfgFile "%~1" + ) else ( + start %cmder_root%\vendor\conemu-maximus5\ConEmu.exe /Icon "%CMDER_ROOT%\icons\cmder.ico" /Title Cmder /LoadCfgFile "%CMDER_ROOT%\config\user_ConEmu.xml" + ) + exit /b + +:windows-terminal + if not exist "%CMDER_ROOT%\vendor\windows-terminal\settings" md "%CMDER_ROOT%\vendor\windows-terminal\settings" 2>nul + if not exist "%CMDER_ROOT%\vendor\windows-terminal\.portable" echo "This makes this installation of Windows Terminal portable" >"%CMDER_ROOT%\vendor\windows-terminal\.portable" 2>nul + + if exist "%CMDER_ROOT%\config\user_windows_terminal_settings.json" ( + if not exist "%CMDER_ROOT%\vendor\windows-terminal\settings\settings.json" ( + echo "Copying user Windows Terminal settings to '%CMDER_ROOT%\vendor\windows-terminal\settings\settings.json'..." + copy "%CMDER_ROOT%\config\user_windows_terminal_settings.json" "%CMDER_ROOT%\vendor\windows-terminal\settings\settings.json" 1>nul + ) + ) else if not exist "%CMDER_ROOT%\config\user_windows_terminal_settings.json" ( + if not exist "%CMDER_ROOT%\config" mkdir "%CMDER_ROOT%\config" 2>nul + echo "Copying default Windows Terminal settings to '%CMDER_ROOT%\config'..." + copy "%CMDER_ROOT%\vendor\windows_terminal_default_settings.json" "%CMDER_ROOT%\config\user_windows_terminal_settings.json" 1>nul + echo "Copying default Windows Terminal settings to '%CMDER_ROOT%\vendor\windows-terminal\settings\settings.json'..." + copy "%CMDER_ROOT%\vendor\windows_terminal_default_settings.json" "%CMDER_ROOT%\vendor\windows-terminal\settings\settings.json" 1>nul + + if %errorlevel% neq 0 ( + echo ERROR: CMDER Initialization has Failed + exit /b 1 + ) + ) else if exist "%cmder_root%\vendor\windows-terminal\settings\settings.json" ( + copy "%cmder_root%\vendor\windows-terminal\settings\settings.json" "%CMDER_ROOT%\config\user_windows_terminal_settings.json" + ) + + start %cmder_root%\vendor\windows-terminal\windowsterminal.exe + exit /b + + diff --git a/README.md b/README.md index 661ba396e..7b8364a40 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ The Cmder's user interface is also designed to be more eye pleasing, and you can | `/SINGLE` | Start Cmder in single mode. | | `/START [start_path]` | Folder path to start in. | | `/TASK [task_name]` | Task to start after launch. | -| `/X [ConEmu extras pars]` | Forwards parameters to ConEmu | +| `-- [ConEmu extras pars]` | Forwards ALL remaining parameters to ConEmu. | ## Context Menu Integration diff --git a/config/Readme.md b/config/Readme.md index c8befd282..4729de95f 100644 --- a/config/Readme.md +++ b/config/Readme.md @@ -1,6 +1,6 @@ ## Config -All config files must be in this folder. If there is no option to set this folder +All config files must be in this folder. If there is no option to set this folder directly, it has to be hardlinked. * `user_aliases.cmd`: aliases in cmd; called from vendor\init.bat; autocreated from diff --git a/launcher/CmderLauncher.vcxproj b/launcher/CmderLauncher.vcxproj index 2662957c9..6d49ed943 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 3fe20c575..90ba93cf9 100644 --- a/launcher/src/CmderLauncher.cpp +++ b/launcher/src/CmderLauncher.cpp @@ -107,9 +107,9 @@ bool FileExists(const wchar_t * filePath) 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 }; @@ -117,7 +117,7 @@ void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstr wchar_t cpuCfgPath[MAX_PATH] = { 0 }; wchar_t userCfgPath[MAX_PATH] = { 0 }; wchar_t defaultCfgPath[MAX_PATH] = { 0 }; - wchar_t conEmuPath[MAX_PATH] = { 0 }; + wchar_t terminalPath[MAX_PATH] = { 0 }; wchar_t configDirPath[MAX_PATH] = { 0 }; wchar_t userConfigDirPath[MAX_PATH] = { 0 }; wchar_t userBinDirPath[MAX_PATH] = { 0 }; @@ -128,21 +128,34 @@ void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstr wchar_t legacyUserAliasesPath[MAX_PATH] = { 0 }; wchar_t args[MAX_PATH * 2 + 256] = { 0 }; wchar_t userConEmuCfgPath[MAX_PATH] = { 0 }; - + wchar_t windowsTerminalDir[MAX_PATH] = { 0 }; + wchar_t conEmuDir[MAX_PATH] = { 0 }; + wchar_t winDir[MAX_PATH] = { 0 }; + wchar_t vendorDir[MAX_PATH] = { 0 }; + wchar_t initCmd[MAX_PATH] = { 0 }; + wchar_t initPowerShell[MAX_PATH] = { 0 }; + wchar_t initBash[MAX_PATH] = { 0 }; + wchar_t initMintty[MAX_PATH] = { 0 }; + wchar_t vendoredGit[MAX_PATH] = { 0 }; + wchar_t amdx64Git[MAX_PATH] = { 0 }; + wchar_t x86Git[MAX_PATH] = { 0 }; + wchar_t programFiles[MAX_PATH] = { 0 }; + wchar_t programFilesX86[MAX_PATH] = { 0 }; + wchar_t minTTYPath[MAX_PATH] = { 0 }; std::wstring cmderStart = path; std::wstring cmderTask = taskName; std::wstring cmderTitle = title; - std::wstring cmderConEmuArgs = conemu_args; + std::wstring cmderTerminalArgs = conemu_args; std::copy(cfgRoot.begin(), cfgRoot.end(), userConfigDirPath); userConfigDirPath[cfgRoot.length()] = 0; 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); @@ -166,8 +179,8 @@ void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstr { PathCombine(userProfilePath, configDirPath, L"user_profile.cmd"); - char *lPr = (char *)malloc(MAX_PATH); - char *pR = (char *)malloc(MAX_PATH); + char* lPr = (char*)malloc(MAX_PATH); + char* pR = (char*)malloc(MAX_PATH); size_t i; wcstombs_s(&i, lPr, (size_t)MAX_PATH, legacyUserProfilePath, (size_t)MAX_PATH); @@ -184,8 +197,8 @@ void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstr { PathCombine(userAliasesPath, configDirPath, L"user_aliases.cmd"); - char *lPr = (char *)malloc(MAX_PATH); - char *pR = (char *)malloc(MAX_PATH); + char* lPr = (char*)malloc(MAX_PATH); + char* pR = (char*)malloc(MAX_PATH); size_t i; wcstombs_s(&i, lPr, (size_t)MAX_PATH, legacyUserAliasesPath, (size_t)MAX_PATH); @@ -222,8 +235,8 @@ void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstr { PathCombine(userProfilePath, userConfigDirPath, L"user_profile.cmd"); - char *lPr = (char *)malloc(MAX_PATH); - char *pR = (char *)malloc(MAX_PATH); + char* lPr = (char*)malloc(MAX_PATH); + char* pR = (char*)malloc(MAX_PATH); size_t i; wcstombs_s(&i, lPr, (size_t)MAX_PATH, legacyUserProfilePath, (size_t)MAX_PATH); @@ -240,8 +253,8 @@ void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstr { PathCombine(userAliasesPath, userConfigDirPath, L"user_aliases.cmd"); - char *lPr = (char *)malloc(MAX_PATH); - char *pR = (char *)malloc(MAX_PATH); + char* lPr = (char*)malloc(MAX_PATH); + char* pR = (char*)malloc(MAX_PATH); size_t i; wcstombs_s(&i, lPr, (size_t)MAX_PATH, legacyUserAliasesPath, (size_t)MAX_PATH); @@ -251,71 +264,158 @@ void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstr } } - // Set path to vendored ConEmu config file - PathCombine(cfgPath, exeDir, L"vendor\\conemu-maximus5\\ConEmu.xml"); + PathCombine(vendorDir, exeDir, L"vendor"); + PathCombine(windowsTerminalDir, vendorDir, L"windows-terminal"); + PathCombine(conEmuDir, vendorDir, L"conemu-maximus5"); + GetEnvironmentVariable(L"WINDIR", winDir, MAX_PATH); - // Set path to Cmder default ConEmu config file - PathCombine(defaultCfgPath, exeDir, L"vendor\\ConEmu.xml.default"); + if (PathFileExists(windowsTerminalDir)) + { + // Set path to vendored ConEmu config file + PathCombine(cfgPath, windowsTerminalDir, L"settings\\settings.json"); - // Check for machine-specific then user config source file. - PathCombine(cpuCfgPath, userConfigDirPath, L"ConEmu-%COMPUTERNAME%.xml"); - ExpandEnvironmentStrings(cpuCfgPath, cpuCfgPath, sizeof(cpuCfgPath) / sizeof(cpuCfgPath[0])); + // Set path to Cmder default ConEmu config file + PathCombine(defaultCfgPath, exeDir, L"vendor\\windows_terminal_default_settings.json"); - // Set path to Cmder user ConEmu config file - PathCombine(userCfgPath, userConfigDirPath, L"user-ConEmu.xml"); + // Check for machine-specific then user config source file. + PathCombine(cpuCfgPath, userConfigDirPath, L"windows_terminal_%COMPUTERNAME%_settings.json"); + ExpandEnvironmentStrings(cpuCfgPath, cpuCfgPath, sizeof(cpuCfgPath) / sizeof(cpuCfgPath[0])); - if ( PathFileExists(cpuCfgPath) || use_user_cfg == false ) // config/ConEmu-%COMPUTERNAME%.xml file exists or /m was specified on command line, use machine specific config. + // Set path to Cmder user ConEmu config file + PathCombine(userCfgPath, userConfigDirPath, L"user_windows_terminal_settings.json"); + } + else if (PathFileExists(conEmuDir)) + { + // Set path to vendored ConEmu config file + PathCombine(cfgPath, conEmuDir, L"ConEmu.xml"); + + // Set path to Cmder default ConEmu config file + PathCombine(defaultCfgPath, exeDir, L"vendor\\ConEmu.xml.default"); + + // Check for machine-specific then user config source file. + PathCombine(cpuCfgPath, userConfigDirPath, L"ConEmu-%COMPUTERNAME%.xml"); + ExpandEnvironmentStrings(cpuCfgPath, cpuCfgPath, sizeof(cpuCfgPath) / sizeof(cpuCfgPath[0])); + + // Set path to Cmder user ConEmu config file + PathCombine(userCfgPath, userConfigDirPath, L"user-ConEmu.xml"); + } + + if (wcscmp(cpuCfgPath, L"") != 0 && (PathFileExists(cpuCfgPath) || use_user_cfg == false)) // config/[host specific terminal emulator config] file exists or /m was specified on command line, use machine specific config. { if (cfgRoot.length() == 0) // '/c [path]' was NOT specified { - if (PathFileExists(cfgPath)) // vendor/conemu-maximus5/ConEmu.xml file exists, copy vendor/conemu-maximus5/ConEmu.xml to config/ConEmu-%COMPUTERNAME%.xml. + if (PathFileExists(cfgPath)) // [terminal emulator config] file exists, copy [terminal emulator config] to config/user_[terminal emulator config] file to backup any settings changes from previous sessions. { if (!CopyFile(cfgPath, cpuCfgPath, FALSE)) { - MessageBox(NULL, - (GetLastError() == ERROR_ACCESS_DENIED) - ? L"Failed to copy vendor/conemu-maximus5/ConEmu.xml file to config/ConEmu-%COMPUTERNAME%.xml! Access Denied." - : L"Failed to copy vendor/conemu-maximus5/ConEmu.xml file to config/ConEmu-%COMPUTERNAME%.xml!", MB_TITLE, MB_ICONSTOP); - exit(1); + if (PathFileExists(windowsTerminalDir)) { + 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_terminal_%COMPUTERNAME%_settigns.json!", MB_TITLE, MB_ICONSTOP); + exit(1); + } + else if (PathFileExists(conEmuDir)) + { + MessageBox(NULL, + (GetLastError() == ERROR_ACCESS_DENIED) + ? L"Failed to copy vendor/conemu-maximus5/ConEmu.xml file to config/ConEmu-%COMPUTERNAME%.xml! Access Denied." + : L"Failed to copy vendor/conemu-maximus5/ConEmu.xml file to config/ConEmu-%COMPUTERNAME%.xml!", MB_TITLE, MB_ICONSTOP); + exit(1); + } } } - else // vendor/conemu-maximus5/ConEmu.xml config file does not exist, copy config/ConEmu-%COMPUTERNAME%.xml to vendor/conemu-maximus5/ConEmu.xml file + else // [terminal emulator config] file does not exist, copy config/[host specific terminal emulator config] file to [terminal emulator config] file { if (!CopyFile(cpuCfgPath, cfgPath, FALSE)) { - MessageBox(NULL, - (GetLastError() == ERROR_ACCESS_DENIED) - ? L"Failed to copy config/ConEmu-%COMPUTERNAME%.xml file to vendor/conemu-maximus5/ConEmu.xml! Access Denied." - : L"Failed to copy config/ConEmu-%COMPUTERNAME%.xml file to vendor/conemu-maximus5/ConEmu.xml!", MB_TITLE, MB_ICONSTOP); - exit(1); + 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." + : L"Failed to copy config/windows_terminal_%COMPUTERNAME%_settings.json file to vendor/windows-terminal/settings/settings.json!", MB_TITLE, MB_ICONSTOP); + exit(1); + } + else if (PathFileExists(conEmuDir)) + { + MessageBox(NULL, + (GetLastError() == ERROR_ACCESS_DENIED) + ? L"Failed to copy config/ConEmu-%COMPUTERNAME%.xml file to vendor/conemu-maximus5/ConEmu.xml! Access Denied." + : L"Failed to copy config/ConEmu-%COMPUTERNAME%.xml file to vendor/conemu-maximus5/ConEmu.xml!", MB_TITLE, MB_ICONSTOP); + exit(1); + } } } } - else // '/c [path]' was specified, don't copy anything and use existing conemu-%COMPUTERNAME%.xml to start comemu. + } + else if (wcscmp(userCfgPath, L"") != 0 && PathFileExists(userCfgPath)) // config/user[terminal emulator config] file exists, use it. + { + if (cfgRoot.length() == 0) // '/c [path]' was NOT specified { - if (use_user_cfg == false && PathFileExists(cfgPath) && !PathFileExists(cpuCfgPath)) // vendor/conemu-maximus5/ConEmu.xml file exists, copy vendor/conemu-maximus5/ConEmu.xml to config/ConEmu-%COMPUTERNAME%.xml. + if (PathFileExists(cfgPath)) // [terminal emulator config] file exists, copy [terminal emulator config] to config/user_[terminal emulator config] file to backup any settings changes from previous sessions. { - if (!CopyFile(cfgPath, cpuCfgPath, FALSE)) + if (!CopyFile(cfgPath, userCfgPath, FALSE)) { - MessageBox(NULL, - (GetLastError() == ERROR_ACCESS_DENIED) - ? L"Failed to copy vendor/conemu-maximus5/ConEmu.xml file to config/ConEmu-%COMPUTERNAME%.xml! Access Denied." - : L"Failed to copy vendor/conemu-maximus5/ConEmu.xml file to config/ConEmu-%COMPUTERNAME%.xml!", MB_TITLE, MB_ICONSTOP); - exit(1); + if (PathFileExists(windowsTerminalDir)) + { + 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_terminal_settigns.json!", MB_TITLE, MB_ICONSTOP); + exit(1); + } + else if (PathFileExists(conEmuDir)) + { + MessageBox(NULL, + (GetLastError() == ERROR_ACCESS_DENIED) + ? L"Failed to copy vendor/conemu-maximus5/ConEmu.xml file to config/user-conemu.xml! Access Denied." + : L"Failed to copy vendor/conemu-maximus5/ConEmu.xml file to config/user-conemu.xml!", MB_TITLE, MB_ICONSTOP); + exit(1); + } } } - - PathCombine(userConEmuCfgPath, userConfigDirPath, L"ConEmu-%COMPUTERNAME%.xml"); - ExpandEnvironmentStrings(userConEmuCfgPath, userConEmuCfgPath, sizeof(userConEmuCfgPath) / sizeof(userConEmuCfgPath[0])); + else // [terminal emulator config] file does not exist, copy config/user_[terminal emulator config] file to [terminal emulator config] file + { + if (!CopyFile(userCfgPath, cfgPath, FALSE)) + { + if (PathFileExists(windowsTerminalDir)) + { + MessageBox(NULL, + (GetLastError() == ERROR_ACCESS_DENIED) + ? L"Failed to copy config/user_windows_terminal_settings.json file to vendor/windows-terminal/settings/settings.json! Access Denied." + : L"Failed to copy config/user_windows_terminal_settings.json file to vendor/windows-terminal/settings/settings.json!", MB_TITLE, MB_ICONSTOP); + exit(1); + } + else if (PathFileExists(conEmuDir)) + { + MessageBox(NULL, + (GetLastError() == ERROR_ACCESS_DENIED) + ? L"Failed to copy config/user-conemu.xml file to vendor/conemu-maximus5/ConEmu.xml! Access Denied." + : L"Failed to copy config/user-conemu.xml file to vendor/conemu-maximus5/ConEmu.xml!", MB_TITLE, MB_ICONSTOP); + exit(1); + } + } + } + } + else if (!PathFileExists(windowsTerminalDir)) { // '/c [path]' was specified, don't copy anything and use existing user_[terminal emulator config] file. + PathCombine(userConEmuCfgPath, userConfigDirPath, L"user-ConEmu.xml"); } } - else if (PathFileExists(userCfgPath)) // config/user_conemu.xml exists, use it. + else if (cfgRoot.length() == 0) // '/c [path]' was NOT specified { - if (cfgRoot.length() == 0) // '/c [path]' was NOT specified + if (PathFileExists(cfgPath)) // [terminal emulator config] file exists, copy [terminal emulator config] file to config/user_[terminal emulator config] file. { - if (PathFileExists(cfgPath)) // vendor/conemu-maximus5/ConEmu.xml exists, copy vendor/conemu-maximus5/ConEmu.xml to config/user_conemu.xml. + if (!CopyFile(cfgPath, userCfgPath, FALSE)) { - if (!CopyFile(cfgPath, userCfgPath, FALSE)) + if (PathFileExists(windowsTerminalDir)) + { + MessageBox(NULL, + (GetLastError() == ERROR_ACCESS_DENIED) + ? L"Failed to copy vendor/windows-terminal/settings/settings.json file to config/user_windows_terminal_settings.json! Access Denied." + : L"Failed to copy vendor/windows-terminal/settings/settings.json file to config/user_windows_terminal_settigns.json!", MB_TITLE, MB_ICONSTOP); + exit(1); + } + else if (PathFileExists(conEmuDir)) { MessageBox(NULL, (GetLastError() == ERROR_ACCESS_DENIED) @@ -324,128 +424,198 @@ void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstr exit(1); } } - else // vendor/conemu-maximus5/ConEmu.xml does not exist, copy config/user-conemu.xml to vendor/conemu-maximus5/ConEmu.xml + else // vendor/[terminal emulator config].default config exists, copy Cmder vendor/[terminal emulator config].default file to [terminal emulator config] file. { - if (!CopyFile(userCfgPath, cfgPath, FALSE)) + if (!CopyFile(defaultCfgPath, cfgPath, FALSE)) { - MessageBox(NULL, - (GetLastError() == ERROR_ACCESS_DENIED) - ? L"Failed to copy config/user-conemu.xml file to vendor/conemu-maximus5/ConEmu.xml! Access Denied." - : L"Failed to copy config/user-conemu.xml file to vendor/conemu-maximus5/ConEmu.xml!", MB_TITLE, MB_ICONSTOP); - exit(1); + if (PathFileExists(windowsTerminalDir)) + { + MessageBox(NULL, + (GetLastError() == ERROR_ACCESS_DENIED) + ? L"Failed to copy vendor/windows-terminal_default_settings_settings.json file to vendor/windows-terminal/settings/settings.json! Access Denied." + : L"Failed to copy vendor/windows-terminal_default_settings_settings.json file to vendor/windows-terminal/settings/settigns.json!", MB_TITLE, MB_ICONSTOP); + exit(1); + } + else if (PathFileExists(conEmuDir)) + { + MessageBox(NULL, + (GetLastError() == ERROR_ACCESS_DENIED) + ? L"Failed to copy vendor/ConEmu.xml.default file to vendor/conemu-maximus5/ConEmu.xml! Access Denied." + : L"Failed to copy vendor/ConEmu.xml.default file to vendor/conemu-maximus5/ConEmu.xml!", MB_TITLE, MB_ICONSTOP); + exit(1); + } } } } - else // '/c [path]' was specified, don't copy anything and use existing user_conemu.xml to start comemu. + else if (!CopyFile(defaultCfgPath, cfgPath, FALSE) && PathFileExists(conEmuDir)) { - PathCombine(userConEmuCfgPath, userConfigDirPath, L"user-ConEmu.xml"); + MessageBox(NULL, + (GetLastError() == ERROR_ACCESS_DENIED) + ? L"Failed to copy vendor/ConEmu.xml.default file to vendor/conemu-maximus5/ConEmu.xml! Access Denied." + : L"Failed to copy vendor/ConEmu.xml.default file to vendor/conemu-maximus5/ConEmu.xml!", MB_TITLE, MB_ICONSTOP); + exit(1); } } - else if (cfgRoot.length() == 0) // '/c [path]' was NOT specified + else if (wcscmp(cfgPath, L"") != 0 && PathFileExists(cfgPath)) // This is a first time Cmder.exe run and [terminal emulator config] file exists, copy [terminal emulator config] file to config/user_[terminal emulator config] file. { - if (PathFileExists(cfgPath)) // vendor/conemu-maximus5/ConEmu.xml exists, copy vendor/conemu-maximus5/ConEmu.xml to config/user_conemu.xml + if (!CopyFile(cfgPath, userCfgPath, FALSE)) { - if (!CopyFile(cfgPath, userCfgPath, FALSE)) + if (PathFileExists(windowsTerminalDir)) { MessageBox(NULL, (GetLastError() == ERROR_ACCESS_DENIED) - ? L"Failed to copy vendor/conemu-maximus5/ConEmu.xml file to config/user-conemu.xml! Access Denied." - : L"Failed to copy vendor/conemu-maximus5/ConEmu.xml file to config/user-conemu.xml!", MB_TITLE, MB_ICONSTOP); + ? L"Failed to copy vendor/windows-terminal/settings/settings.json file to config/user_windows_terminal_settings_settings.json! Access Denied." + : L"Failed to copy vendor/windows-terminal/settings/settings.json file to config/user_windows_terminal_settings_settigns.json!", MB_TITLE, MB_ICONSTOP); exit(1); } - else // vendor/ConEmu.xml.default config exists, copy Cmder vendor/ConEmu.xml.default file to vendor/conemu-maximus5/ConEmu.xml. - { - if (!CopyFile(defaultCfgPath, cfgPath, FALSE)) - { - MessageBox(NULL, - (GetLastError() == ERROR_ACCESS_DENIED) - ? L"Failed to copy vendor/ConEmu.xml.default file to vendor/conemu-maximus5/ConEmu.xml! Access Denied." - : L"Failed to copy vendor/ConEmu.xml.default file to vendor/conemu-maximus5/ConEmu.xml!", MB_TITLE, MB_ICONSTOP); - exit(1); - } - } - } - else { - if (!CopyFile(defaultCfgPath, cfgPath, FALSE)) + else { MessageBox(NULL, (GetLastError() == ERROR_ACCESS_DENIED) - ? L"Failed to copy vendor/ConEmu.xml.default file to vendor/conemu-maximus5/ConEmu.xml! Access Denied." - : L"Failed to copy vendor/ConEmu.xml.default file to vendor/conemu-maximus5/ConEmu.xml!", MB_TITLE, MB_ICONSTOP); + ? L"Failed to copy vendor/conemu-maximus5/ConEmu.xml file to config/user-conemu.xml! Access Denied." + : L"Failed to copy vendor/conemu-maximus5/ConEmu.xml file to config/user-conemu.xml!", MB_TITLE, MB_ICONSTOP); exit(1); } } - } - else if (PathFileExists(cfgPath)) // vendor/conemu-maximus5/ConEmu.xml exists, copy vendor/conemu-maximus5/ConEmu.xml to config/user_conemu.xml - { - if (!CopyFile(cfgPath, userCfgPath, FALSE)) - { - MessageBox(NULL, - (GetLastError() == ERROR_ACCESS_DENIED) - ? L"Failed to copy vendor/conemu-maximus5/ConEmu.xml file to config/user-conemu.xml! Access Denied." - : L"Failed to copy vendor/conemu-maximus5/ConEmu.xml file to config/user-conemu.xml!", MB_TITLE, MB_ICONSTOP); - exit(1); - } PathCombine(userConEmuCfgPath, userConfigDirPath, L"user-ConEmu.xml"); } - else // '/c [path]' was specified and 'vendor/ConEmu.xml.default' config exists, copy Cmder 'vendor/ConEmu.xml.default' file to '[user specified path]/config/user_ConEmu.xml'. + else if (wcscmp(defaultCfgPath, L"") != 0) // '/c [path]' was specified and 'vendor/[terminal emulator config].default' config exists, copy Cmder 'vendor/[terminal emulator config].default' file to '[user specified path]/config/user_[terminal emulator config]'. { if ( ! CopyFile(defaultCfgPath, userCfgPath, FALSE)) { - MessageBox(NULL, - (GetLastError() == ERROR_ACCESS_DENIED) - ? L"Failed to copy vendor/ConEmu.xml.default file to [user specified path]/config/user_ConEmu.xml! Access Denied." - : L"Failed to copy vendor/ConEmu.xml.default file to [user specified path]/config/user_ConEmu.xml!", MB_TITLE, MB_ICONSTOP); - exit(1); + if (PathFileExists(windowsTerminalDir)) + { + MessageBox(NULL, + (GetLastError() == ERROR_ACCESS_DENIED) + ? L"Failed to copy vendor/windows-terminal_default_settings_settings.json file to [user specified path]/config/user_windows_terminal_settings.json! Access Denied." + : L"Failed to copy vendor/windows-terminal_default_settings_settings.json file to [user specified path]/config/user_windows_terminal_settings.json!", MB_TITLE, MB_ICONSTOP); + exit(1); + } + else + { + MessageBox(NULL, + (GetLastError() == ERROR_ACCESS_DENIED) + ? L"Failed to copy vendor/ConEmu.xml.default file to [user specified path]/config/user_ConEmu.xml! Access Denied." + : L"Failed to copy vendor/ConEmu.xml.default file to [user specified path]/config/user_ConEmu.xml!", MB_TITLE, MB_ICONSTOP); + exit(1); + } } PathCombine(userConEmuCfgPath, userConfigDirPath, L"user-ConEmu.xml"); } + GetEnvironmentVariable(L"ProgramFiles", programFiles, MAX_PATH); + GetEnvironmentVariable(L"ProgramFiles(x86)", programFilesX86, MAX_PATH); + + PathCombine(vendoredGit, vendorDir, L"git-for-windows"); + PathCombine(amdx64Git, programFiles, L"Git"); + PathCombine(x86Git, programFilesX86, L"Git"); + SYSTEM_INFO sysInfo; GetNativeSystemInfo(&sysInfo); - if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) + if (PathFileExists(windowsTerminalDir)) { - PathCombine(conEmuPath, exeDir, L"vendor\\conemu-maximus5\\ConEmu64.exe"); + PathCombine(terminalPath, exeDir, L"vendor\\windows-terminal\\WindowsTerminal.exe"); } - else + else if (PathFileExists(conEmuDir)) { - PathCombine(conEmuPath, exeDir, L"vendor\\conemu-maximus5\\ConEmu.exe"); + swprintf_s(args, L"%s /Icon \"%s\"", args, icoPath); + swprintf_s(args, L"%s /title \"%s\"", args, cmderTitle.c_str()); + PathCombine(terminalPath, exeDir, L"vendor\\conemu-maximus5\\ConEmu64.exe"); } + else + { + PathCombine(terminalPath, winDir, L"system32\\cmd.exe"); - swprintf_s(args, L"%s /Icon \"%s\"", args, icoPath); + if (streqi(cmderTask.c_str(), L"powershell")) + { + PathCombine(terminalPath, winDir, L"System32\\WindowsPowerShell\\v1.0\\powershell.exe"); + } + /* + else if (streqi(cmderTask.c_str(), L"mintty")) + { + if (PathFileExists(vendoredGit)) + { + PathCombine(terminalPath, vendoredGit, L"git-bash.exe"); + } + else if (PathFileExists(amdx64Git)) + { + PathCombine(terminalPath, amdx64Git, L"git-bash.exe"); + } + else if (PathFileExists(x86Git)) + { + PathCombine(terminalPath, x86Git, L"git-bash.exe"); + } + } + */ + } if (!streqi(cmderStart.c_str(), L"")) { - swprintf_s(args, L"%s /dir \"%s\"", args, cmderStart.c_str()); + if (PathFileExists(windowsTerminalDir)) { + swprintf_s(args, L"%s -d \"%s\"", args, cmderStart.c_str()); + } + else + { + swprintf_s(args, L"%s /dir \"%s\"", args, cmderStart.c_str()); + } } if (is_single_mode) { - swprintf_s(args, L"%s /single", args); - } - - if (!streqi(cmderTitle.c_str(), L"")) - { - swprintf_s(args, L"%s /title \"%s\"", args, cmderTitle.c_str()); + if (!PathFileExists(windowsTerminalDir)) { + swprintf_s(args, L"%s /single", args); + } } if (cfgRoot.length() != 0) { - swprintf_s(args, L"%s -loadcfgfile \"%s\"", args, userConEmuCfgPath); + if (!PathFileExists(windowsTerminalDir)) { + swprintf_s(args, L"%s -loadcfgfile \"%s\"", args, userConEmuCfgPath); + } } - if (!streqi(cmderConEmuArgs.c_str(), L"")) + if (!streqi(cmderTerminalArgs.c_str(), L"")) { - swprintf_s(args, L"%s %s", args, cmderConEmuArgs.c_str()); + swprintf_s(args, L"%s %s", args, cmderTerminalArgs.c_str()); } // The `/run` arg and its value MUST be the last arg of ConEmu // see : https://conemu.github.io/en/ConEmuArgs.html // > This must be the last used switch (excepting -new_console and -cur_console) + PathCombine(initCmd, vendorDir, L"init.bat"); + PathCombine(initPowerShell, vendorDir, L"profile.ps1"); + PathCombine(initBash, vendorDir, L"start_git_bash.cmd"); + PathCombine(initMintty, vendorDir, L"start_git_mintty.cmd"); + if (!streqi(cmderTask.c_str(), L"")) { - swprintf_s(args, L"%s /run {%s}", args, cmderTask.c_str()); + if (PathFileExists(windowsTerminalDir)) { + swprintf_s(args, L"%s -p \"%s\"", args, cmderTask.c_str()); + } + else if (PathFileExists(conEmuDir)) + { + swprintf_s(args, L"%s /run {%s}", args, cmderTask.c_str()); + } + else + { + if (streqi(cmderTask.c_str(), L"powershell")) + { + swprintf_s(args, L"%s -ExecutionPolicy Bypass -NoLogo -NoProfile -NoExit -Command \"Invoke-Expression 'Import-Module ''%s'''\"", args, initPowerShell); + } + else if (streqi(cmderTask.c_str(), L"bash")) + { + swprintf_s(args, L"%s /c \"%s\"", args, initBash); + } + else if (streqi(cmderTask.c_str(), L"mintty")) + { + swprintf_s(args, L"%s /c \"%s\"", args, initMintty); + } + else if (streqi(cmderTask.c_str(), L"cmder")) + { + swprintf_s(args, L"%s /k \"%s\"", args, initCmd); + } + } } SetEnvironmentVariable(L"CMDER_ROOT", exeDir); @@ -455,18 +625,52 @@ void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstr SetEnvironmentVariable(L"CMDER_USER_BIN", userBinDirPath); } + // Try to find m'intty.exe' so ConEmu can launch using %MINTTY_EXE% in external Git for Cmder Mini. + // See: https://github.com/Maximus5/ConEmu/issues/2559 for why this is commented. + + /* + if (PathFileExists(vendoredGit)) + { + PathCombine(minTTYPath, vendoredGit, L"usr\\bin\\mintty.exe"); + SetEnvironmentVariable(L"MINTTY_EXE", minTTYPath); + } + else if (PathFileExists(amdx64Git)) + { + PathCombine(minTTYPath, amdx64Git, L"usr\\bin\\mintty.exe"); + SetEnvironmentVariable(L"MINTTY_EXE", minTTYPath); + } + else if (PathFileExists(x86Git)) + { + PathCombine(minTTYPath, x86Git, L"usr\\bin\\mintty.exe"); + SetEnvironmentVariable(L"MINTTY_EXE", minTTYPath); + } + */ + // Ensure EnvironmentVariables are propagated. 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; - if (!CreateProcess(conEmuPath, args, NULL, NULL, false, 0, NULL, NULL, &si, &pi)) { - MessageBox(NULL, _T("Unable to create the ConEmu process!"), _T("Error"), MB_OK); + + if (!CreateProcess(terminalPath, args, NULL, NULL, false, 0, NULL, NULL, &si, &pi)) + { + if (PathFileExists(windowsTerminalDir)) + { + MessageBox(NULL, _T("Unable to create the Windows Terminal process!"), _T("Error"), MB_OK); + } + else if (PathFileExists(conEmuDir)) + { + MessageBox(NULL, _T("Unable to create the ConEmu process!"), _T("Error"), MB_OK); + } + else + { + MessageBox(NULL, _T("Unable to create the Cmd process!"), _T("Error"), MB_OK); + } return; } } @@ -521,11 +725,11 @@ void RegisterShellMenu(std::wstring opt, wchar_t* keyBaseName, std::wstring cfgR wchar_t commandStr[MAX_PATH + 20] = { 0 }; wchar_t baseCommandStr[MAX_PATH + 20] = { 0 }; - if (!single) { - swprintf_s(baseCommandStr, L"\"%s\"", exePath); + if (single) { + swprintf_s(baseCommandStr, L"\"%s\" /single", exePath); } else { - swprintf_s(baseCommandStr, L"\"%s\" /single", exePath); + swprintf_s(baseCommandStr, L"\"%s\"", exePath); } if (cfgRoot.length() == 0) // '/c [path]' was NOT specified @@ -583,7 +787,7 @@ struct cmderOptions std::wstring cmderTitle = L"Cmder"; std::wstring cmderIcon = L""; std::wstring cmderRegScope = L"USER"; - std::wstring cmderConEmuArgs = L""; + std::wstring cmderTerminalArgs = L""; bool cmderSingle = false; bool cmderUserCfg = true; bool registerApp = false; @@ -597,11 +801,22 @@ cmderOptions GetOption() LPWSTR *szArgList; int argCount; + wchar_t windowsTerminalDir[MAX_PATH] = { 0 }; + wchar_t conEmuDir[MAX_PATH] = { 0 }; + wchar_t vendorDir[MAX_PATH] = { 0 }; + wchar_t exeDir[MAX_PATH] = { 0 }; + + GetModuleFileName(NULL, exeDir, sizeof(exeDir)); + PathRemoveFileSpec(exeDir); + + PathCombine(vendorDir, exeDir, L"vendor"); + PathCombine(windowsTerminalDir, vendorDir, L"windows-terminal"); + PathCombine(conEmuDir, vendorDir, L"ConEmu-Maximus5"); + szArgList = CommandLineToArgvW(GetCommandLine(), &argCount); for (int i = 1; i < argCount; i++) { - // MessageBox(NULL, szArgList[i], L"Arglist contents", MB_OK); if (cmderOptions.error == false) { if (_wcsicmp(L"/c", szArgList[i]) == 0) @@ -638,26 +853,31 @@ cmderOptions GetOption() MessageBox(NULL, szArgList[i + 1], L"/START - Folder does not exist!", MB_OK); } } - else if (_wcsicmp(L"/task", szArgList[i]) == 0) + else if (_wcsicmp(L"/task", szArgList[i]) == 0 || PathFileExists(windowsTerminalDir) || PathFileExists(conEmuDir)) { cmderOptions.cmderTask = szArgList[i + 1]; i++; } - else if (_wcsicmp(L"/title", szArgList[i]) == 0) + else if ((_wcsicmp(L"bash", szArgList[i]) == 0 || _wcsicmp(L"powershell", szArgList[i]) == 0) || PathFileExists(windowsTerminalDir) || PathFileExists(conEmuDir)) + { + cmderOptions.cmderTask = szArgList[i]; + i++; + } + else if (_wcsicmp(L"/title", szArgList[i]) == 0 && !PathFileExists(windowsTerminalDir) && PathFileExists(conEmuDir)) { cmderOptions.cmderTitle = szArgList[i + 1]; i++; } - else if (_wcsicmp(L"/icon", szArgList[i]) == 0) + else if (_wcsicmp(L"/icon", szArgList[i]) == 0 && !PathFileExists(windowsTerminalDir) && PathFileExists(conEmuDir)) { cmderOptions.cmderIcon = szArgList[i + 1]; i++; } - else if (_wcsicmp(L"/single", szArgList[i]) == 0) + else if (_wcsicmp(L"/single", szArgList[i]) == 0 && !PathFileExists(windowsTerminalDir) && PathFileExists(conEmuDir)) { cmderOptions.cmderSingle = true; } - else if (_wcsicmp(L"/m", szArgList[i]) == 0) + else if (_wcsicmp(L"/m", szArgList[i]) == 0 && !PathFileExists(windowsTerminalDir) && PathFileExists(conEmuDir)) { cmderOptions.cmderUserCfg = false; } @@ -690,7 +910,7 @@ cmderOptions GetOption() /* Used for passing arguments to conemu prog */ else if (_wcsicmp(L"/x", szArgList[i]) == 0) { - cmderOptions.cmderConEmuArgs = szArgList[i + 1]; + cmderOptions.cmderTerminalArgs = szArgList[i + 1]; i++; } /* Bare double dash, remaining commandline is for conemu */ @@ -700,7 +920,7 @@ cmderOptions GetOption() auto doubledash = cmdline.find(L" -- "); if (doubledash != std::string::npos) { - cmderOptions.cmderConEmuArgs = cmdline.substr(doubledash + 4); + cmderOptions.cmderTerminalArgs = cmdline.substr(doubledash + 4); } break; } @@ -727,7 +947,11 @@ cmderOptions GetOption() cmderOptions.error = true; } } + } + if (!PathFileExists(windowsTerminalDir) && !PathFileExists(conEmuDir) && streqi(cmderOptions.cmderTask.c_str(), L"")) + { + cmderOptions.cmderTask = L"cmder"; } if (cmderOptions.error == true) @@ -756,12 +980,29 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, cmderOptions cmderOptions = GetOption(); + wchar_t windowsTerminalDir[MAX_PATH] = { 0 }; + wchar_t exeDir[MAX_PATH] = { 0 }; + + GetModuleFileName(NULL, exeDir, sizeof(exeDir)); + PathRemoveFileSpec(exeDir); + PathCombine(windowsTerminalDir, exeDir, L"vendor\\windows-terminal"); + if (cmderOptions.registerApp == true) { - RegisterShellMenu(cmderOptions.cmderRegScope, SHELL_MENU_REGISTRY_PATH_BACKGROUND, cmderOptions.cmderCfgRoot, cmderOptions.cmderSingle); - RegisterShellMenu(cmderOptions.cmderRegScope, SHELL_MENU_REGISTRY_PATH_LISTITEM, cmderOptions.cmderCfgRoot, cmderOptions.cmderSingle); - RegisterShellMenu(cmderOptions.cmderRegScope, SHELL_MENU_REGISTRY_DRIVE_PATH_BACKGROUND, cmderOptions.cmderCfgRoot, cmderOptions.cmderSingle); - RegisterShellMenu(cmderOptions.cmderRegScope, SHELL_MENU_REGISTRY_DRIVE_PATH_LISTITEM, cmderOptions.cmderCfgRoot, cmderOptions.cmderSingle); + if (PathFileExists(windowsTerminalDir)) + { + RegisterShellMenu(cmderOptions.cmderRegScope, SHELL_MENU_REGISTRY_PATH_BACKGROUND, cmderOptions.cmderCfgRoot, cmderOptions.cmderSingle); + RegisterShellMenu(cmderOptions.cmderRegScope, SHELL_MENU_REGISTRY_PATH_LISTITEM, cmderOptions.cmderCfgRoot, cmderOptions.cmderSingle); + RegisterShellMenu(cmderOptions.cmderRegScope, SHELL_MENU_REGISTRY_DRIVE_PATH_BACKGROUND, cmderOptions.cmderCfgRoot, cmderOptions.cmderSingle); + RegisterShellMenu(cmderOptions.cmderRegScope, SHELL_MENU_REGISTRY_DRIVE_PATH_LISTITEM, cmderOptions.cmderCfgRoot, cmderOptions.cmderSingle); + } + else + { + RegisterShellMenu(cmderOptions.cmderRegScope, SHELL_MENU_REGISTRY_PATH_BACKGROUND, cmderOptions.cmderCfgRoot, false); + RegisterShellMenu(cmderOptions.cmderRegScope, SHELL_MENU_REGISTRY_PATH_LISTITEM, cmderOptions.cmderCfgRoot, false); + RegisterShellMenu(cmderOptions.cmderRegScope, SHELL_MENU_REGISTRY_DRIVE_PATH_BACKGROUND, cmderOptions.cmderCfgRoot, false); + RegisterShellMenu(cmderOptions.cmderRegScope, SHELL_MENU_REGISTRY_DRIVE_PATH_LISTITEM, cmderOptions.cmderCfgRoot, false); + } } else if (cmderOptions.unRegisterApp == true) { @@ -776,8 +1017,8 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, } else { - StartCmder(cmderOptions.cmderStart, cmderOptions.cmderSingle, cmderOptions.cmderTask, cmderOptions.cmderTitle, cmderOptions.cmderIcon, cmderOptions.cmderCfgRoot, cmderOptions.cmderUserCfg, cmderOptions.cmderConEmuArgs); + 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 5960625a6..8602089e0 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 ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// diff --git a/launcher/src/strings.rc2 b/launcher/src/strings.rc2 index 088730753..d8feb4d8b 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 /c [CMDER User Root Path]\n /task [ConEmu Task Name]\n /icon [CMDER Icon Path]\n [/start [Start in Path] | [Start in Path]]\n /single\n /m\n /x [ConEmu extra arguments]\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]" } ///////////////////////////////////////////////////////////////////////////// diff --git a/packignore b/packignore index 1fd4315d4..7059f3cc3 100644 --- a/packignore +++ b/packignore @@ -23,5 +23,6 @@ appveyor.yml vendor\cmder.sh vendor\git-prompt.sh config\user-* +config\user_* clink_history* *.log diff --git a/scripts/build.ps1 b/scripts/build.ps1 index d4ccb6711..d80fe03a6 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -8,6 +8,47 @@ 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 +.PARAMETER sourcesPath + Path to the vendor sources JSON file. Defaults to vendor/sources.json. + + Use this to point to a custom package manifest. +.PARAMETER saveTo + Destination directory for downloaded and extracted vendor dependencies. + + Defaults to the repository vendor directory. +.PARAMETER launcher + Path to the launcher project directory used when -Compile is set. + + Defaults to the repository launcher directory. +.PARAMETER config + Path to the configuration directory used to back up and restore user-modified + terminal settings during vendor refresh. + + Defaults to the repository config directory. +.PARAMETER noVendor + Skip downloading and extracting all vendors. + + Useful with -Compile when only rebuilding the launcher. +.PARAMETER terminal + Select which terminal packages to include from sources: + - all: include all supported terminal packages (default) + - none: skip terminal vendor downloads + - conemu-maximus5: include only ConEmu package + - windows-terminal: include only Windows Terminal package +.PARAMETER Compile + Build the launcher executable using MSBuild. + + Requires Visual C++ build tools and msbuild in PATH. +.PARAMETER InstallPacman + Install pacman in the bundled Git for Windows environment if it is not present. +.PARAMETER Verbose + Built-in common parameter from CmdletBinding. + + Prints detailed progress output for troubleshooting. +.PARAMETER WhatIf + Built-in common parameter from CmdletBinding (SupportsShouldProcess). + + Does a dry-run of the build process, showing what actions would be taken without making changes. .EXAMPLE .\build.ps1 @@ -21,20 +62,41 @@ Skip all downloads and only build launcher. .EXAMPLE - .\build -verbose + .\build.ps1 -Verbose Execute the build and see what's going on. .EXAMPLE - .\build.ps1 -SourcesPath '~/custom/vendors.json' + .\build.ps1 -SourcesPath 'C:\custom\sources.json' Build Cmder with your own packages. See vendor/sources.json for the syntax you need to copy. +.EXAMPLE + .\build.ps1 -Terminal conemu-maximus5 + + Build Cmder including only ConEmu (skips Windows Terminal). +.EXAMPLE + .\build.ps1 -Terminal windows-terminal + + Build Cmder including only Windows Terminal (skips ConEmu). +.EXAMPLE + .\build.ps1 -Terminal none -Compile + + Build launcher only and skip all terminal vendor downloads. +.EXAMPLE + .\build.ps1 -InstallPacman + + Build vendors and install pacman into the bundled Git for Windows environment if missing. +.EXAMPLE + .\build.ps1 -WhatIf + + Shows what actions would be taken without applying changes. .NOTES AUTHORS - Samuel Vasko, Jack Bennett + Samuel Vasko, Jack Bennett, Dax Games Part of the Cmder project. .LINK http://cmder.app/ - Project Home #> + [CmdletBinding(SupportsShouldProcess = $true)] Param( # CmdletBinding will give us; @@ -56,11 +118,17 @@ 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', + # Build launcher if you have MSBuild tools installed - [switch]$Compile + [switch]$Compile, + + # Install pacman if not present + [switch]$InstallPacman ) -# Get the scripts and Cmder root dirs we are building in. +# Get the scripts and cmder root dirs we are building in. $cmder_root = Resolve-Path "$PSScriptRoot\.." # Dot source util functions into this scope @@ -113,15 +181,36 @@ if (-not $noVendor) { } else { $ConEmuXml = "" } + # Preserve modified (by user) Windows Terminal setting file + if ($config -ne "") { + $WinTermSettingsJson = Join-Path $saveTo "windows-terminal\settings\settings.json" + if (Test-Path $WinTermSettingsJson -pathType leaf) { + $WinTermSettingsJsonSave = Join-Path $config "windows_terminal_settings.json" + Write-Verbose "Backup '$WinTermSettingsJson' to '$WinTermSettingsJsonSave'" + Copy-Item $WinTermSettingsJson $WinTermSettingsJsonSave + } + else { $WinTermSettingsJson = "" } + } + 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 } } foreach ($s in $sources) { + if ($terminal -eq "none") { + continue + } elseif ($s.name -eq "conemu-maximus5" -and $terminal -eq "windows-terminal") { + continue + } elseif ($s.name -eq "windows-terminal" -and $terminal -eq "conemu-maximus5") { + continue + } + Write-Verbose "Getting vendored $($s.name) $($s.version)..." # We do not care about the extensions/type of archive @@ -132,6 +221,16 @@ if (-not $noVendor) { Download-File -Url $s.url -File $vend\$tempArchive -ErrorAction Stop Extract-Archive $tempArchive $s.name + # 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 + } + if ((Get-ChildItem $s.name).Count -eq 1) { Flatten-Directory($s.name) } @@ -146,6 +245,12 @@ if (-not $noVendor) { Copy-Item $ConEmuXmlSave $ConEmuXml } + # Restore Windows Terminal user configuration + if ($WinTermSettingsJson -ne "") { + Write-Verbose "Restore '$WinTermSettingsJsonSave' to '$WinTermSettingsJson'" + Copy-Item $WinTermSettingsJsonSave $WinTermSettingsJson + } + # 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" @@ -159,6 +264,19 @@ if (-not $noVendor) { Copy-Item $($saveTo + "git-prompt.sh") $($saveTo + "git-for-windows/etc/profile.d/git-prompt.sh") } + $gitForWindowsPath = $saveTo + "git-for-windows" + $pacmanPath = $saveTo + "git-for-windows/usr/bin/pacman.exe" + + $shouldInstallPacman = + $InstallPacman -and + (Test-Path $gitForWindowsPath) -and + -not (Test-Path $pacmanPath) + + if ($shouldInstallPacman) { + Write-Verbose "Installing pacman..." + & $($saveTo + "git-for-windows/bin/bash.exe") $($saveTo + "../scripts/install_pacman.sh") + } + Pop-Location } diff --git a/scripts/install_pacman.sh b/scripts/install_pacman.sh new file mode 100644 index 000000000..fa9c1f079 --- /dev/null +++ b/scripts/install_pacman.sh @@ -0,0 +1,133 @@ +#!/usr/bin/env bash + +# Based on: https://github.com/mcgitty/pacman-for-git +# Dax T. Games Fork: https://github.com/daxgames/pacman-for-git + +# Disclaimer: Use at your own risk. +# +# This script modifies system files and installs the pacman package manager into your Git for Windows environment. +# +# While it has been tested in various Git for Windows versions, there is always a risk of data loss or system instability when running scripts that alter executable files and shared libraries. +# +# Make sure to back up any important data before proceeding. +# +# Always review and understand scripts from external sources prior to execution. +export bin_source=${1:-https://github.com/daxgames/pacman-for-git/raw/refs/heads/main} +echo "Using binary source: $bin_source" +echo "Using HOME directory: $HOME" +read -rp "Press [Enter] to continue..." + +if [[ "$HOSTTYPE" == "i686" ]]; then + pacman=( + pacman-6.0.0-4-i686.pkg.tar.zst + pacman-mirrors-20210703-1-any.pkg.tar.zst + msys2-keyring-1~20210213-2-any.pkg.tar.zst + ) + + zstd=zstd-1.5.0-1-i686.pkg.tar.xz + zstd_win=https://github.com/facebook/zstd/releases/download/v1.5.5/zstd-v1.5.5-win32.zip +else + pacman=( + pacman-6.0.1-18-x86_64.pkg.tar.zst + pacman-mirrors-20220205-1-any.pkg.tar.zst + msys2-keyring-1~20220623-1-any.pkg.tar.zst + ) + + zstd=zstd-1.5.2-1-x86_64.pkg.tar.xz + zstd_win=https://github.com/facebook/zstd/releases/download/v1.5.5/zstd-v1.5.5-win64.zip +fi + +echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +echo Downloading pacman files... +echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +for f in "${pacman[@]}"; do + [[ -f "$HOME/Downloads/$f" ]] && continue + echo "Running: curl -sLkf -o \"$HOME/Downloads/$f\" \"${bin_source}/$f\"" + curl -sLkf -o "$HOME/Downloads/$f" "${bin_source}/$f" || exit 1 +done +echo -e "\n=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n" + +echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +echo Downloading zstd binaries... +echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +if [[ ! -f "$HOME/Downloads/$zstd" ]] ; then + echo "Running: curl -sLkf -o \"$HOME/Downloads/$zstd\" \"${bin_source}/$zstd\"" + curl -sLkf -o "$HOME/Downloads/$zstd" "${bin_source}/$zstd" || exit 1 +fi + +if [[ ! -f "$HOME/Downloads/$(basename${zstd_win})" ]] ; then + echo "Running: curl -sLkf -o \"$HOME/Downloads/$(basename \"${zstd_win}\")\" \"$zstd_win\"" + curl -sLkf -o "$HOME/Downloads/$(basename "${zstd_win}")" "$zstd_win" || exit 1 +fi +echo -e "\n=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n" + +echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +echo Downloading pacman.conf... +echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +echo "Running: curl -Lk https://raw.githubusercontent.com/msys2/MSYS2-packages/7858ee9c236402adf569ac7cff6beb1f883ab67c/pacman/pacman.conf" +curl -sLk https://raw.githubusercontent.com/msys2/MSYS2-packages/7858ee9c236402adf569ac7cff6beb1f883ab67c/pacman/pacman.conf -o /etc/pacman.conf || exit 1 + +pushd "$HOME/Downloads" +[[ -d "$(basename "${zstd_win}" | sed 's/\.zip$//')" ]] && \ + rm -rf "$(basename "${zstd_win}" | sed 's/\.zip$//')" +unzip "$HOME/Downloads/$(basename "${zstd_win}")" +export PATH="$PATH:$HOME/Downloads/$(basename "${zstd_win}" | sed 's/\.zip$//')" +popd +echo -e "\n=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n" + +cd / +echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +echo Installing pacman files... +echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +echo "Extracting zstd to /usr..." +tar x --xz -vf "$HOME/Downloads/$zstd" usr + +for f in "${pacman[@]}"; do + echo "Extracting $f to /usr and /etc..." + tar x --zstd -vf "$HOME/Downloads/$f" usr etc 2>/dev/null +done +echo -e "\n=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n" + +echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +echo Initializing pacman... +echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +mkdir -p /var/lib/pacman +ln -sf "$(which gettext)" /usr/bin/ +pacman-key --init +pacman-key --populate msys2 +pacman -Syu --noconfirm --disable-download-timeout +echo -e "\n=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n" + +echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +echo Getting package versions for the installed Git release +echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +t=$(grep -E 'mingw-w64-[ix_0-9]+-git ' /etc/package-versions.txt) +echo "Found package version line: $t" + +curl --help >/dev/null 2>&1 || { echo "ERROR: curl is not installed properly."; exit 1; } + +echo "Getting commit ID that matches '$t' from github pacman-for-git..." +t=$(curl -sLk "${bin_source}/version-tags.txt" | grep "$t") +echo "Full line from version-tags.txt: '$t'" + +[[ "$t" == "" ]] && echo "ERROR: Commit ID not logged in github pacman-for-git." && exit 1 +echo -e "Using commit ID: '${t##* }'" +echo -e "\n=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n" + +echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +echo Downloading package database files for the installed Git release +echo =-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +b=64 && [[ "$t" == *-i686-* ]] && b=32 +URL="https://github.com/git-for-windows/git-sdk-$b/raw/${t##* }" +while read -r p v; do + d="/var/lib/pacman/local/$p-$v" + mkdir -p "$d" + echo "$d" + + for f in desc files mtree; do + curl -fsSL "$URL$d/$f" -o "$d/$f" + done + + [[ ! -f "$d/desc" ]] && rmdir "$d" && echo "Missing $d" +done < /etc/package-versions.txt +echo -e "\n=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n" diff --git a/scripts/pack.ps1 b/scripts/pack.ps1 index 8dccc5eb1..1b1304608 100644 --- a/scripts/pack.ps1 +++ b/scripts/pack.ps1 @@ -6,14 +6,60 @@ 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 +.PARAMETER cmderRoot + Path to the Cmder repository root that should be packaged. + + Defaults to the parent directory of this script. +.PARAMETER terminal + Select which terminal package set is included in generated archives: + - all: create all archive variants (default) + - none: exclude both ConEmu and Windows Terminal packages + - conemu-maximus5: include only ConEmu package + - windows-terminal: include only Windows Terminal package +.PARAMETER saveTo + Output directory where archives and hashes.txt are written. + + Defaults to the repository build directory. +.PARAMETER Verbose + Built-in common parameter from CmdletBinding. + + Prints detailed packaging progress and included files. +.PARAMETER WhatIf + Built-in common parameter from CmdletBinding (SupportsShouldProcess). + + Shows what actions would run without making changes. .EXAMPLE .\pack.ps1 Creates default archives for Cmder .EXAMPLE - .\pack.ps1 -verbose + .\pack.ps1 -Verbose Creates default archives for Cmder with plenty of information +.EXAMPLE + .\pack.ps1 -Terminal none + + Create archives without bundled terminal emulator packages. +.EXAMPLE + .\pack.ps1 -Terminal conemu-maximus5 + + Create archives that include ConEmu and exclude Windows Terminal. +.EXAMPLE + .\pack.ps1 -Terminal windows-terminal + + Create archives that include Windows Terminal and exclude ConEmu. +.EXAMPLE + .\pack.ps1 -SaveTo 'C:\temp\cmder-artifacts' + + Write release archives and hashes.txt to a custom output directory. +.EXAMPLE + .\pack.ps1 -CmderRoot 'C:\src\cmder' + + Package a Cmder checkout from a custom repository path. +.EXAMPLE + .\pack.ps1 -WhatIf + + Preview packaging actions without creating or deleting files. .NOTES AUTHORS Samuel Vasko, Jack Bennett, Martin Kemp @@ -31,6 +77,9 @@ Param( # Path to the vendor configuration source file [string]$cmderRoot = "$PSScriptRoot\..", + # Using this option will pack artifacts for a specific included terminal emulator [none, all, conemu-maximus5, or windows-terminal] + [string]$terminal = 'all', + # Vendor folder locaton [string]$saveTo = "$PSScriptRoot\..\build" ) @@ -41,10 +90,42 @@ $cmderRoot = Resolve-Path $cmderRoot $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`""; +if ($terminal -eq "none") { + $targets = @{ + "cmder_win.7z" = "-t7z -m0=lzma2 -mx=9 -mfb=64 -md=32m -ms=on -myx=7 -mqs=on -xr!`"vendor\conemu-maximus5`" -xr!`"vendor\windows-terminal`""; + "cmder_win.zip" = "-mm=Deflate -mfb=128 -mpass=3 -xr!`"vendor\conemu-maximus5`" -xr!`"vendor\windows-terminal`""; + "cmder_win.mini.zip" = "-xr!`"vendor\git-for-windows`" -xr!`"vendor\conemu-maximus5`" -xr!`"vendor\windows-terminal`""; + } +} elseif ($terminal -eq "windows-terminal") { + $targets = @{ + "cmder_win.7z" = "-t7z -m0=lzma2 -mx=9 -mfb=64 -md=32m -ms=on -myx=7 -mqs=on -xr!`"vendor\conemu-maximus5`" -xr!`"vendor\windows-terminal`""; + "cmder_win.zip" = "-mm=Deflate -mfb=128 -mpass=3 -xr!`"vendor\conemu-maximus5`" -xr!`"vendor\windows-terminal`""; + "cmder_win_mini.zip" = "-xr!`"vendor\git-for-windows`" -xr!`"vendor\conemu-maximus5`" -xr!`"vendor\windows-terminal`""; + "cmder_wt.7z" = "-t7z -m0=lzma2 -mx=9 -mfb=64 -md=32m -ms=on -myx=7 -mqs=on -xr!`"vendor\conemu-maximus5`""; + "cmder_wt.zip" = "-mm=Deflate -mfb=128 -mpass=3 -xr!`"vendor\conemu-maximus5`""; + "cmder_wt_mini.zip" = "-xr!`"vendor\git-for-windows`" -xr!`"vendor\conemu-maximus5`""; + } +} elseif ($terminal -eq "conemu-maximus5") { + $targets = @{ + "cmder_win.7z" = "-t7z -m0=lzma2 -mx=9 -mfb=64 -md=32m -ms=on -myx=7 -mqs=on -xr!`"vendor\conemu-maximus5`" -xr!`"vendor\windows-terminal`""; + "cmder_win.zip" = "-mm=Deflate -mfb=128 -mpass=3 -xr!`"vendor\conemu-maximus5`" -xr!`"vendor\windows-terminal`""; + "cmder_win_mini.zip" = "-xr!`"vendor\git-for-windows`" -xr!`"vendor\conemu-maximus5`" -xr!`"vendor\windows-terminal`""; + "cmder.7z" = "-t7z -m0=lzma2 -mx=9 -mfb=64 -md=32m -ms=on -myx=7 -mqs=on -xr!`"vendor\windows-terminal`""; + "cmder.zip" = "-mm=Deflate -mfb=128 -mpass=3 -xr!`"vendor\windows-terminal`""; + "cmder_mini.zip" = "-xr!`"vendor\git-for-windows`" -xr!`"vendor\windows-terminal`""; + } +} else { + $targets = @{ + "cmder_win.7z" = "-t7z -m0=lzma2 -mx=9 -mfb=64 -md=32m -ms=on -myx=7 -mqs=on -xr!`"vendor\conemu-maximus5`" -xr!`"vendor\windows-terminal`""; + "cmder_win.zip" = "-mm=Deflate -mfb=128 -mpass=3 -xr!`"vendor\conemu-maximus5`" -xr!`"vendor\windows-terminal`""; + "cmder_win_mini.zip" = "-xr!`"vendor\git-for-windows`" -xr!`"vendor\conemu-maximus5`" -xr!`"vendor\windows-terminal`""; + "cmder_wt.7z" = "-t7z -m0=lzma2 -mx=9 -mfb=64 -md=32m -ms=on -myx=7 -mqs=on -xr!`"vendor\conemu-maximus5`""; + "cmder_wt.zip" = "-mm=Deflate -mfb=128 -mpass=3 -xr!`"vendor\conemu-maximus5`""; + "cmder_wt_mini.zip" = "-xr!`"vendor\git-for-windows`" -xr!`"vendor\conemu-maximus5`""; + "cmder.7z" = "-t7z -m0=lzma2 -mx=9 -mfb=64 -md=32m -ms=on -myx=7 -mqs=on -xr!`"vendor\windows-terminal`""; + "cmder.zip" = "-mm=Deflate -mfb=128 -mpass=3 -xr!`"vendor\windows-terminal`""; + "cmder_mini.zip" = "-xr!`"vendor\git-for-windows`" -xr!`"vendor\windows-terminal`""; + } } Push-Location -Path $cmderRoot @@ -70,7 +151,7 @@ if ($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent) { 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) + Add-Content -path "$saveTo\hashes.txt" -value ($t.Name + "`t" + $hash) } Pop-Location diff --git a/scripts/rehome.sh b/scripts/rehome.sh new file mode 100644 index 000000000..c1977e94b --- /dev/null +++ b/scripts/rehome.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +if [ "$#" -ne 2 ]; then + echo "Usage: $0 : :" + exit 1 +fi + +branches=$1 +orgs=$2 + +source_branch=$(echo ${branches} | awk -F: '{print $1}') +dest_branch=$(echo ${branches} | awk -F: '{print $2}') + +source_org=$(echo ${orgs} | awk -F: '{print $1}') +dest_org=$(echo ${orgs} | awk -F: '{print $2}') + +sed -i "s/${source_branch}/${dest_branch}/g;s/${source_org}/${dest_org}/g;s/, \"development\"//;s/^\s\+- development//" $(grep -R "${source_branch}\|${source_org}\|development" ./.github | awk -F: '{print $1}' | grep -v workflows/branches.yml) diff --git a/scripts/update.ps1 b/scripts/update.ps1 index c6b982d7c..17350b52f 100644 --- a/scripts/update.ps1 +++ b/scripts/update.ps1 @@ -5,19 +5,27 @@ 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 - Then unblock the script for execution with UnblockFile .\build.ps1 + Then unblock the script for execution with UnblockFile .\update.ps1 +.PARAMETER sourcesPath + Path to the vendor sources JSON file to update. Defaults to `vendor\sources.json`. +.PARAMETER IncludePrerelease + Include pre-release versions (RC, beta, alpha, preview, etc.). By default, only stable releases are considered. .EXAMPLE - .\build.ps1 + .\update.ps1 Updates the dependency sources in the default location, the vendor/sources.json file. .EXAMPLE - .\build -verbose + .\update.ps1 -Verbose Updates the dependency sources and see what's going on. .EXAMPLE - .\build.ps1 -SourcesPath '~/custom/vendors.json' + .\update.ps1 -SourcesPath '~/custom/vendors.json' Specify the path to update dependency sources file at. +.EXAMPLE + .\update.ps1 -IncludePrerelease + + Updates dependencies including pre-release versions. .NOTES AUTHORS David Refoua diff --git a/scripts/utils.ps1 b/scripts/utils.ps1 index 58955407c..21840365f 100644 --- a/scripts/utils.ps1 +++ b/scripts/utils.ps1 @@ -105,6 +105,7 @@ function Get-VersionStr { if ( $GitPresent -eq 'true' ) { $string = Invoke-Expression "git describe --abbrev=0 --tags" + write-Verbose "Version string from git describe: $string" } } @@ -124,6 +125,8 @@ function Get-VersionStr { # Remove starting 'v' characters $string = $string -replace '^v+','' # normalize version string + write-Verbose "Determined version string: $string" + return $string } @@ -134,6 +137,8 @@ function Parse-Changelog($file) { # 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 } + write-Verbose "Parsed version string from changelog: $version" + return $version } @@ -249,3 +254,107 @@ function Download-File { $wc.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials; $wc.DownloadFile($Url, $File) } + +function Format-FileSize { + <# + .SYNOPSIS + Formats a file size in bytes to a human-readable string using binary units. + + .DESCRIPTION + Converts file sizes to appropriate binary units (B, KiB, MiB, GiB) for better readability. + + .PARAMETER Bytes + The file size in bytes to format. + + .EXAMPLE + Format-FileSize -Bytes 1024 + Returns "1.00 KiB" + + .EXAMPLE + Format-FileSize -Bytes 15728640 + Returns "15.00 MiB" + #> + param( + [Parameter(Mandatory = $true)] + [double]$Bytes + ) + + if ($Bytes -ge 1GB) { + return "{0:N2} GiB" -f ($Bytes / 1GB) + } elseif ($Bytes -ge 1MB) { + return "{0:N2} MiB" -f ($Bytes / 1MB) + } elseif ($Bytes -ge 1KB) { + return "{0:N2} KiB" -f ($Bytes / 1KB) + } else { + return "{0:N0} B" -f $Bytes + } +} + +function Get-ArtifactDownloadUrl { + <# + .SYNOPSIS + Retrieves the download URL for a GitHub Actions artifact with retry logic. + + .DESCRIPTION + Uses the GitHub CLI to fetch artifact information from the GitHub API with automatic retries. + Falls back to returning $null if all attempts fail. + + .PARAMETER ArtifactName + The name of the artifact to retrieve the download URL for. + + .PARAMETER Repository + The GitHub repository in the format "owner/repo". + + .PARAMETER RunId + The GitHub Actions workflow run ID. + + .PARAMETER MaxRetries + Maximum number of retry attempts. Default is 3. + + .PARAMETER DelaySeconds + Delay in seconds between retry attempts. Default is 2. + + .EXAMPLE + Get-ArtifactDownloadUrl -ArtifactName "cmder.zip" -Repository "cmderdev/cmder" -RunId "123456789" + + .EXAMPLE + Get-ArtifactDownloadUrl -ArtifactName "build-output" -Repository "owner/repo" -RunId "987654321" -MaxRetries 5 -DelaySeconds 3 + #> + param( + [Parameter(Mandatory = $true)] + [string]$ArtifactName, + + [Parameter(Mandatory = $true)] + [string]$Repository, + + [Parameter(Mandatory = $true)] + [string]$RunId, + + [int]$MaxRetries = 3, + [int]$DelaySeconds = 2 + ) + + for ($i = 0; $i -lt $MaxRetries; $i++) { + try { + # Use GitHub CLI to get artifact information + $artifactsJson = gh api "repos/$Repository/actions/runs/$RunId/artifacts" --jq ".artifacts[] | select(.name == `"$ArtifactName`")" + + if ($artifactsJson) { + $artifact = $artifactsJson | ConvertFrom-Json + if ($artifact.id) { + # Construct browser-accessible GitHub Actions artifact download URL + # Format: https://github.com/owner/repo/actions/runs/{run_id}/artifacts/{artifact_id} + return "https://github.com/$Repository/actions/runs/$RunId/artifacts/$($artifact.id)" + } + } + } catch { + Write-Host "Attempt $($i + 1) failed to get artifact URL for $ArtifactName : $_" + } + + if ($i -lt ($MaxRetries - 1)) { + Start-Sleep -Seconds $DelaySeconds + } + } + + return $null +} diff --git a/vendor/ConEmu.xml.default b/vendor/ConEmu.xml.default index a4e5cc1fb..47b53d430 100644 --- a/vendor/ConEmu.xml.default +++ b/vendor/ConEmu.xml.default @@ -1,7 +1,7 @@ - + @@ -42,8 +42,8 @@ - - + + @@ -58,7 +58,7 @@ - + @@ -78,7 +78,6 @@ - @@ -113,13 +112,13 @@ - + - + - + @@ -128,8 +127,8 @@ - - + + @@ -166,19 +165,19 @@ - + - + - + - + @@ -413,15 +412,15 @@ - + - + - + @@ -484,12 +483,12 @@ - - + + - - + + @@ -497,8 +496,8 @@ - - + + @@ -507,8 +506,8 @@ - - + + @@ -516,61 +515,78 @@ - - - + + + - + + + + + + + + + + + + + + + + + + + + - - + + - + - - + + - - + - + + - - + - - + + - + - + - @@ -676,7 +692,7 @@ - + @@ -845,13 +861,13 @@ - - + + - + - + @@ -869,10 +885,16 @@ + + + + + + - + @@ -902,6 +924,15 @@ + + + + + + + + + diff --git a/vendor/bin/cmder_diag.cmd b/vendor/bin/cmder_diag.cmd index f526cff62..d806ee6b2 100644 --- a/vendor/bin/cmder_diag.cmd +++ b/vendor/bin/cmder_diag.cmd @@ -2,9 +2,9 @@ (echo. echo ------------------------------------ -echo set +echo Get Cmder env variables... echo ------------------------------------ -set +set | findstr -i -r "^aliases= architecture_bits ccall= cexec= ^clink_ ^cmder ^debug_output= fast_init= ^GIT_INSTALL_ROOT= ^git_locale= ^HOME= ^max_depth= ^nix_tools= ^path_position= ^path= ^PLINK_PROTOCOL= ^print_ ^SVN_SSH= ^time_init= ^user_aliases= ^verbose_output=" echo. echo ------------------------------------ diff --git a/vendor/bin/create-cmdercfg.cmd b/vendor/bin/create-cmdercfg.cmd new file mode 100644 index 000000000..cc8c7116b --- /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" diff --git a/vendor/bin/create-cmdercfg.ps1 b/vendor/bin/create-cmdercfg.ps1 new file mode 100644 index 000000000..4dfc15e5c --- /dev/null +++ b/vendor/bin/create-cmdercfg.ps1 @@ -0,0 +1,30 @@ +[CmdletBinding()] +param( + [Parameter()] + [string]$shell = 'cmd', + [string]$outfile = "$env:cmder_config_dir\user_init.cmd" +) + +if ($shell -match 'powershell') { + write-host "'$shell' is not supported at this time!" + exit 0 +} elseif ($shell -match 'bash') { + write-host "'$shell' is not supported at this time!" + exit 0 +} elseif ($shell -notMatch 'cmd') { + exit 0 +} + +$CmderModulePath = Join-path $env:cmder_root "vendor/psmodules/" +$CmderFunctions = Join-Path $CmderModulePath "Cmder.ps1" + +. $CmderFunctions + +if ($shell -match 'cmd') { + write-host "Generating Cmder Config for '$shell' shell in '$outfile'..." + templateExpand "$env:cmder_root\vendor\user_init.cmd.template" "$outfile" +} elseif ($shell -match 'powershell') { + write-host "'$shell' is not supported at this time!" +} elseif ($shell -match 'bash') { + write-host "'$shell' is not supported at this time!" +} diff --git a/vendor/bin/timer.cmd b/vendor/bin/timer.cmd index e0b84249d..68a5bc328 100644 --- a/vendor/bin/timer.cmd +++ b/vendor/bin/timer.cmd @@ -11,6 +11,7 @@ set /a hours=%end_h%-%start_h% set /a mins=%end_m%-%start_m% set /a secs=%end_s%-%start_s% set /a ms=%end_ms%-%start_ms% + if %ms% lss 0 set /a secs = %secs% - 1 & set /a ms = 100%ms% if %secs% lss 0 set /a mins = %mins% - 1 & set /a secs = 60%secs% if %mins% lss 0 set /a hours = %hours% - 1 & set /a mins = 60%mins% @@ -20,3 +21,26 @@ if 1%ms% lss 100 set ms=0%ms% :: Mission accomplished set /a totalsecs = %hours%*3600 + %mins%*60 + %secs% echo Elapsed Time: %hours%:%mins%:%secs%.%ms% (%totalsecs%.%ms%s total) + +:: cleanup +set start= +set end= +set options= + +set start_h= +set start_m= +set start_s= +set start_ms= + +set end_h= +set end_m= +set end_s= +set end_ms= + +set hours= +set mins= +set secs= +set ms= + +set totalsecs= + diff --git a/vendor/clink.lua b/vendor/clink.lua index 804f9c649..4452c3470 100644 --- a/vendor/clink.lua +++ b/vendor/clink.lua @@ -800,6 +800,10 @@ for _,lua_module in ipairs(clink.find_files(completions_dir..'*.lua')) do end end +-- If Cmder is launched with '/c [folderPath]', indicating Cmder is installed globally and +-- each user has a private '[folderPath]\config' folder, Clink won't know about the global +-- '%cmder_root%\config dir, so we need to load scripts from there before . Clink loads lua +-- scripts from the profile directory given to it when it was injected. if clink.get_env('CMDER_USER_CONFIG') then local cmder_config_dir = clink.get_env('CMDER_ROOT')..'/config/' for _,lua_module in ipairs(clink.find_files(cmder_config_dir..'*.lua')) do diff --git a/vendor/cmder.sh b/vendor/cmder.sh index 8467593b3..dfbf91c71 100644 --- a/vendor/cmder.sh +++ b/vendor/cmder.sh @@ -22,7 +22,11 @@ function runProfiled { } # We do this for bash as admin sessions since $CMDER_ROOT is not being set -if [ "$CMDER_ROOT" == "" ] ; then +if [ -z "$CMDER_ROOT" ] && [ -n "$cmder_root" ] ; then + export CMDER_ROOT=$(cygpath -u $cmder_root) +fi + +if [ -z "$CMDER_ROOT" ] ; then case "$ConEmuDir" in *\\*) CMDER_ROOT=$( cd "$(cygpath -u "$ConEmuDir")/../.." ; pwd );; esac else case "$CMDER_ROOT" in *\\*) CMDER_ROOT="$(cygpath -u "$CMDER_ROOT")";; esac diff --git a/vendor/cmder_exinit b/vendor/cmder_exinit index 4ec3351af..edb12c7ec 100644 --- a/vendor/cmder_exinit +++ b/vendor/cmder_exinit @@ -26,15 +26,14 @@ function runProfiled { unset profile_d_scripts pushd "${1}" >/dev/null - if [ ! "x${ZSH_VERSION}" = "x" ]; then + if [ -n "${ZSH_VERSION}" ]; then profile_d_scripts=$(ls *.zsh 2>/dev/null) - elif [ ! "x${BASH_VERSION}" = "x" ]; then + elif [ -n "${BASH_VERSION}" ]; then profile_d_scripts=$(ls *.sh 2>/dev/null) fi - if [ ! "x${profile_d_scripts}" = "x" ] ; then + if [ -n "${profile_d_scripts}" ] ; then for x in ${profile_d_scripts} ; do - echo Sourcing "${1}/${x}"... . "${1}/${x}" done fi @@ -44,23 +43,23 @@ function runProfiled { # Check that we haven't already been sourced. [[ -z ${CMDER_EXINIT} ]] && CMDER_EXINIT="1" || return +if [ -z "$CMDER_ROOT" ] && [ -n "$cmder_root" ] ; then + export CMDER_ROOT=$(cygpath -u $cmder_root) +fi + # We do this for bash as admin sessions since $CMDER_ROOT is not being set if [ "$CMDER_ROOT" = "" -a "$ConEmuDir" != "" ] ; then - if [ -d "${ConEmuDir}../../vendor" ] ; then + if [ -d "${ConEmuDir}/../../vendor" ] ; then case "$ConEmuDir" in *\\*) CMDER_ROOT=$( cd "$(cygpath -u "$ConEmuDir")/../.." ; pwd );; esac - else - echo "Running in ConEmu without Cmder, skipping Cmder integration." fi elif [ "$CMDER_ROOT" != "" ] ; then case "$CMDER_ROOT" in *\\*) CMDER_ROOT="$(cygpath -u "$CMDER_ROOT")";; esac fi -if [ ! "$CMDER_ROOT" = "" ] ; then +if [ -n "$CMDER_ROOT" ] ; then # Remove any trailing '/' CMDER_ROOT=$(echo $CMDER_ROOT | sed 's:/*$::') - echo "Using \"CMDER_ROOT\" at \"${CMDER_ROOT}\"." - export CMDER_ROOT PATH=${CMDER_ROOT}/bin:${CMDER_ROOT}/vendor/bin:$PATH:${CMDER_ROOT} diff --git a/vendor/init.bat b/vendor/init.bat index 2eabb6ea8..3a622c963 100644 --- a/vendor/init.bat +++ b/vendor/init.bat @@ -166,9 +166,24 @@ if "%PROCESSOR_ARCHITECTURE%"=="x86" ( set CMDER_CLINK=0 ) +if defined CMDER_USER_CONFIG ( + if exist "%CMDER_ROOT%\config\user_init.cmd" ( + call "%CMDER_ROOT%\config\user_init.cmd" + exit /b + ) else if exist "%CMDER_USER_CONFIG%\config\user_init.cmd" ( + call "%CMDER_USER_CONFIG%\config\user_init.cmd" + exit /b + ) +) else if exist "%CMDER_ROOT%\config\user_init.cmd" ( + call "%CMDER_ROOT%\config\user_init.cmd" + exit /b +) + if "%CMDER_CLINK%" == "1" ( REM TODO: Detect if clink is already injected, if so goto :CLINK_FINISH goto :INJECT_CLINK +) else if "%CMDER_CLINK%" == "2" ( + goto :CLINK_FINISH ) goto :SKIP_CLINK @@ -205,6 +220,7 @@ goto :SKIP_CLINK ) "%CMDER_ROOT%\vendor\clink\clink_%clink_architecture%.exe" inject --quiet --profile "%CMDER_CONFIG_DIR%" --scripts "%CMDER_ROOT%\vendor" + set CMDER_CLINK=2 :: Check if a fatal error occurred when trying to inject Clink if errorlevel 2 ( @@ -302,7 +318,7 @@ if exist "%CMDER_ROOT%\vendor\git-for-windows" ( ) :SPECIFIED_GIT -%print_debug% init.bat "Using /GIT_INSTALL_ROOT..." +%print_debug% init.bat "Using specified GIT_INSTALL_ROOT=%GIT_INSTALL_ROOT%...." goto :CONFIGURE_GIT :FOUND_GIT @@ -311,8 +327,13 @@ goto :CONFIGURE_GIT :CONFIGURE_GIT %print_debug% init.bat "Using Git from '%GIT_INSTALL_ROOT%..." + :: Add git to the path -if exist "%GIT_INSTALL_ROOT%\cmd\git.exe" %lib_path% enhance_path "%GIT_INSTALL_ROOT%\cmd" "" +%print_debug% init.bat "START - git.exe(prepend): Env Var - PATH=%path%" +if exist "%GIT_INSTALL_ROOT%\cmd\git.exe" ( + set "path=%GIT_INSTALL_ROOT%\cmd;%path%" +) +%print_debug% init.bat "END - git.exe(prepend): Env Var - PATH=%path%" :: Add the unix commands at the end to not shadow windows commands like `more` and `find` if %nix_tools% equ 1 ( @@ -323,16 +344,30 @@ if %nix_tools% equ 1 ( set "path_position=" ) +%print_debug% init.bat "START - nix_tools(%path_position%): Env Var - PATH=%path%" if %nix_tools% geq 1 ( if exist "%GIT_INSTALL_ROOT%\mingw32" ( - %lib_path% enhance_path "%GIT_INSTALL_ROOT%\mingw32\bin" %path_position% + if "%path_position%" == "append" ( + set "path=%path%;%GIT_INSTALL_ROOT%\mingw32\bin" + ) else ( + set "path=%GIT_INSTALL_ROOT%\mingw32\bin;%path%" + ) ) else if exist "%GIT_INSTALL_ROOT%\mingw64" ( - %lib_path% enhance_path "%GIT_INSTALL_ROOT%\mingw64\bin" %path_position% + if "%path_position%" == "append" ( + set "path=%path%;%GIT_INSTALL_ROOT%\mingw64\bin" + ) else ( + set "path=%GIT_INSTALL_ROOT%\mingw64\bin;%path%" + ) ) if exist "%GIT_INSTALL_ROOT%\usr\bin" ( - %lib_path% enhance_path "%GIT_INSTALL_ROOT%\usr\bin" %path_position% + if "%path_position%" == "append" ( + set "path=%path%;%GIT_INSTALL_ROOT%\usr\bin" + ) else ( + set "path=%GIT_INSTALL_ROOT%\usr\bin;%path%" + ) ) ) +%print_debug% init.bat "END - nix_tools(%path_position%): Env Var - PATH=%path%" :SET_ENV @@ -365,8 +400,7 @@ if defined git_locale ( ) endlocal && set LANG=%LANG% -%print_debug% init.bat "Env Var - GIT_INSTALL_ROOT=%GIT_INSTALL_ROOT%" -%print_debug% init.bat "Found Git in: '%GIT_INSTALL_ROOT%'" +%print_debug% init.bat "Found Git in: 'GIT_INSTALL_ROOT=%GIT_INSTALL_ROOT%'" goto :PATH_ENHANCE :NO_GIT @@ -374,14 +408,32 @@ goto :PATH_ENHANCE endlocal :PATH_ENHANCE -%lib_path% enhance_path "%CMDER_ROOT%\vendor\bin" +%print_debug% init.bat "START - vendor/bin(prepend): Env Var - PATH=%path%" +set "path=%CMDER_ROOT%\vendor\bin;%path%" +%print_debug% init.bat "END - vendor/bin(prepend): Env Var - PATH=%path%" :USER_CONFIG_START -%lib_path% enhance_path_recursive "%CMDER_ROOT%\bin" 0 %max_depth% -if defined CMDER_USER_BIN ( +%print_debug% init.bat "START - bin(prepend): Env Var - PATH=%path%" +if %max_depth% gtr 1 ( + %lib_path% enhance_path_recursive "%CMDER_ROOT%\bin" 0 %max_depth% +) else ( + set "path=%CMDER_ROOT%\bin;%path%" +) +%print_debug% init.bat "END - bin(prepend): Env Var - PATH=%path%" + +if defined CMDER_USER_BIN if defined CMDER_USER_ROOT ( + %print_debug% init.bat "START - user_bin(prepend): Env Var - PATH=%path%" + if %max_depth% gtr 1 ( %lib_path% enhance_path_recursive "%CMDER_USER_BIN%" 0 %max_depth% + ) else ( + set "path=%CMDER_USER_ROOT%\bin;%path%" + ) + %print_debug% init.bat "END - user_bin(prepend): Env Var - PATH=!path!" ) -%lib_path% enhance_path "%CMDER_ROOT%" append + +%print_debug% init.bat "START - cmder_root(append): Env Var - PATH=%path%" +set "path=%path%;%CMDER_ROOT%" +%print_debug% init.bat "END - cmder_root(append): Env Var - PATH=%path%" :: Drop *.bat and *.cmd files into "%CMDER_ROOT%\config\profile.d" :: to run them at startup. @@ -490,12 +542,40 @@ if "%CMDER_ALIASES%" == "1" if exist "%CMDER_ROOT%\bin\alias.bat" if exist "%CMD set initialConfig= -:CMDER_CONFIGURED -if not defined CMDER_CONFIGURED set CMDER_CONFIGURED=1 - -set CMDER_INIT_END=%time% +if not exist "%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 %time_init% gtr 0 ( - "%cmder_root%\vendor\bin\timer.cmd" "%CMDER_INIT_START%" "%CMDER_INIT_END%" + if not exist "%CMDER_ROOT%\config\user_init.cmd" ( + %print_error% "Failed to generate Cmder config" + ) ) + +:CMDER_CONFIGURED + if not defined CMDER_CONFIGURED set CMDER_CONFIGURED=1 + set CMDER_INIT_END=%time% + + if "%time_init%" == "1" if "%CMDER_INIT_END%" neq "" if "%CMDER_INIT_START%" neq "" ( + call "%cmder_root%\vendor\bin\timer.cmd" "%CMDER_INIT_START%" "%CMDER_INIT_END%" + ) + +:CLEANUP + set architecture_bits= + set CMDER_ALIASES= + set CMDER_INIT_END= + set CMDER_INIT_START= + set CMDER_USER_FLAGS= + set CMDER_CLINK= + set debug_output= + set fast_init= + set max_depth= + set nix_tools= + set path_position= + set print_debug= + set print_error= + set print_verbose= + set print_warning= + set time_init= + set verbose_output= + set user_aliases= + exit /b diff --git a/vendor/lib/lib_path.cmd b/vendor/lib/lib_path.cmd index 4415388b6..6bebc23cd 100644 --- a/vendor/lib/lib_path.cmd +++ b/vendor/lib/lib_path.cmd @@ -91,13 +91,13 @@ exit /b if /i "!position!" == "append" ( 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 ) %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!;" + 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!" @@ -157,8 +157,12 @@ exit /b exit /b :enhance_path_recursive + call :set_path_recursive "%~1" "%~2" "%~3" + exit /b + +:set_path_recursive :::=============================================================================== -:::enhance_path_recursive - Add a directory and subs to the path env variable if +:::set_path_recursive - Add a directory and subs to the path env variable if ::: required. :::. :::include: @@ -167,7 +171,7 @@ exit /b :::. :::usage: :::. -::: call "%~DP0lib_path" enhance_path_recursive "[dir_path]" [max_depth] [append] +::: call "%~DP0lib_path" set_path_recursive "[dir_path]" [max_depth] [append] :::. :::required: :::. @@ -190,13 +194,28 @@ exit /b exit /b 1 ) + rem Parse arguments robustly: + rem Accept either public form: "[dir_path]" [max_depth] [append] + rem or internal recursive form: "[dir_path]" [depth] [max_depth] [append] set "depth=%~2" set "max_depth=%~3" + set "position=" - if "%~4" neq "" if /i "%~4" == "append" ( - set "position=%~4" - ) else ( - set "position=" + if /i "%~4" == "append" set "position=append" + if /i "%~3" == "append" ( + set "position=append" + set "max_depth=" + ) + + if not defined depth set "depth=0" + if not defined max_depth ( + if defined depth ( + rem If only one numeric argument provided, treat it as max_depth + set "max_depth=%depth%" + set "depth=0" + ) else ( + set "max_depth=1" + ) ) dir "%add_path%" 2>NUL | findstr -i -e "%find_pathext%" >NUL @@ -209,7 +228,11 @@ exit /b if "%fast_init%" == "1" ( if "%add_to_path%" neq "" ( - call :enhance_path "%add_to_path%" %position% + if "%position%" == "append" ( + set "path=%path%;%add_to_path%" + ) else ( + set "path=%add_to_path%;%path%" + ) ) ) @@ -218,22 +241,24 @@ exit /b 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%" + %print_debug% :set_path_recursive "Env Var - add_path=%add_to_path%" + %print_debug% :set_path_recursive "Env Var - position=%position%" + %print_debug% :set_path_recursive "Env Var - depth=%depth%" + %print_debug% :set_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% + %print_debug% :set_path_recursive "Adding parent directory - '%add_to_path%'" + if "%position%" == "append" ( + set "path=%path%;%add_to_path%" + ) else ( + set "path=%add_to_path%;%path%" + ) ) call :set_depth call :loop_depth ) - set "PATH=%PATH%" - exit /b :set_depth @@ -246,9 +271,9 @@ 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%" + %print_debug% :set_path_recursive "Env Var BEFORE - depth=%depth%" + %print_debug% :set_path_recursive "Found Subdirectory - '%%~fi'" + call :set_path_recursive "%%~fi" %depth% %max_depth% %position% + %print_debug% :set_path_recursive "Env Var AFTER- depth=%depth%" ) exit /b diff --git a/vendor/profile.ps1 b/vendor/profile.ps1 index bc33a9b65..19eef8b4e 100644 --- a/vendor/profile.ps1 +++ b/vendor/profile.ps1 @@ -104,7 +104,7 @@ if ($null -ne $ENV:GIT_INSTALL_ROOT) { # Create 'vi' alias for 'vim' if vim is available if (Get-Command -Name "vim" -ErrorAction SilentlyContinue) { - New-Alias -name "vi" -value vim + New-Alias -name "vi" -value vim -errorAction SilentlyContinue } # PSReadline configuration diff --git a/vendor/psmodules/Cmder.ps1 b/vendor/psmodules/Cmder.ps1 index 6de808e4b..ad46b4ea6 100644 --- a/vendor/psmodules/Cmder.ps1 +++ b/vendor/psmodules/Cmder.ps1 @@ -249,3 +249,29 @@ function Get-GitStatusSetting { return $true } + +function yOrn( $question ) { + Do { + $Answer = Read-Host -Prompt "`n${question}? (y/n) " + } + Until ($Answer -eq 'y' -or $Answer -eq 'n' -or $Answer -eq 'yes' -or $Answer -eq 'no') + + return $Answer +} + +function templateExpand($template_filename, $outfile) { + $template = Get-Content "$template_filename" -Raw + + $expanded = Invoke-Expression "@`"`r`n$template`r`n`"@" + + $overwrite = 'y' + if ((test-path "$outfile")) { + $overwrite = yOrn "'$outfile' already exists do you want to overwrite it" + } + + if ($overwrite -match 'y') { + $expanded | out-file -ErrorAction silentlycontinue -encoding ascii "$outfile" + } else { + write-host "Skipping Cmder '$shell' config generation at user request!" + } +} diff --git a/vendor/sources.json b/vendor/sources.json index df1ae3e5f..3f6118fc1 100644 --- a/vendor/sources.json +++ b/vendor/sources.json @@ -1,13 +1,13 @@ [ { "name": "git-for-windows", - "version": "2.52.0.windows.1", - "url": "https://github.com/git-for-windows/git/releases/download/v2.52.0.windows.1/PortableGit-2.52.0-64-bit.7z.exe" + "version": "2.54.0.windows.1", + "url": "https://github.com/git-for-windows/git/releases/download/v2.54.0.windows.1/PortableGit-2.54.0-64-bit.7z.exe" }, { "name": "clink", - "version": "1.9.5", - "url": "https://github.com/chrisant996/clink/releases/download/v1.9.5/clink.1.9.5.ee6b4f.zip" + "version": "1.9.17", + "url": "https://github.com/chrisant996/clink/releases/download/v1.9.17/clink.1.9.17.36e2ca.zip" }, { "name": "conemu-maximus5", @@ -16,8 +16,8 @@ }, { "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" + "version": "1.23.20211.0", + "url": "https://github.com/microsoft/terminal/releases/download/v1.23.20211.0/Microsoft.WindowsTerminal_1.23.20211.0_x64.zip" }, { "name": "clink-completions", diff --git a/vendor/start_git_bash.cmd b/vendor/start_git_bash.cmd new file mode 100644 index 000000000..679c5af9e --- /dev/null +++ b/vendor/start_git_bash.cmd @@ -0,0 +1,51 @@ +@echo off + +if not defined CMDER_ROOT ( + if defined ConEmuDir ( + for /f "delims=" %%i in ("%ConEmuDir%\..\..") do ( + set "CMDER_ROOT=%%~fi" + ) + ) else ( + for /f "delims=" %%i in ("%~dp0\..") do ( + set "CMDER_ROOT=%%~fi" + ) + ) +) + +if defined ConEmuDir ( + set "gitCommand=--command=%ConEmuBaseDirShort%\conemu-msys2-64.exe" +) + +if exist "%CMDER_ROOT%\vendor\git-for-windows" ( + set "PATH=%CMDER_ROOT%\vendor\git-for-windows\usr\bin;%PATH%" + set "gitCmd=%CMDER_ROOT%\vendor\git-for-windows\git-cmd.exe" + set "bashCmd=%CMDER_ROOT%\vendor\git-for-windows\usr\bin\bash.exe" +) else if exist "%ProgramFiles%\git" ( + set "PATH=%ProgramFiles%\git\usr\bin;%PATH%" + set "gitCmd=%ProgramFiles%\git\git-cmd.exe" + set "bashCmd=%ProgramFiles%\git\usr\bin\bash.exe" + if not exist "%ProgramFiles%\git\etc\profile.d\cmder_exinit.sh" ( + echo Run 'mklink "%ProgramFiles%\git\etc\profile.d\cmder_exinit.sh" "%CMDER_ROOT%\vendor\cmder_exinit"' in 'cmd::Cmder as Admin' to use Cmder with external Git Bash + echo. + echo or + echo. + echo Run 'echo "" ^> "%ProgramFiles%\git\etc\profile.d\cmder_exinit.sh"' in 'cmd::Cmder as Admin' to disable this message. + ) +) else if exist "%ProgramFiles(x86)%\git" ( + set "PATH=%ProgramFiles(x86)%\git\usr\bin;%PATH%" + set "gitCmd=%ProgramFiles(x86)%\git\git-cmd.exe" + set "bashCmd=%ProgramFiles(x86)%\git\usr\bin\bash.exe" + if not exist "%ProgramFiles(x86)%\git\etc\profile.d\cmder_exinit.sh" ( + echo Run 'mklink "%ProgramFiles^(x86^)%\git\etc\profile.d\cmder_exinit.sh" "%CMDER_ROOT%\vendor\cmder_exinit"' in 'cmd::Cmder as Admin' to use Cmder with external Git Bash + echo. + echo or + echo. + echo Run 'echo "" ^> "%ProgramFiles^(x86^)%\git\etc\profile.d\cmder_exinit.sh"' in 'cmd::Cmder as Admin' to disable this message. + ) +) + +if defined ConEmuDir ( + "%gitCmd%" --no-cd %gitCommand% "%bashCmd%" --login -i +) else ( + "%bashCmd%" --login -i +) diff --git a/vendor/start_git_mintty.cmd b/vendor/start_git_mintty.cmd new file mode 100644 index 000000000..ea4f09a9f --- /dev/null +++ b/vendor/start_git_mintty.cmd @@ -0,0 +1,40 @@ +@echo off + +if not defined CMDER_ROOT ( + if defined ConEmuDir ( + for /f "delims=" %%i in ("%ConEmuDir%\..\..") do ( + set "CMDER_ROOT=%%~fi" + ) + ) else ( + for /f "delims=" %%i in ("%~dp0\..") do ( + set "CMDER_ROOT=%%~fi" + ) + ) +) + +if exist "%CMDER_ROOT%\vendor\git-for-windows" ( + set "PATH=%CMDER_ROOT%\vendor\git-for-windows\usr\bin;%PATH%" + set "gitCmd=%CMDER_ROOT%\vendor\git-for-windows\usr\bin\mintty.exe" +) else if exist "%ProgramFiles%\git" ( + set "PATH=%ProgramFiles%\git\usr\bin;%PATH%" + set "gitCmd=%ProgramFiles%\git\usr\bin\mintty.exe" + if not exist "%ProgramFiles%\git\etc\profile.d\cmder_exinit.sh" ( + echo Run 'mklink "%ProgramFiles%\git\etc\profile.d\cmder_exinit.sh" "%CMDER_ROOT%\vendor\cmder_exinit"' in 'cmd::Cmder as Admin' to use Cmder with external Git Bash + echo. + echo or + echo. + echo Run 'echo "" ^> "%ProgramFiles%\git\etc\profile.d\cmder_exinit.sh"' in 'cmd::Cmder as Admin' to disable this message. + ) +) else if exist "%ProgramFiles(x86)%\git" ( + set "PATH=%ProgramFiles(x86)%\git\usr\bin;%PATH%" + set "gitCmd=%ProgramFiles(x86)%\git\usr\bin\mintty.exe" + if not exist "%ProgramFiles(x86)%\git\etc\profile.d\cmder_exinit.sh" ( + echo Run 'mklink "%ProgramFiles^(x86^)%\git\etc\profile.d\cmder_exinit.sh" "%CMDER_ROOT%\vendor\cmder_exinit"' in 'cmd::Cmder as Admin' to use Cmder with external Git Bash + echo. + echo or + echo. + echo Run 'echo "" ^> "%ProgramFiles^(x86^)%\git\etc\profile.d\cmder_exinit.sh"' in 'cmd::Cmder as Admin' to disable this message. + ) +) + +"%gitCmd%" /bin/bash -l diff --git a/vendor/user_init.cmd.template b/vendor/user_init.cmd.template new file mode 100644 index 000000000..82fc90b87 --- /dev/null +++ b/vendor/user_init.cmd.template @@ -0,0 +1,174 @@ +@echo off + +:: This file was autogenerated by Cmder init.bat +:: +:: It is yours to edit and will not be touched again by Cmder. +:: +:: If you wish to recreate this file simply rename it and Cmder will re-create it the next time it is run +:: or run the followin command from a Cmder shell: +:: +:: powershell -f %cmder_root%\vendor\bin\create-cmdercfg.ps1 -shell cmd [-outfile "[filename]"] +:: + +if "%CMDER_CLINK%" == "1" ( + goto :INJECT_CLINK +) else if "%CMDER_CLINK%" == "2" if defined WT_PROFILE_ID ( + goto :INJECT_CLINK +) else if "%CMDER_CLINK%" == "2" ( + goto :CLINK_FINISH +) + +goto :SKIP_CLINK + +:INJECT_CLINK + %print_verbose% "Injecting Clink!" + + :: Check if Clink is not present + if not exist "%CMDER_ROOT%\vendor\clink\clink_%clink_architecture%.exe" ( + goto :SKIP_CLINK + ) + + :: Run Clink + if not exist "%CMDER_CONFIG_DIR%\settings" if not exist "%CMDER_CONFIG_DIR%\clink_settings" ( + echo Generating Clink initial settings in "%CMDER_CONFIG_DIR%\clink_settings" + copy "%CMDER_ROOT%\vendor\clink_settings.default" "%CMDER_CONFIG_DIR%\clink_settings" + echo Additional *.lua files in "%CMDER_CONFIG_DIR%" are loaded on startup. + ) + + if not exist "%CMDER_CONFIG_DIR%\cmder_prompt_config.lua" ( + echo Creating Cmder prompt config file: "%CMDER_CONFIG_DIR%\cmder_prompt_config.lua" + copy "%CMDER_ROOT%\vendor\cmder_prompt_config.lua.default" "%CMDER_CONFIG_DIR%\cmder_prompt_config.lua" + ) + + "%CMDER_ROOT%\vendor\clink\clink_%clink_architecture%.exe" inject --quiet --profile "%CMDER_CONFIG_DIR%" --scripts "%CMDER_ROOT%\vendor" + + if errorlevel 1 ( + %print_error% "Clink initialization has failed with error code: %errorlevel%" + goto :CLINK_FINISH + ) + + set CMDER_CLINK=2 + goto :CLINK_FINISH + +:SKIP_CLINK + %print_warning% "Skipping Clink Injection!" + + for /f "tokens=2 delims=:." %%x in ('chcp') do set cp=%%x + 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 + + chcp %cp%>nul + +:CLINK_FINISH + if not defined GIT_INSTALL_ROOT set "GIT_INSTALL_ROOT=$env:GIT_INSTALL_ROOT" + if not defined SVN_SSH set "SVN_SSH=$env:SVN_SSH" + if not defined git_locale set git_locale=$env:git_locale + if not defined LANG set LANG=$env:lang + if not defined user_aliases set "user_aliases=$env:user_aliases" + if not defined aliases set "aliases=%user_aliases%" + if not defined HOME set "HOME=%USERPROFILE%" + + set PLINK_PROTOCOL=$env:PLINK_PROTOCOL + + set "path=%GIT_INSTALL_ROOT%\cmd;%path%" + + set path_position=append + if %nix_tools% equ 1 ( + set "path_position=append" + ) else ( + set "path_position=" + ) + + if %nix_tools% geq 1 ( + if exist "%GIT_INSTALL_ROOT%\mingw32" ( + if "%path_position%" == "append" ( + set "path=%path%;%GIT_INSTALL_ROOT%\mingw32\bin" + ) else ( + set "path=%GIT_INSTALL_ROOT%\mingw32\bin;%path%" + ) + ) else if exist "%GIT_INSTALL_ROOT%\mingw64" ( + if "%path_position%" == "append" ( + set "path=%path%;%GIT_INSTALL_ROOT%\mingw64\bin" + ) else ( + set "path=%GIT_INSTALL_ROOT%\mingw64\bin;%path%" + ) + ) + if exist "%GIT_INSTALL_ROOT%\usr\bin" ( + if "%path_position%" == "append" ( + set "path=%path%;%GIT_INSTALL_ROOT%\usr\bin" + ) else ( + set "path=%GIT_INSTALL_ROOT%\usr\bin;%path%" + ) + ) + ) + + set "path=%CMDER_ROOT%\vendor\bin;%path%" + +:USER_CONFIG_START + if %max_depth% gtr 1 ( + %lib_path% enhance_path_recursive "%CMDER_ROOT%\bin" 0 %max_depth% + ) else ( + set "path=%CMDER_ROOT%\bin;%path%" + ) + + setlocal enabledelayedexpansion + if defined CMDER_USER_BIN ( + if %max_depth% gtr 1 ( + %lib_path% enhance_path_recursive "%CMDER_USER_BIN%" 0 %max_depth% + ) else ( + set "path=%CMDER_USER_ROOT%\bin;%path%" + ) + ) + endlocal && set "path=%path%" + + set "path=%path%;%CMDER_ROOT%" + + call "%user_aliases%" + + %lib_profile% run_profile_d "%CMDER_ROOT%\config\profile.d" + if defined CMDER_USER_CONFIG ( + %lib_profile% run_profile_d "%CMDER_USER_CONFIG%\profile.d" + ) + + call "%CMDER_ROOT%\config\user_profile.cmd" + if defined CMDER_USER_CONFIG ( + if exist "%CMDER_USER_CONFIG%\user_profile.cmd" ( + call "%CMDER_USER_CONFIG%\user_profile.cmd" + ) + ) + + set "path=%path:;;=;% + +:CMDER_CONFIGURED + if not defined CMDER_CONFIGURED set CMDER_CONFIGURED=1 + + set CMDER_INIT_END=%time% + + if "%time_init%" == "1" if "%CMDER_INIT_END%" neq "" if "%CMDER_INIT_START%" neq "" ( + call "%cmder_root%\vendor\bin\timer.cmd" "%CMDER_INIT_START%" "%CMDER_INIT_END%" + ) + +:CLEANUP + set architecture_bits= + set CMDER_ALIASES= + set CMDER_INIT_END= + set CMDER_INIT_START= + set CMDER_USER_FLAGS= + set debug_output= + set fast_init= + set max_depth= + set nix_tools= + set path_position= + set print_debug= + set print_error= + set print_verbose= + set print_warning= + set time_init= + set verbose_output= + set user_aliases= + +exit /b + + diff --git a/vendor/windows_terminal_default_settings.json b/vendor/windows_terminal_default_settings.json new file mode 100644 index 000000000..908d25453 --- /dev/null +++ b/vendor/windows_terminal_default_settings.json @@ -0,0 +1,390 @@ +{ + "$help": "https://aka.ms/terminal-documentation", + "$schema": "https://aka.ms/terminal-profiles-schema", + "actions": [ + { + "command": { + "action": "copy", + "singleLine": false + }, + "keys": "ctrl+shift+c" + }, + { + "command": "unbound", + "keys": "ctrl+v" + }, + { + "command": "unbound", + "keys": "ctrl+c" + }, + { + "command": "paste" + }, + { + "command": "find", + "keys": "ctrl+shift+f" + }, + { + "command": { + "action": "splitPane", + "split": "auto", + "splitMode": "duplicate" + }, + "keys": "alt+shift+d" + } + ], + "copyFormatting": "none", + "copyOnSelect": true, + "defaultProfile": "{48946353-ebe8-4571-a591-7d609f31327a}", + "newTabMenu": [ + { + "type": "remainingProfiles" + } + ], + "profiles": { + "defaults": { + "colorScheme": "One Half Dark", + "font": { + "face": "Cascadia Code" + } + }, + "list": [ + { + "colorScheme": "One Half Dark", + "commandline": "cmd /k \"%WT_SETTINGS_DIR%\\..\\..\\init.bat\"", + "guid": "{48946353-ebe8-4571-a591-7d609f31327a}", + "hidden": false, + "icon": "%WT_SETTINGS_DIR%\\..\\..\\..\\icons\\cmder.ico", + "name": "Cmder", + "startingDirectory": null, + "tabTitle": "Cmder", + "useAtlasEngine": false + }, + { + "colorScheme": "One Half Dark", + "commandline": "%SystemRoot%\\System32\\cmd.exe /k \"%WT_SETTINGS_DIR%\\..\\..\\init.bat\"", + "elevate": true, + "guid": "{bdd957d0-c15a-49e6-9816-14b02351a071}", + "hidden": false, + "icon": "%WT_SETTINGS_DIR%\\..\\..\\..\\icons\\cmder_red.ico", + "name": "Cmder as Admin", + "startingDirectory": null, + "tabTitle": "Cmder as Admin" + }, + { + "colorScheme": "One Half Dark", + "commandline": "PowerShell -ExecutionPolicy Bypass -NoLogo -NoProfile -NoExit -Command \"Invoke-Expression 'Import-Module ''%WT_SETTINGS_DIR%\\..\\..\\profile.ps1'''\"", + "guid": "{eb1f6578-ce9d-47a9-a8c7-9b3fdd22302d}", + "hidden": false, + "icon": "%WT_SETTINGS_DIR%\\..\\..\\..\\icons\\cmder_orange.ico", + "name": "Cmder - PowerShell", + "startingDirectory": null, + "tabTitle": "Cmder", + "useAtlasEngine": false + }, + { + "colorScheme": "One Half Dark", + "commandline": "PowerShell -ExecutionPolicy Bypass -NoLogo -NoProfile -NoExit -Command \"Invoke-Expression 'Import-Module ''%WT_SETTINGS_DIR%\\..\\..\\profile.ps1'''\"", + "elevate": true, + "guid": "{c5225c3e-8619-4145-8182-2800814eeb17}", + "hidden": false, + "icon": "%WT_SETTINGS_DIR%\\..\\..\\..\\icons\\cmder_purple.ico", + "name": "Cmder - PowerShell as Admin", + "startingDirectory": null, + "tabTitle": "Cmder - PowerShell as Admin", + "useAtlasEngine": false + }, + { + "colorScheme": "One Half Dark", + "commandline": "%WT_SETTINGS_DIR%\\..\\..\\start_git_bash.cmd", + "guid": "{c5c298e9-010e-4b8c-bc55-e3df81846b4c}", + "hidden": false, + "icon": "%WT_SETTINGS_DIR%\\..\\..\\..\\icons\\cmder_blue.ico", + "name": "Cmder - Bash", + "startingDirectory": null, + "tabTitle": "Cmder - Bash" + }, + { + "colorScheme": "One Half Dark", + "commandline": "%WT_SETTINGS_DIR%\\..\\..\\start_git_bash.cmd", + "elevate": true, + "guid": "{545eb9ed-4c1c-49b3-8cc6-7eb41bd280ff}", + "hidden": false, + "icon": "%WT_SETTINGS_DIR%\\..\\..\\..\\icons\\cmder_yellow.ico", + "name": "Cmder - Bash as Admin", + "startingDirectory": null, + "tabTitle": "Cmder - Bash as Admin" + }, + { + "commandline": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", + "guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}", + "hidden": false, + "name": "Windows PowerShell" + }, + { + "commandline": "%SystemRoot%\\System32\\cmd.exe", + "guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}", + "hidden": false, + "name": "Command Prompt" + } + ] + }, + "schemes": [ + { + "background": "#0C0C0C", + "black": "#0C0C0C", + "blue": "#0037DA", + "brightBlack": "#767676", + "brightBlue": "#3B78FF", + "brightCyan": "#61D6D6", + "brightGreen": "#16C60C", + "brightPurple": "#B4009E", + "brightRed": "#E74856", + "brightWhite": "#F2F2F2", + "brightYellow": "#F9F1A5", + "cursorColor": "#FFFFFF", + "cyan": "#3A96DD", + "foreground": "#CCCCCC", + "green": "#13A10E", + "name": "Campbell", + "purple": "#881798", + "red": "#C50F1F", + "selectionBackground": "#FFFFFF", + "white": "#CCCCCC", + "yellow": "#C19C00" + }, + { + "background": "#012456", + "black": "#0C0C0C", + "blue": "#0037DA", + "brightBlack": "#767676", + "brightBlue": "#3B78FF", + "brightCyan": "#61D6D6", + "brightGreen": "#16C60C", + "brightPurple": "#B4009E", + "brightRed": "#E74856", + "brightWhite": "#F2F2F2", + "brightYellow": "#F9F1A5", + "cursorColor": "#FFFFFF", + "cyan": "#3A96DD", + "foreground": "#CCCCCC", + "green": "#13A10E", + "name": "Campbell Powershell", + "purple": "#881798", + "red": "#C50F1F", + "selectionBackground": "#FFFFFF", + "white": "#CCCCCC", + "yellow": "#C19C00" + }, + { + "background": "#282828", + "black": "#282828", + "blue": "#458588", + "brightBlack": "#928374", + "brightBlue": "#83A598", + "brightCyan": "#8EC07C", + "brightGreen": "#B8BB26", + "brightPurple": "#D3869B", + "brightRed": "#FB4934", + "brightWhite": "#EBDBB2", + "brightYellow": "#FABD2F", + "cursorColor": "#FFFFFF", + "cyan": "#689D6A", + "foreground": "#EBDBB2", + "green": "#98971A", + "name": "Gruvbox Dark", + "purple": "#B16286", + "red": "#CC241D", + "selectionBackground": "#FFFFFF", + "white": "#A89984", + "yellow": "#D79921" + }, + { + "background": "#272822", + "black": "#3E3D32", + "blue": "#03395C", + "brightBlack": "#272822", + "brightBlue": "#66D9EF", + "brightCyan": "#66D9EF", + "brightGreen": "#A6E22E", + "brightPurple": "#AE81FF", + "brightRed": "#F92672", + "brightWhite": "#F8F8F2", + "brightYellow": "#FD971F", + "cursorColor": "#FFFFFF", + "cyan": "#66D9EF", + "foreground": "#F8F8F2", + "green": "#A6E22E", + "name": "Monokai", + "purple": "#AE81FF", + "red": "#F92672", + "selectionBackground": "#FFFFFF", + "white": "#F8F8F2", + "yellow": "#FFE792" + }, + { + "background": "#282C34", + "black": "#282C34", + "blue": "#61AFEF", + "brightBlack": "#5A6374", + "brightBlue": "#61AFEF", + "brightCyan": "#56B6C2", + "brightGreen": "#98C379", + "brightPurple": "#C678DD", + "brightRed": "#E06C75", + "brightWhite": "#DCDFE4", + "brightYellow": "#E5C07B", + "cursorColor": "#FFFFFF", + "cyan": "#56B6C2", + "foreground": "#DCDFE4", + "green": "#98C379", + "name": "One Half Dark", + "purple": "#C678DD", + "red": "#E06C75", + "selectionBackground": "#FFFFFF", + "white": "#DCDFE4", + "yellow": "#E5C07B" + }, + { + "background": "#FAFAFA", + "black": "#383A42", + "blue": "#0184BC", + "brightBlack": "#4F525D", + "brightBlue": "#61AFEF", + "brightCyan": "#56B5C1", + "brightGreen": "#98C379", + "brightPurple": "#C577DD", + "brightRed": "#DF6C75", + "brightWhite": "#FFFFFF", + "brightYellow": "#E4C07A", + "cursorColor": "#4F525D", + "cyan": "#0997B3", + "foreground": "#383A42", + "green": "#50A14F", + "name": "One Half Light", + "purple": "#A626A4", + "red": "#E45649", + "selectionBackground": "#FFFFFF", + "white": "#FAFAFA", + "yellow": "#C18301" + }, + { + "background": "#002B36", + "black": "#002B36", + "blue": "#268BD2", + "brightBlack": "#073642", + "brightBlue": "#839496", + "brightCyan": "#93A1A1", + "brightGreen": "#586E75", + "brightPurple": "#6C71C4", + "brightRed": "#CB4B16", + "brightWhite": "#FDF6E3", + "brightYellow": "#657B83", + "cursorColor": "#FFFFFF", + "cyan": "#2AA198", + "foreground": "#839496", + "green": "#859900", + "name": "Solarized Dark", + "purple": "#D33682", + "red": "#DC322F", + "selectionBackground": "#FFFFFF", + "white": "#EEE8D5", + "yellow": "#B58900" + }, + { + "background": "#FDF6E3", + "black": "#002B36", + "blue": "#268BD2", + "brightBlack": "#073642", + "brightBlue": "#839496", + "brightCyan": "#93A1A1", + "brightGreen": "#586E75", + "brightPurple": "#6C71C4", + "brightRed": "#CB4B16", + "brightWhite": "#FDF6E3", + "brightYellow": "#657B83", + "cursorColor": "#002B36", + "cyan": "#2AA198", + "foreground": "#657B83", + "green": "#859900", + "name": "Solarized Light", + "purple": "#D33682", + "red": "#DC322F", + "selectionBackground": "#FFFFFF", + "white": "#EEE8D5", + "yellow": "#B58900" + }, + { + "background": "#000000", + "black": "#000000", + "blue": "#3465A4", + "brightBlack": "#555753", + "brightBlue": "#729FCF", + "brightCyan": "#34E2E2", + "brightGreen": "#8AE234", + "brightPurple": "#AD7FA8", + "brightRed": "#EF2929", + "brightWhite": "#EEEEEC", + "brightYellow": "#FCE94F", + "cursorColor": "#FFFFFF", + "cyan": "#06989A", + "foreground": "#D3D7CF", + "green": "#4E9A06", + "name": "Tango Dark", + "purple": "#75507B", + "red": "#CC0000", + "selectionBackground": "#FFFFFF", + "white": "#D3D7CF", + "yellow": "#C4A000" + }, + { + "background": "#FFFFFF", + "black": "#000000", + "blue": "#3465A4", + "brightBlack": "#555753", + "brightBlue": "#729FCF", + "brightCyan": "#34E2E2", + "brightGreen": "#8AE234", + "brightPurple": "#AD7FA8", + "brightRed": "#EF2929", + "brightWhite": "#EEEEEC", + "brightYellow": "#FCE94F", + "cursorColor": "#000000", + "cyan": "#06989A", + "foreground": "#555753", + "green": "#4E9A06", + "name": "Tango Light", + "purple": "#75507B", + "red": "#CC0000", + "selectionBackground": "#FFFFFF", + "white": "#D3D7CF", + "yellow": "#C4A000" + }, + { + "background": "#000000", + "black": "#000000", + "blue": "#000080", + "brightBlack": "#808080", + "brightBlue": "#0000FF", + "brightCyan": "#00FFFF", + "brightGreen": "#00FF00", + "brightPurple": "#FF00FF", + "brightRed": "#FF0000", + "brightWhite": "#FFFFFF", + "brightYellow": "#FFFF00", + "cursorColor": "#FFFFFF", + "cyan": "#008080", + "foreground": "#C0C0C0", + "green": "#008000", + "name": "Vintage", + "purple": "#800080", + "red": "#800000", + "selectionBackground": "#FFFFFF", + "white": "#C0C0C0", + "yellow": "#808000" + } + ], + "themes": [], + "useAcrylicInTabRow": true, + "wordDelimiters": " ()\"',;<>!@#$%^&*|+=[]{}~?\u2502" +}