曾经非常羡慕mac平台上的iTerm2+oh-my-zsh组合,可以实现一个非常好看又实用的终端,十分希望windows平台上也有类似的东西,然而在很长时间里都没有出现,以前最好的方案还是cmder,直到微软发布了Windows Terminal。
Windows Terminal
Windows Terminal正式版已经发布了,可以直接通过Windows商店安装,现在已经支持可视化的设置界面了,大多数的美化教程可能都会介绍Windows Terminal结合WSL使用,但我个人使用下来发现几个问题:一个是WSL启动较慢,二是开启WSL后vmmem会占用大量内存,第三是通过vscode访问WSL有时会出现断开连接,所以我放弃了WSL这个方案。
oh-my-posh
oh-my-posh是PowerShell的一套主题,听名字就知道和oh-my-zsh是类似的,最新版本是 Oh My Posh 3
开始安装
oh-my-posh的安装还是比较简单的
- 通过管理员权限打开PowerShell
- 绕过PowerShell执行策略,使其可以执行脚本文件
Set-ExecutionPolicy Bypass
复制代码
- 安装oh-my-posh主题
Install-Module oh-my-posh -Scope CurrentUser
复制代码
- 安装posh-git将git信息添加到提示中
Install-Module posh-git -Scope CurrentUser
复制代码
注意:如果中途有询问,直接Y或A就好了
- 通过这个 地址 下载安装字体,推荐安装DejaVuSansMono Nerd Font(其他的我也没试过)
修改配置
安装完成之后,修改PowerShell的配置文件
- 启动编辑PowerShell配置文件的引擎
if (!(Test-Path -Path $PROFILE )) { New-Item -Type File -Path $PROFILE -Force }
复制代码
- 使用vscode打开配置文件(也可以用其他方式打开),配置文件地址一般是:C:Users${username}DocumentsWindowsPowerShellMicrosoft.PowerShell_profile.ps1
code $PROFILE
复制代码
- 添加以下配置内容
Import-Module posh-git # 导入posh-git
Import-Module oh-my-posh # 导入oh-my-posh
Set-PoshPrompt -Theme M365Princess # 设置主题为M365Princess
复制代码
- 最终效果如图,也可以通过Get-PoshThemes查看全部可用主题
自定义别名
本来美化教程到这儿就差不多结束了,但是有一说一,这个东西网上的教程其实已经有很多了,在这儿发一个类似的东西属实没啥必要,所以下面要整点不一样的东西。
通过上面那个配置文件,可以自定义一些命令行的别名,类似于一些简单的跳转:
function Go-Up {
# 跳转上级
cd ../
}
function Go-Home {
# 跳转根目录
cd ~
}
Set-Alias '..' Go-up
Set-Alias '~' Go-Home
复制代码
在使用PowerShell的过程中,一直有个不太喜欢的点,就是PowerShell查看当前目录下的文件可以使用 ls、dir、Get-ChildItem,这几个效果都是一样的,如下:
而我想要实现类似于bash的文件名称横向排布,并且不同的文件类型显示不同的颜色的输出,类似于下图:
PowerShell没有提供类似的方法,但我们可以自定义实现,代码如下:
# >>> 移除默认别名 >>>
Remove-Item alias:ls
# >>> 自定义函数 >>>
function Color-List($str) {
$regex_opts = ([System.Text.RegularExpressions.RegexOptions]::IgnoreCase-bor [System.Text.RegularExpressions.RegexOptions]::Compiled)
$fore = $Host.UI.RawUI.ForegroundColor
$compressed = New-Object System.Text.RegularExpressions.Regex('.(zip|tar|gz|rar|jar|war|7z)$', $regex_opts)
$executable = New-Object System.Text.RegularExpressions.Regex('.(exe|bat|cmd|py|ps1|psm1|vbs|rb|reg|sh|zsh)$', $regex_opts)
$code_files = New-Object System.Text.RegularExpressions.Regex('.(ini|csv|log|xml|yml|json|JAVA|c|cpp|css|sass|js|ts|jsx|tsx|vue)$', $regex_opts)
$itemList = @()
Invoke-Expression ("Get-ChildItem" + " " + $str) | ForEach-Object {
$item = New-Object object
if ($_.GetType().Name -eq 'DirectoryInfo')
{
$item | Add-Member NoteProperty name ("`e[34m" + $_.name) # 目录名称蓝色
}
elseif ($compressed.IsMatch($_.Name))
{
$item | Add-Member NoteProperty name ("`e[31m" + $_.name) # 压缩文件红色
}
elseif ($executable.IsMatch($_.Name))
{
$item | Add-Member NoteProperty name ("`e[36m" + $_.name) # 可执行文件青色
}
elseif ($code_files.IsMatch($_.Name))
{
$item | Add-Member NoteProperty name ("`e[33m" + $_.name) # 代码文件黄色
}
else
{
$item | Add-Member NoteProperty name ("`e[37m" + $_.name) # 其他文件默认白色
}
$itemList += $item
}
echo $itemList | Format-Wide -AutoSize # 格式化输出
}
function Get-List {
Color-List "-Exclude .*"
}
function Get-All-List {
Color-List "$args"
}
# >>> 重新定义别名 >>>
Set-Alias ls Get-List
Set-Alias la Get-All-List
复制代码
最终效果如下: