notes/config/win10/terminal/Powershell5_profile.ps1

1062 lines
21 KiB
PowerShell
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

& {
$private:msg = @"
___ ___
(o o) (o o)
( V ) Hi, PowerShell5! ( V )
--m-m----------------------m-m--
"@
Write-Host $Msg -ForegroundColor DarkYellow
}
<#
NOTE: PowerShell5 配置文件 $Profile 的编码格式必须是 UTF-8(BOM) Byte Order Mark
一般而言Windows PowerShell 默认使用 Unicode UTF-16LE 编码。 但是Windows PowerShell 中 cmdlet 使用的默认编码不一致。
参考 https://learn.microsoft.com/zh-cn/powershell/module/microsoft.powershell.core/about/about_character_encoding?view=powershell-5.1
从 PowerShell 5.1 开始,重定向运算符(> 和 >>)调用 Out-File cmdlet。
因此,可以使用 $PSDefaultParameterValues 首选项变量设置它们的默认编码,如以下示例所示:
$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
使用以下语句可更改具有 Encoding 参数的所有 cmdlet 的默认编码。
$PSDefaultParameterValues['*:Encoding'] = 'utf8'
#>
$PSDefaultParameterValues['*:Encoding'] = 'utf8'
$OutputEncoding = [Console]::InputEncoding = [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding
Invoke-Expression (& { (zoxide init powershell | Out-String) })
if (Get-Command nvim -ErrorAction SilentlyContinue) {
Set-Alias vi nvim
} elseif (Get-Command vim -ErrorAction SilentlyContinue) {
Set-Alias vi vim
}
# On MacOS, $platform is Unix
# On Win10, $platform is Win32NT
# $platform = [System.Environment]::OSVersion.Platform
# ======================= Import Modules =======================
Import-Module PSReadLine
# Auto complete
Set-PSReadlineOption -EditMode Emacs
# Set-PSReadlineOption -PredictionSource History
Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete
Set-PSReadlineOption -Color @{
Command = "DarkGreen"
Comment = "Gray"
Error = "DarkRed"
Number = "White"
String = "White"
Keyword = "DarkYellow"
Default = "DarkGray"
Operator = "Gray"
Type = "DarkBlue"
}
# Auto complete commands from history
Set-PSReadlineKeyHandler -Key UpArrow -Function HistorySearchBackward
Set-PSReadlineKeyHandler -Key DownArrow -Function HistorySearchForward
Set-PSReadlineKeyHandler -Key "Ctrl+z" -Function Undo
function GitCurrentBranch {
$branch = $(git rev-parse --abbrev-ref HEAD) 2>$null
if ($branch -eq "" -or $null -eq $branch) {
return $null
}
return $branch
}
function IsGitRepo {
$branch = $GitCurrentBranch
return $null -eq $branch
}
function GitStashCount {
param (
[string[]] $Lines
)
$stash = $Lines | Where-Object -FilterScript { $_.StartsWith("# stash")}
if ($null -eq $stash -or "" -eq $stash) {
return 0
}
$tmp = $stash -split " "
return [int] $tmp[2]
}
function GitTagByCommit {
param (
[string] $CommitId
)
$tag = $(git tag --points-at $CommitId) 2> $null
if ($tag -eq "" -or $null -eq $tag) {
$tag = ""
} else { # 🚩 § ⚡ 🏷 🏷️
# $tag = "  {0}" -f $tag
$tag = "🚩{0}" -f $tag
}
return $tag
}
function GitOid {
param (
[string[]]$Lines
)
$branchOid = $Lines | Where-Object -FilterScript { $_.StartsWith("# branch.oid") }
if ($null -eq $branchOid -or $branchOid -eq "") {
return ""
}
$tmp= $branchOid -split " "
$longCommitId = $tmp[2]
$commitId = $longCommitId.Substring(0, 7)
return $commitId
}
function GitBranchInfo {
param (
[string[]] $Lines
)
$CommitId = $(GitOid $Lines)
$branchInfo = $Lines | Where-Object -FilterScript { $_.StartsWith("# branch.head") }
$tmp = $branchInfo -split " "
$branchName = $tmp[2]
$tag = $(GitTagByCommit $CommitId)
if ($branchName -eq "(detached)") {
$branchName = "{0}{1}" -f $CommitId, $tag
} else {
$branchName = "{0}{1}" -f $branchName, $tag
}
return $branchName
}
function GitUpstream {
param (
[string[]]$Lines
)
$upstream = ""
$upstreamInfo = $lines | Where-Object -FilterScript { $_.StartsWith("# branch.upstream") }
if ($null -ne $upstreamInfo -and $upstreamInfo -ne "") {
$tmp = $upstreamInfo -split " "
$upstream = $tmp[2]
}
return $upstream
}
function GitDiff {
param (
[string[]]$Lines
)
$diffInfo = $lines | Where-Object -FilterScript { $_.StartsWith("# branch.ab") }
$ahead = 0
$behind = 0
if ($null -ne $diffInfo -and $diffInfo -ne "") {
$tmp = $diffInfo -split " "
$ahead = [int]$tmp[2]
$behind = [System.Math]::Abs([int]$tmp[3])
}
return $ahead, $behind
}
function GitChange {
param (
[string[]]$Lines
)
$stagingList = $Lines | Where-Object -FilterScript { $_.StartsWith("1") -or $_.StartsWith("2") }
$totalChanged = 0
$added = 0
$modified = 0
$deleted = 0
$unstaged = 0
$staged = 0
if ($null -ne $stagingList) {
$totalChanged = $stagingList.Count
foreach ($line in $stagingList) {
$tmp = $line -split " "
$flag = $tmp[1]
if ($flag.Contains("A")) {
$added++
} elseif ($flag.Contains("M") -or $flag.Contains("R")) {
$modified++
} elseif ($flag.Contains("D")) {
$deleted++
}
if ("." -eq $flag[0]) {
$unstaged++
}
if ("." -eq $flag[1]) {
$staged++
}
}
}
return $added, $modified, $deleted, $totalChanged, $unstaged, $staged
}
function GitUntracked {
param (
[string[]]$Lines
)
$untrackedList = $lines | Where-Object -FilterScript { $_.StartsWith("?") }
$untrackedNum = 0
if ($null -ne $untrackedList) {
$untrackedNum = $untrackedList.Count
}
return $untrackedNum
}
function GitConflict {
param (
[string[]] $Lines
)
$conflicts = $Lines | Where-Object -FilterScript { $_.StartsWith("u") }
$conflictNum = 0
if ($null -ne $conflicts) {
$conflictNum = $conflicts.Count
}
return $conflictNum
}
function GetGitInfo {
$lines = $(git --no-optional-locks status --porcelain=2 --branch --show-stash) 2> $null
if ($lines -eq "" -or $null -eq $lines) {
return $null
}
# output example
# branch.oid eef0ee61f64a0ccecafa75ca338f8e958725ce95
# branch.head master
# branch.upstream origin/master
# branch.ab +0 -0
$branchName = $(GitBranchInfo $lines)
$upstream = $(GitUpstream $lines)
$ahead, $behind = $(GitDiff $lines)
$added, $modified, $deleted, $totalChanged, $unstaged, $staged = $(GitChange $lines)
$untrackedNum = $(GitUntracked $lines)
$conflictNum = $(GitConflict $lines)
$stashed = $(GitStashCount $lines)
$info = @{
BranchName = $branchName
Upstream = $upstream
Ahead = $ahead
Behind = $behind
Added = $added
Modified = $modified
Deleted = $deleted
TotalChanged = $totalChanged
Unstaged = $unstaged
Staged = $staged
ConflictNum = $conflictNum
Stashed = $stashed
UntrackedNum = $untrackedNum
}
return $info
}
function WriteGitInfo {
# git prompt
$gitInfo = $(GetGitInfo)
# Write-Host $gitInfo -NoNewline
if ($null -eq $gitInfo) {
return
}
Write-Host "(" -ForegroundColor DarkGreen -NoNewline
$branchName = "{0}" -f $gitInfo.BranchName
Write-Host $branchName -ForegroundColor DarkBlue -NoNewline
if ($gitInfo.Ahead -gt 0) {
$tmp = "↑{0}" -f $gitInfo.Ahead
Write-Host $tmp -ForegroundColor DarkGreen -NoNewline
}
if ($gitInfo.Behind -gt 0) {
$tmp = "↓{0}" -f $gitInfo.Behind
Write-Host $tmp -ForegroundColor DarkRed -NoNewline
}
if ($gitInfo.Stashed -gt 0) {
$tmp = "▣{0}" -f $gitInfo.Stashed
Write-Host $tmp -ForegroundColor DarkCyan -NoNewline
}
if ($gitInfo.UntrackedNum -gt 0) {
$tmp = "?{0}" -f $gitInfo.UntrackedNum
Write-Host $tmp -ForegroundColor Magenta -NoNewline
}
if ($gitInfo.Added -gt 0 -or
$gitInfo.Modified -gt 0 -or
$gitInfo.Deleted -gt 0 -or
$gitInfo.TotalChanged -gt 0) {
Write-Host "|" -ForegroundColor White -NoNewline
}
if ($gitInfo.TotalChanged -gt 0) {
$tmp = "±{0}:" -f $gitInfo.TotalChanged # ⁕
Write-Host $tmp -ForegroundColor DarkMagenta -NoNewline
}
if ($gitInfo.Added -gt 0) {
$tmp = "+{0}" -f $gitInfo.Added
Write-Host $tmp -ForegroundColor DarkGreen -NoNewline
}
if ($gitInfo.Modified -gt 0) {
$tmp = "~{0}" -f $gitInfo.Modified
Write-Host $tmp -ForegroundColor DarkYellow -NoNewline
}
if ($gitInfo.Deleted -gt 0) {
$tmp = "-{0}" -f $gitInfo.Deleted
Write-Host $tmp -ForegroundColor DarkRed -NoNewline
}
if ($gitInfo.Unstaged -gt 0 -or
$gitInfo.Staged -gt 0) {
Write-Host "|" -ForegroundColor White -NoNewline
}
if ($gitInfo.Unstaged -gt 0) {
$tmp = "✗{0}" -f $gitInfo.Unstaged
Write-Host $tmp -ForegroundColor DarkRed -NoNewline
}
if ($gitInfo.Staged -gt 0) {
$tmp = "✓{0}" -f $gitInfo.Staged
Write-Host $tmp -ForegroundColor DarkGreen -NoNewline
}
if ($gitInfo.ConflictNum -gt 0) {
$tmp = "|merge:{0}" -f $gitInfo.ConflictNum
Write-Host $tmp -ForegroundColor Red -NoNewline
}
Write-Host ") " -ForegroundColor DarkGreen -NoNewline
}
function Prompt {
# $arrow = " "
$arrow = ""
Write-Host "# " -ForegroundColor White -NoNewline
# $lastStatus = $?
if ($IsWindows) { # Besides, $IsLinux and $IsMacOS are available
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = [Security.Principal.WindowsPrincipal] $identity
$adminRole = [Security.Principal.WindowsBuiltInRole]::Administrator
if($principal.IsInRole($adminRole)) {
Write-Host "[ADMIN!] " -ForegroundColor DarkRed -NoNewline
}
}
# Write time info
Write-Host "[$(Get-Date -Format "HH:mm:ss")] " -ForegroundColor DarkMagenta -NoNewline
# Write current directory
$cwd = $(Get-Location).ToString()
if ($cwd.StartsWith($Home)) {
$reg = "^({0})?" -f $Home
$reg = $reg.Replace("\", "\\")
$cwd = $cwd -replace $reg, "~"
}
Write-Host "$cwd " -ForegroundColor DarkCyan -NoNewline
$(WriteGitInfo)
# Write-Host "" -ForegroundColor DarkCyan -NoNewline
# if ($lastStatus) {
# Write-Host "" -ForegroundColor DarkCyan -NoNewline
# } else {
# Write-Host "" -ForegroundColor DarkRed -NoNewline
# }
return "$arrow"
}
function man {
Get-Help -Detailed $args
}
# Remove conflict aliases in Powershell 5
Remove-Item Alias:gc -Force -ErrorAction SilentlyContinue # Get-Content
Remove-Item Alias:gl -Force -ErrorAction SilentlyContinue # Get-Location
Remove-Item Alias:gp -Force -ErrorAction SilentlyContinue # Get-Property
Remove-Item Alias:gcb -Force -ErrorAction SilentlyContinue
Remove-Item Alias:gcm -Force -ErrorAction SilentlyContinue
Remove-Item Alias:type -Force -ErrorAction SilentlyContinue # Get-Content
# Remove-Alias gcs
# Remove-Alias gm
# Remove-Alias gpv
# Define aliases or function similar to *nix
Set-Alias type Get-Command
Set-Alias pbcopy Set-Clipboard
Set-Alias pbpaste Get-Clipboard
function GitMainBranch {
$MainBranch = $(git branch --list main) 2> $null
if (![string]::IsNullOrWhiteSpace($MainBranch) -and $MainBranch.Contains("main")) {
return "main"
}
return "master"
}
# Define git aliases referring to git plugin of oh-my-zsh.
function g {
git $args
}
function ga {
git add $args
}
function gaa {
git add --all $args
}
function gapa {
git add --patch $args
}
function gau {
git add --update $args
}
function gb {
git branch $args
}
function gba {
git branch -a $args
}
function gbd {
param (
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[ArgumentCompleter({
param($pCmd, $pParam, $pWord, $pAst, $pFakes)
$MergedBranchs = $(git branch --merged | Select-String "^(\*|\s*(master|main|develop|dev)\s*$)" -NotMatch).Line
if ([string]::IsNullOrEmpty($pWord)) {
return $MergedBranchs | ForEach-Object { $_.Trim() }
}
$MergedBranchs | Select-String "$pWord"
})]
[string] $branch
)
git branch -d $branch
}
function gbdf {
param (
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[ArgumentCompleter({
param($pCmd, $pParam, $pWord, $pAst, $pFakes)
$MergedBranchs = $(git branch --merged | Select-String "^(\*|\s*(master|main|develop|dev)\s*$)" -NotMatch).Line
if ([string]::IsNullOrEmpty($pWord)) {
return $MergedBranchs | ForEach-Object { $_.Trim() }
}
$MergedBranchs | Select-String "$pWord"
})]
[string] $branch
)
git branch -D $branch
}
function gbda {
$MergedBranchs = $(git branch --merged | Select-String "^(\*|\s*(master|main|develop|dev)\s*$)" -NotMatch).Line
$MergedBranchs | ForEach-Object {
if ([string]::IsNullOrEmpty($_)) {
return
}
git branch -d $_.Trim()
}
}
function gbl {
git blame -b -w $args
}
function gbnm {
git branch --no-merged $args
}
function gbr {
git branch --remote $args
}
function gbs {
git bisect $args
}
function gbsb {
git bisect bad $args
}
function gbsg {
git bisect good $args
}
function gbsr {
git bisect reset $args
}
function gbss {
git bisect start $args
}
function gc {
git commit -v $args
}
function gc! {
git commit -v --amend $args
}
function gca {
git commit -v -a $args
}
function gcam {
git commit -a -m $args
}
function gca! {
git commit -v -a --amend $args
}
function gcan! {
git commit -v -a -s --no-edit --amend $args
}
function gcb {
git checkout -b $args
}
function gcf {
git config --list $args
}
function gcl {
git clone --recursive $args
}
function gclean {
git clean -df $args
}
function gcm {
git checkout $(GitMainBranch) $args
}
function gcd {
git checkout develop $args
}
function gcmsg {
git commit -m $args
}
function gco {
# git checkout $args
param(
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[ArgumentCompleter({
param($pCmd, $pParam, $pWord, $pAst, $pFakes)
$branchList = $(git branch --format='%(refname:short)') 2> $null
$tagList = $(git tag) 2> $null
$items = @( $branchList ) + @( $tagList )
if ([string]::IsNullOrWhiteSpace($pWord)) {
return $items | ForEach-Object { $_.Trim() }
}
$items | Select-String "$pWord"
})]
[string] $branch
)
git checkout $branch;
}
function gcount {
git shortlog -sn $args
}
function gcp {
git cherry-pick $args
}
function gcpa {
git cherry-pick --abort $args
}
function gcpc {
git cherry-pick --continue $args
}
function gcs {
git commit -S $args
}
function gd {
git diff $args
}
function gdca {
git diff --cached $args
}
function gdt {
git diff-tree --no-commit-id --name-only -r $args
}
function gdw {
git diff --word-diff $args
}
function gf {
git fetch $args
}
function gfa {
git fetch --all --prune $args
}
function gfo {
git fetch origin $args
}
function gg {
git gui citool $args
}
function gga {
git gui citool --amend $args
}
function ggf {
$CurrentBranch = $(GitCurrentBranch)
git push --force origin $CurrentBranch
}
function ggfl {
$CurrentBranch = $(GitCurrentBranch)
git push --force-with-lease origin $CurrentBranch
}
function ghh {
git help $args
}
function ggsup {
$CurrentBranch = $(GitCurrentBranch)
git branch --set-upstream-to=origin/$CurrentBranch
}
function gpsup {
$CurrentBranch = $(GitCurrentBranch)
git push --set-upstream origin $CurrentBranch
}
function gignore {
git update-index --assume-unchanged $args
}
function gignored {
git ls-files -v | Select-String "^[a-z]" -CaseSensitive
}
function glg {
git log --stat --color $args
}
function glgg {
git log --graph --color $args
}
function glgga {
git log --graph --decorate --all $args
}
function glgm {
git log --graph --max-count=10 $args
}
function glgp {
git log --stat --color -p $args
}
function glo {
git log --oneline --decorate --color $args
}
function glog {
git log --oneline --decorate --color --graph $args
}
function glol {
git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit $args
}
function glola {
git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --all $args
}
function gmerge {
git merge $args
}
function gmom {
git merge origin/$(GitMainBranch) $args
}
function gmt {
git mergetool --no-prompt $args
}
function gmtvim {
git mergetool --no-prompt --tool=vimdiff $args
}
function gmum {
git merge upstream/$(GitMainBranch) $args
}
function gpd {
git push --dry-run $args
}
function gpf {
git push --force-with-lease $args
}
function gpf! {
git push --force $args
}
function gpoat {
git push origin --all
git push origin --tags
}
function gpristine {
git reset --hard
git clean -dfx
}
function gpu {
git push upstream $args
}
function gpull {
git pull $args
}
function gpush {
git push $args
}
function gpushv {
git push -v $args
}
function gr {
git remote $args
}
function gra {
git remote add $args
}
function grb {
git rebase $args
}
function grba {
git rebase --abort $args
}
function grbc {
git rebase --continue $args
}
function grbi {
git rebase -i $args
}
function grbm {
git rebase $(GitMainBranch) $args
}
function grbs {
git rebase --skip $args
}
function grh {
git reset $args
}
function grhh {
git reset --hard $args
}
function grmv {
git remote rename $args
}
function grrm {
git remote remove $args
}
function grset {
git remote set-url $args
}
function grt {
try {
$RootPath = git rev-parse --show-toplevel
}
catch {
$RootPath = "."
}
Set-Location $RootPath
}
function gru {
git reset -- $args
}
function grup {
git remote update $args
}
function grv {
git remote -v $args
}
function gsb {
git status -sb $args
}
function gsd {
git svn dcommit $args
}
function gsh {
git show $args
}
function gsi {
git submodule init $args
}
function gsps {
git show --pretty=short --show-signature $args
}
function gsr {
git svn rebase $args
}
function gss {
git status -s $args
}
function gst {
git status $args
}
function gsta {
git stash save $args
}
function gstaa {
git stash apply $args
}
function gstd {
git stash drop $args
}
function gstl {
git stash list $args
}
function gstp {
git stash pop $args
}
function gstc {
git stash clear $args
}
function gsts {
git stash show --text $args
}
function gsu {
git submodule update $args
}
function gts {
git tag -s $args
}
function gunignore {
git update-index --no-assume-unchanged $args
}
function gunwip {
Write-Output $(git log -n 1 | Select-String "--wip--" -Quiet).Count
git reset HEAD~1
}
function gpr {
git pull --rebase $args
}
function gupv {
git pull --rebase -v $args
}
function glum {
git pull upstream $(GitMainBranch) $args
}
function gvt {
git verify-tag $args
}
function gwch {
git whatchanged -p --abbrev-commit --pretty=medium $args
}
function gwip {
git add -A
git rm $(git ls-files --deleted) 2> $null
git commit --no-verify -m "--wip-- [skip ci]"
}
function ggl {
$CurrentBranch = $(GitCurrentBranch)
git pull origin $CurrentBranch
}
function ggpush {
$CurrentBranch = $(GitCurrentBranch)
git push origin $CurrentBranch
}
<#
.SYNOPSIS
A simple wrap function of ssh. Auto completion of servers are added.
.DESCRIPTION
A simple wrap function of ssh. Auto completion of servers are added.
.PARAMETER RemoteHost
Remote Server Hosts, can be automatically completed.
.EXAMPLE
pssh root@192.168.2.1
pssh -V
pssh -h
#>
function pssh {
param(
# [Parameter(Mandatory)]
# [ValidateNotNullOrEmpty()]
[ArgumentCompleter({
param($pCmd, $pParam, $pWord, $pAst, $pFakes)
$items = @( "root@192.168.2.1", "root@192.168.2.2")
if ([string]::IsNullOrWhiteSpace($pWord)) {
return $items | ForEach-Object { $_.Trim() }
}
$items | Select-String "$pWord"
})]
[String] $RemoteHost
)
if ([string]::IsNullOrWhiteSpace($RemoteHost)) {
ssh $args
} else {
ssh $RemoteHost
}
}
# Useful custom functions
function Convert-Files($path, $source, $dest) {
Get-ChildItem -File -Recurse $path | ForEach-Object {
Convert-File $_.FullName $source $dest
}
}
function Convert-File($file, $source, $dest) {
$utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False)
Write-Host -ForegroundColor Darkgreen "Conversion finished: ", $file
$x =[System.IO.File]::ReadAllText($file)
$content = $x -replace $source, $dest
[System.IO.File]::WriteAllText($file, $content, $utf8NoBomEncoding)
}
function dos2unix($pattern) {
Convert-Files $pattern "`r`n" "`n"
}
function unix2dos($pattern) {
Convert-Files $pattern "`n" "`r`n"
}
function open($path) {
if ($path) {
Invoke-Item $path
} else {
Invoke-Item "."
}
}
function timestamp {
$timestamp = [DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds()
Write-Host $timestamp
}
function which {
param (
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string] $Cmd
)
$cmdInfo = $(Get-Command $Cmd)
if ($null -eq $cmdInfo) {
return
}
Write-Output $cmdInfo.Source
}
function tig {
git -c alias.tig=!tig tig
}