真 ● 禁秘技 ● 奥义 ● 终端美化

1 概述

作为一个程序员,可以没钱,没车,没房,没老婆,没女朋友。

但是,一定要有一个漂亮骚气的终端。

没错,大骚特骚。

说什么大实话。

先来看看原生的终端:

真漂亮啊。

再看看美化过的:

这才叫终端嘛。

美化过的就是不一样。

如果您也想要这样的终端,那这篇文章要仔细看,同时顺手点个赞。

文章讲述了如何使用zsh,配合主题Powerlevel10k(以下简称p10k)进行终端美化的过程,不废话了,进入正题。

2 环境

笔者环境:

  • Manjaro
  • Xfce
  • 自带的Xfce terminal

其他Linux基本适用,安装zsh+zinit/oh-my-zsh即可,Mac用户可以通过homebrew安装zsh+p10k,至于Win用户,可以尝试WSL+图形界面。

3 准备工作

安装zsh+zinit/oh-my-zsh

3.1 zsh

Manjaro/Arch

yay -S zsh

Debian系:

sudo apt install zsh

RedHat系:

sudo yum install -y zsh

其他可以来到官方Github安装,戳这里

设为默认shell:

chsh -s $(which zsh)

再把原来的别名复制到

~/.zshrc

3.2 zinit/oh-my-zsh

其实p10k安装有很多种方式,如图:

这里演示的是通过zinitoh-my-zsh(以下简称OMZ安装)。

3.2.1 zinit

zinit是一个强大的zsh插件管理器,安装:

sh -c "$(curl -fsSL https://raw.githubusercontent.com/zdharma/zinit/master/doc/install.sh)"

接着在~/.zshrc加上:

zinit ice depth=1; 
zinit light romkatv/powerlevel10k

即可完成p10k的安装。

3.2.2 OMZ

首先安装OMZ

sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
#或
sh -c "$(wget -O- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

失败的话可以clone仓库安装,戳这里

接着安装p10k

git clone --depth=1 https://gitee.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k

最后在~/.zshrc中定义加上主题:

ZSH_THEME="powerlevel10k/powerlevel10k"

3.3 字体

Manjaro/Arch用户:

yay -S nerd-fonts-meslo

或手动安装:

其他系统的字体安装请参考其他博客,比如:

4 p10k基本配置

如果是使用zinit安装的p10k,重新启动zsh即可,如果是OMZ安装的p10k,请手动输入:

p10k configure

就会出现图形化配置向导。首先会问几个问题:

会问三个图标:钻石,锁与Debian,这个是测试有没有安装对应的字体,如果没有安装的话应该是不能正常显示图标的,然后会问图标是否会重叠,接着有四种风格可以选择:

从这里开始就是自定义配置了,笔者选的3 ,接着可以选择:

  • 编码(Unicode/ASCII
  • 时间(不显示/12小时制/24小时制)
  • 提示段分隔符(三角/垂直/斜线/圆角)
  • 提示段头部(三角/渐隐/斜线/垂直)
  • 提示段尾部(垂直/渐隐/三角/倾斜/圆角)
  • 高度(一行/两行)
  • 左右提示段连接方式(无/点状连接/实线连接)
  • 提示段旁的命令提示符(无/左/右/左+右)
  • 颜色(最亮/亮/暗/最暗)
  • 空格(稀疏/紧密)
  • 图标(少/多)
  • 提示段流(Prompt Flow)(简洁/流畅,相比起简洁模式,对于时间、Git分支等流畅模式会显示更多文字或图标)
  • 临时提示(开启/关闭)
  • 即时提示模式(关闭/安静模式/啰嗦模式,官方是推荐啰嗦模式的,关闭是已经尝试过即时提示模式,但是不兼容zsh配置,需要关闭,安静模式建议已经阅读了即时提示模式文档后使用)
  • 覆盖p10k配置文件(如果p10k配置文件已存在,会提示是否覆盖,不覆盖的话也就是相当于此次配置无效,需要覆盖才能生效),覆盖之前原文件会备份

简单配置的效果:

5 p10k自定义配置

由于p10kp9k的一个分支(关于p9k的相关描述请看文末),对于p9k的配置大部分都是兼容的,因此这里以p9k的配置为例进行说明。

5.1 如何修改配置文件?

首先要知道配置文件的默认位置为:

~/.p10k.zsh

这是默认的配置,在vcs下面添加一个time

就会看到左边也多了一个时间:

这样提示段就可以很轻松地进行自定义了。

5.2 提示段

5.2.1 开启/关闭整个提示段

关闭左边/右边整个提示段:

# 左
# 注左边的提示段测试关闭失败,可能是p10k强制不允许关闭左边提示段的原因
typeset -g POWERLEVEL9K_DISABLE_PROMPT=true
#右
typeset -g POWERLEVEL9K_DISABLE_RPROMPT=true

5.2.2 系统相关

  • background_jobs:后台任务
  • battery:电池状态
  • context:用户名+主机名,基于USER环境变量以及SSH状态
  • date:日期
  • dir:当前工作目录
  • dir_writable:当前目录可写状态,可写时为空,不可写时有一个锁
  • disk_usage:当前分区的磁盘使用百分比
  • history:历史命令记录数量
  • host:主机名
  • ip:内网ip
  • _ip_ip
  • public_ip:公网ip
  • load:机器的平均负载
  • os_icon:操作系统图标,支持的系统有AplineAOSCArchCentOSCoreOSDebianDevuanElementaryFedoraGentooMageiaManjaroMintNixOSOpenSUSESabayonSlackwareUbuntu
  • ram:可用内存大小
  • root_indicator:拥有root权限的提示符
  • status:前一条命令的结果状态码
  • swap:交换分区使用情况
  • time:时间
  • user:当前用户
  • vi_modevi模式
  • sshssh状态

5.2.3 语言相关

  • go_versionGo版本
  • node_versionNode.js版本
  • nodeenvnodeenv显示的Node版本
  • nvmNVM显示的Node版本
  • php_versionphp版本
  • laravel_versionLaravel版本
  • symfony2_test2Symfony2测试类与代码类的比率
  • symfony2_versionSymfony2版本
  • virtualenvPythonVirtualEnv环境
  • anacondaAnaconda环境
  • pyenvpyenv version命令显示的第一个单词,但是如果是system将不会显示
  • chruby:使用chrubyRuby环境
  • rbenv:使用rbenvRuby环境
  • rspec_statusRSpec中测试类与代码类的比率
  • rvm:使用GEM_HOME环境变量或者MY_RUBY_HOME环境变量显示的Ruby信息
  • rust_versionRust版本
  • swift_versionSwift版本
  • java_versionJava版本
  • openfoamOpenFOAM库版本

笔者认为这类提示符的用处不是很大,因为具体环境的话自己应该是清楚的,因此笔者没有选择这类进行配置。

5.2.4 云相关

  • aws:当前的AWS配置
  • aws_eb_env:当前的Elastic Beanstalk环境
  • docker_machine:当前的Docker Machine
  • docker_machinekubectl配置
  • dropboxDropbox目录以及使用dropbox-cli的同步状态

5.2.5 其他

  • vcsgit/hg仓库的信息
  • command_execution_time:命令执行时间
  • todotodo.txt文件中任务数量
  • detect_virt:使用systemd进行虚拟化检测
  • newline:另起一行
  • custom_command:自定义命令,需要以custom_开头

比如,利用

nmcli device wifi

显示wifi速率,首先添加一个函数:

wifi_rate(){
    local rate=$(nmcli device wifi | grep -E "\*" | awk '{print $6}') #awk后面的数字可能每个人不同
    echo "\uf0e7 $rate Mbit/s"
}

其次添加自定义提示段(以custom开头):

typeset -g POWERLEVEL9K_CUSTOM_WIFI_RATE="wifi_rate"

最后在

typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS
#或
typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS

加上即可,演示效果:

需要的话,可以根据信号状态定义不同的颜色:

完整配置文件如下,加上了wifi名字:

set_wifi()
{
  wifi_signal=$(nmcli device wifi | grep -E "\*" | awk '{print $8}')
  typeset -g POWERLEVEL9K_CUSTOM_WIFI_NAME_FOREGROUND="black"
  typeset -g POWERLEVEL9K_CUSTOM_WIFI_RATE_FOREGROUND="black"
  typeset -g POWERLEVEL9K_CUSTOM_WIFI_BARS_AND_SIGNAL_FOREGROUND="black"

  typeset -g POWERLEVEL9K_CUSTOM_WIFI_NAME_BACKGROUND="green" 
  typeset -g POWERLEVEL9K_CUSTOM_WIFI_RATE_BACKGROUND="green"
  typeset -g POWERLEVEL9K_CUSTOM_WIFI_BARS_AND_SIGNAL_BACKGROUND="green"

  if [[ $wifi_signal -lt 50 ]] ; then 
    typeset -g POWERLEVEL9K_CUSTOM_WIFI_NAME_BACKGROUND="red"
    typeset -g POWERLEVEL9K_CUSTOM_WIFI_RATE_BACKGROUND="red"
    typeset -g POWERLEVEL9K_CUSTOM_WIFI_BARS_AND_SIGNAL_BACKGROUND="red"
  elif [[ $wifi_signal -lt 75 ]] ; then 
    typeset -g POWERLEVEL9K_CUSTOM_WIFI_NAME_BACKGROUND="yellow"
    typeset -g POWERLEVEL9K_CUSTOM_WIFI_RATE_BACKGROUND="yellow"
    typeset -g POWERLEVEL9K_CUSTOM_WIFI_BARS_AND_SIGNAL_BACKGROUND="yellow"
  fi
}
set_wifi

wifi_name(){
  local name=$(nmcli device wifi | grep -E "\*" | awk '{print $3}')
  echo "\uf502 $name"
}
wifi_rate(){
  local rate=$(nmcli device wifi | grep -E "\*" | awk '{print $6}')
  echo "\uf0e7 $rate Mbit/s"
}
wifi_bars_and_signal(){
  local bars=$(nmcli device wifi | grep -E "\*" | awk '{print $9}')
  echo "$bars $wifi_signal %%"
}

typeset -g POWERLEVEL9K_CUSTOM_WIFI_NAME="wifi_name"
typeset -g POWERLEVEL9K_CUSTOM_WIFI_RATE="wifi_rate"
typeset -g POWERLEVEL9K_CUSTOM_WIFI_BARS_AND_SIGNAL="wifi_bars_and_signal"

typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(
  # =========================[ Line #1 ]=========================
  date
  dir                     # current directory
  dir_writable
  vcs                     # git status
  newline
  # =========================[ Line #2 ]=========================
  ram
  # prompt_char           # prompt symbol
  custom_wifi_name 
  custom_wifi_rate 
  custom_wifi_bars_and_signal 
)

注意提示段并不是越多越好,太多的话会有点显得过于花里胡哨,而且会影响速度。

5.3 颜色

修改提示段的前景/背景,直接修改即可,一般的格式为:

typeset -g POWERLEVEL9K_NAME_STATUS_BACKGROUND=
typeset -g POWERLEVEL9K_NAME_STATUS_FOREGROUND=

其中NAME为5.1小节中对应的提示段,比如可以修改:

typeset -g POWERLEVEL9K_OS_ICON_FOREGROUND="green"
typeset -g POWERLEVEL9K_PHP_VERSION_BACKGROUND="010"

颜色可以使用一些常见的red/green等等,也可以使用序号,可以查看这张图:

也可以使用如下命令显示颜色:

for i in {0..255}; do print -Pn "%K{$i}  %k%F{$i}${(l:3::0:)i}%f " ${${(M)$((i%6)):#3}:+$'\n'}; done

STATUS不是每个提示段都有的,拥有STATUS的提示段如下:

  • batteryLOWCHARGINGCHAGEDDISCONNECTED
  • contextDEFAULTROOTSUDOREMOTEREMOTE_SUDO
  • dirHOMEHOME_SUBFOLDERDEFAULTETCNOT_WRITABLE
  • dir_writableFORBIDDEN
  • disk_usageNORMALWARNINGCRITICAL
  • hostLOCALREMOTE
  • loadCRITICALWARNINGNORMAL
  • rspec_statsSTATS_GOODSTATS_AVGSTATS_BAD
  • symfony2_testTESTS_GOODTESTS_AVGTESTS_BAD
  • userDEFAULTSUDOROOT
  • vcsCLEANUNTRACKEDMODIFIED
  • vi_modeNORMALINSERTVISUAL

大部分都可以很容易理解,这里以最简单的为例:

typeset -g POWERLEVEL9K_DIR_DEFAULT_BACKGROUND='166'
typeset -g POWERLEVEL9K_DIR_DEFAULT_FOREGROUND='000'
typeset -g POWERLEVEL9K_DIR_ETC_BACKGROUND='226'
typeset -g POWERLEVEL9K_DIR_ETC_FOREGROUND='000'
typeset -g POWERLEVEL9K_DIR_HOME_BACKGROUND='044'
typeset -g POWERLEVEL9K_DIR_HOME_FOREGROUND='000'

设置home目录,etc目录以及默认目录的前景与背景。

另外需要注意的是显示的颜色还与终端本身的设置颜色有关,请到具体的终端配置去修改:

5.4 位置

可以加上

typeset -g POWERLEVEL9K_PROMPT_ON_NEWLINE=true

使输入的命令显示在新的一行。

typeset -g POWERLEVEL9K_RPROMPT_ON_NEWLINE=true

让右边的提示段在新的一行。

typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMETS
#或
typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMETS

中,可以配合newline以及5.1中的提示段自定义位置,示例如下:

POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(
    os_icon date time newline 
    custom_wifi_rate custom_wifi_bars_and_signal newline
    background_jobs ram load swap disk_usage newline 
    php_version java_version node_version newline 
    dir dir_writable vcs 
)

5.5 图标

使用

get_icon_names

可以查看内置的图标。

注意这个和字体有关,如果使用默认的PowerlineFonts或者使用AwesomeFonts可能不会完整显示所有图标,请使用Nerd-Fonts。

戳这里查看Nerd-fonts的部分图标,戳这里(国外网站)搜索所有的图标。

官方的例子是自定义vcs的图标:

typeset -g POWERLEVEL9K_VCS_BRANCH_ICON=$'\uF126'

F126可以通过上面的网站搜索得到,是一个分支的图标:

其他git相关图标:

  • GithubVCS_GIT_GITHUB_ICON
  • BitBucketVCS_GIT_BITBUCKET_ICON
  • GitLabVCS_GIT_GITLAB_ICON
  • 其他:VCS_GIT_ICON

另外还可以修改提示段前的图标:

typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX="↱"
typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX="↳ "
typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_PREFIX="xxx"

还可以根据get_icon_names修改默认图标,比如,修改

typeset -g POWERLEVEL9K_HOME_SUB_ICON=$'\uf74b'

但是直接改icon的话图标会显示得很小,可以在函数中像上面的wifi一样使用echo自定义。

6 配置文件

笔者的配置文件,仅供参考:

7 杂项

7.1 文章更新

这篇文章其实是从笔者之前的文章修改更新过来的,由于之前的那一篇写得有点混乱,这里重新排版并修正了一些错误。

7.2 关于p9k

(以下部分针对p9k的老用户,刚接触p10k的可以略过)

前面提到p10kp9k的一个分支,p10k是2019年3月从p9k的仓库fork而来的。p9k已经是一个拥有大量用户的成熟的工程。p10k被分离出来,以更快的速度迭代更新,添加新特性以及改进性能。

p9kp10k是独立的项目,只能安装其中一个,但是p10k会识别p9k的所有参数。

目前p9k已经不再维护更新,推荐使用p10k

7.3 提示延迟

笔者认为出现p10k的主要原因就是p9k很慢,比如这是p9kissue

具体内容请查看p9k官方issuep10k改进了性能,p10k Github有一个演示视频,展示了p10k的速度,在Intel i9-7900X+Ubuntu 18.04上,测试提示延迟如下:

(来源官方测试)

相对来说,p9k具有可接受的延迟,如果只是需要当前目录而不需要截断或缩短,p9k可以17ms内渲染完成,p10k可以将其提高30倍的渲染速度,但实际上并不需要,因为延迟变得明显的阀值为50ms。官方建议必须小心使用p9k的配置,因为很容易使得提示变慢,但是p10k在任何配置中几乎都是即时的,可以保持远低于50ms。

另外笔者的系统上也测试过,p9k确实要比p10k慢,添加了很多设置后,p9k在终端中连续按Enter,松手之后还在提示,甚至一个普通的ls也有明显的延迟,但是p10k没有这样的问题,很流畅。

7.4 加载速度

p10kp9k能更快加载,前提是,zsh版本5.4+。

官方建议使用下面的命令测试:

time (repeat 1000 zsh -dfis <<< 'source ~/powerlevel10k/powerlevel10k.zsh-theme')

但是笔者没有这个文件,怀疑是位置给错了,修改如下:

time (repeat 1000 zsh -dfis <<< 'source /usr/share/zsh-theme-powerlevel10k/powerlevel10k/powerlevel10k.zsh-theme')

笔者的系统上耗时如下:

换了p9k后:

time (repeat 1000 zsh -dfis <<< 'source /usr/share/zsh-theme-powerlevel9k/powerlevel9k.zsh-theme')

耗时如下:

不过好像没快多少的样子,可能是zsh版本的问题,装的是目前最新的5.8,可能老一点的版本区别会明显一点。

官方的测试是p10k用了29s,比相同环境下的p9k master分支大约快6倍,比p9k next分支快17倍。笔者认为仅供参考吧,用p10k就对了,毕竟比p9k快。

7.5 其他

  • p10k默认只开启vcsgit后端的支持,如果需要svn/hg,需要添加到typeset -g POWERLEVEL9K_VCS_BACKENDS。但是p10k还没有针对svn/hg优化,所以添加的话会让提示变慢
  • p10k不支持typeset -g POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY=true
  • p10k会兼容p9k的所有选项,因此,相同配置下如果p9kp10k看到的图标不一样,可能是设置了typeset -g POWERLEVEL9K_MODE的原因,请去掉typeset -g POWERLEVEL9K_MODE
  • p9k不识别typeset -g ZLE_RPROMPT_INDENT,因此p10k相比起p9k会有额外的空格。如果不想要可以设置typeset -g ZLE_RPROMPT_INDENT=0

  • p9k在图标附近有不一致的空格,在p10k已经不存在了,不过可以设置typeset -g POWERLEVEL9K_LEGACY_ICON_SPACING=true显示与p9k中一样的空格

  • p10k修正了p9k的许多bugs,除了修复空格问题等,最主要是极大地提高了速度

8 关于tty

由于p10k可以配置得非常炫酷,因此想要在tty上显示是几乎不现实的,这里建议的做法是,准备两套主题,一套在GUI使用,一套在tty使用,建议的做法是先备份在GUI上的主题(~/.p10.zsh):

cp ~/.p10k.zsh ~/.p10k.zsh.gui

然后再运行一次p10k configure选择Lean

注意字符集需要选择ASCII

颜色不能选择256,否则显示不出来:

简单配置后的效果:

虽然确实是普通了一点,但胜在通用。

首先备份生成的主题:

cp ~/.p10k.zsh ~/.p10k.zsh.tty

这样需要的时候进行手动切换即可:

# GUI
cp ~/.p10k.zsh.gui ~/.p10k.zsh
# tty
cp ~/.p10k.zsh.tty ~/.p10k.zsh

9 最后

首先本文写作日期是10月24日,先祝所有的程序员节日快乐,写的代码永远没有bug。

说了这么多,如果是p9k的用户强烈建议迁移到p10k,官方有迁移指南,戳这里

另外如果想配置一个真正漂亮实用又快速高效的终端是真的需要一点动手能力的,希望看完这篇文章的读者能收到启发,去配置一个自己专属的终端。

你可能感兴趣的