PowerShell美化指南
macOS之所以被很多程序员喜爱,一个是它是*nix内核, 能够很简单、方便地做到一些在Windows上很复杂的事情,比如说安装环境,在Windows上如果没有prebuilt的二进制文件可以下载,有东西要自己编译,事情就会变得相当麻烦。
另一个,基于*nix内核,macOS可以非常方便地使用Shell,搭配oh-my-zsh之类的框架使用,可以进一步提升它的使用效率,当然也能让Shell变得更好看。
在现实中很多程序员还是在使用Windows,然而在Windows上,即使微软推出了更加贴近Linux一些的Windows PowerShell,但是它的能力还是有限。
这篇指南将会告诉你怎么优化、美化你的PowerShell,让它能够给你一个和macOS的zsh类似的感觉。
准备工作
首先你需要准备以下一些东西:
1、PowerShell 7.x(不是系统自带的Windows PowerShell)
2、Scoop
3、Windows Terminal(微软商店下载)
4、一款你喜欢的NerdFont
在上述软件/字体都安装好之后,你需要在PowerShell里执行一下策略:
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
之后,我们就可以开始我们的美化操作了。
安装oh-my-posh
第一步是安装oh-my-posh,我们可以简单地用Scoop安装:
scoop install https://github.com/JanDeDobbeleer/oh-my-posh3/releases/latest/download/oh-my-posh.json
我们安装的版本是oh-my-posh 3,它能够给我们的PowerShell提供一个非常好看的样式。
用Scoop安装好之后,我们打开PowerShell,键入如下内容:
notepad $profile
打开Profile文件进行编辑,下面是oh-my-posh 3官方给出的一个参考配置:
[ScriptBlock]$Prompt = {
    $lastCommandSuccess = $?
    $realLASTEXITCODE = $global:LASTEXITCODE
    $errorCode = 0
    if ($lastCommandSuccess -eq $false) {
        #native app exit code
        if ($realLASTEXITCODE -is [int]) {
            $errorCode = $realLASTEXITCODE
        }
        else {
            $errorCode = 1
        }
    }
    $startInfo = New-Object System.Diagnostics.ProcessStartInfo
    $startInfo.FileName = "C:\tools\oh-my-posh.exe"
    $cleanPWD = $PWD.ProviderPath.TrimEnd("\")
    $startInfo.Arguments = "-config=""$env:USERPROFILE\.poshthemes\jandedobbeleer.omp.json"" -error=$errorCode -pwd=""$cleanPWD"""
    $startInfo.Environment["TERM"] = "xterm-256color"
    $startInfo.CreateNoWindow = $true
    $startInfo.StandardOutputEncoding = [System.Text.Encoding]::UTF8
    $startInfo.RedirectStandardOutput = $true
    $startInfo.UseShellExecute = $false
    if ($PWD.Provider.Name -eq 'FileSystem') {
      $startInfo.WorkingDirectory = $PWD.ProviderPath
    }
    $process = New-Object System.Diagnostics.Process
    $process.StartInfo = $startInfo
    $process.Start() | Out-Null
    $standardOut = $process.StandardOutput.ReadToEnd()
    $process.WaitForExit()
    $standardOut
    $global:LASTEXITCODE = $realLASTEXITCODE
    #remove temp variables
    Remove-Variable realLASTEXITCODE -Confirm:$false
    Remove-Variable lastCommandSuccess -Confirm:$false
}
Set-Item -Path Function:prompt -Value $Prompt -Force
把这一大段先复制粘贴进去,需要注意的是这里面有一个oh-my-posh.exe的路径,还有一个主题文件,也就是jandedobbeleer.omp.json,由于我们是通过Scoop安装的,这两个路径实际上不存在。
我们需要手动把这两个路径改一下。
oh-my-posh.exe的位置:
C:\Users\[USER]\scoop\apps\oh-my-posh\current\oh-my-posh.exe
注意其中的[USER]对应你当前的Windows用户,这是在你的Windows用户文件夹下面。
主题文件jandedobbeleer.omp.json的位置:
C:\Users\[USER]\scoop\apps\oh-my-posh\current\themes\jandedobbeleer.omp.json
这个主题文件你是可以自行配置的,虽然工具作者说默认主题满足大多数用户的需要,但是我自己认为它还是有一点点花哨。
下面是我自己调的一个配置,搭配的字体是FiraMono NF:
{
  "blocks": [
    {
      "type": "prompt",
      "alignment": "left",
      "segments": [
        {
          "type": "session",
          "style": "diamond",
          "foreground": "#ffffff",
          "background": "#c386f1",
          "leading_diamond": "\uE0B6",
          "trailing_diamond": "\uE0B0"
        },
        {
          "type": "path",
          "style": "powerline",
          "powerline_symbol": "\uE0B0",
          "foreground": "#ffffff",
          "background": "#ff479c",
          "properties": {
            "prefix": " \uE5FF ",
            "style": "agnoster_full"
          }
        },
        {
          "type": "git",
          "style": "powerline",
          "powerline_symbol": "\uE0B0",
          "foreground": "#193549",
          "background": "#fffb38",
          "properties": {
            "display_status": false,
            "display_status_detail": false,
            "display_stash_count": true,
            "display_upstream_icon": true
          }
        },
        {
          "type": "root",
          "style": "powerline",
          "powerline_symbol": "\uE0B0",
          "foreground": "#ffffff",
          "background": "#ffff66"
        },
        {
          "type": "exit",
          "style": "diamond",
          "foreground": "#ffffff",
          "background": "#2e9599",
          "leading_diamond": "",
          "trailing_diamond": "\uE0B4",
          "properties": {
            "display_exit_code": false,
            "always_enabled": false,
            "error_color": "#f1184c",
            "color_background": true,
            "prefix": "<transparent>\uE0B0</> \uE23A"
          }
        }
      ]
    }
  ],
  "final_space": true
}
配置完成后在PowerShell里输入. $profile就可以看到效果,如果你是在VSCode或者命令行窗口里使用,出于渲染的问题,你看到的效果可能会有一些怪,在Windows Terminal下效果是最好的。
到这里第一步美化结束。
这里附上oh-my-posh的官方文档,你可以对照文档调整你自己的主题配置:
安装PSReadLine
第二个需要安装的东西叫PSReadLine,你可以选择性地安装预览版或者稳定版,这里我个人推荐安装预览版。
Install-Module PSReadLine -AllowPrerelease -Force
在PowerShell里执行这一行就可以进行安装,安装完成后我们需要再次通过notepad $profile进行一些设置。
我们在Profile里面增加下面这些内容:
Import-Module PSReadLine
Set-PSReadLineOption -PredictionSource History # 设置预测文本来源为历史记录
Set-PSReadlineKeyHandler -Key Tab -Function Complete # 设置 Tab 键补全
Set-PSReadLineKeyHandler -Key "Ctrl+f" -Function MenuComplete # 设置 Ctrl+d 为菜单补全和 Intellisense
Set-PSReadLineKeyHandler -Key "Ctrl+z" -Function Undo # 设置 Ctrl+z 为撤销
Set-PSReadLineKeyHandler -Key UpArrow -Function HistorySearchBackward # 设置向上键为后向搜索历史记录
Set-PSReadLineKeyHandler -Key DownArrow -Function HistorySearchForward # 设置向下键为前向搜索历史纪录
我们把模块引进来,然后做一些设置。
添加好之后我们就可以基于历史执行过的命令来进行一些快速的命令补全。
安装posh-git
这个东西是专门针对git做的命令补全模块,支持Ctrl+D的菜单补全,支持列出所有可用的分支、Tag等等。
安装方法也很简单,执行下面这一条命令即可:
Install-Module posh-git -Scope CurrentUser -AllowPrerelease -Force
然后你只需要在Profile里引入就好了:
Import-Module posh-git
安装npm-completion
对于前端开发者,你可能需要npm-completion。
PowerShell-Completion/npm-completion
安装方式一样很简单,和posh-git差不多:
Install-Module npm-completion -Scope CurrentUser
然后在Profile里引入:
Import-Module npm-completion
如果你用的不是npm,而是yarn,那么你也可以安装一个posh-yarn-completion。
其他
到这里我们的美化基本上就结束了,在GitHub上还有一些其他项目,比如Docker的补全matt9ucci/DockerCompletion,这些你都可以根据自己的实际需要安装。
类似的项目并不难找,动手能力强大的朋友也可以根据自己的习惯开发/修改类似的模块。