终端,shell,prompt美化

1,631 阅读6分钟

前言

工欲善其事必先利其器,终端算是编程中经常接触的“器”,下面记录个人针对terminal,shell和prompt的一些个性化设置,仅供参考

作者沉迷折腾,永远在利器,从来不做事;带伙引以为戒😵‍💫

不过折腾的过程雀食有意思(也可能是我太闲了)

原文发布于vluv.space

📚相关术语

MeaningExamples
TerminalA text input and output environment.Windows Terminal,Alacritty,Kitty,Wezterm...
ConsoleA physical terminal.
Shellcommand-line interpreternushell,bash,zsh,fish,powershell...
PromptThe text that appears at the beginning of a command line形如$,>>>

如果想更细致的了解这几个概念的区别,可参考What is the difference between Terminal, Console, Shell, and Command Line?


⌨️终端美化

个人体验的终端有 Windows Terminal,Wezterm;

Wezterm 可自定义的程度比较高,可以自定义 tab 的位置&样式,但体验过程中,Wezterm 的启动速度相对较慢,目前主要使用 Windows Terminal

我的一些个性化设置

  • 字体: Maple Mono NF CN,对Ligatures,中文支持比较好的Nerd Font;
  • toggle focus mode: 选择开启 Focus Mode,可以隐藏上方 tab 栏,让界面更简洁
  • Color Schemes:Tokyo Night 或 Catppuccin Mocha;比较美观的两款夜间主题
  • Appearance: 在 Transparency 中选择 Enable acrylic material,启用亚克力效果;透明度 80%

效果图

wt.webp


🐚Shell

个人觉得比较好用的 shell 有 Nushell,fish; Powershell偶尔会用,但pwsh在个人机器上加载速度略慢,对使用体验有些影响。

Windows 环境上,fish 安装略麻烦,Nushell 可以通过winget,scoop或者cargo等进行安装;对于 linux,wsl 环境,两者安装都是比较容易的。

# windows
winget install nushell
# macos
brew install nushell
# arch linux
sudo pacman -S nushell

Nushell 社区比较活跃,插件市场&配置分享在 github 可以找到很多,感觉是比 powershell 活跃的。

nu_scripts仓库中维护了社区用户分享的 nushell 配置,喜欢折腾的可以参考本仓库。

下面是个人的 Nushell config,配置文件比较长,考虑篇幅,这里只附上关键内容。有需要完整配置的可以联系作者

Keybindings

我下载了 fuzzy finder 以及 bat 这两个命令行工具,配合以下配置可以方便的检索历史命令以及文件;此外还有一些比较实用的命令行工具,放在文末

# keybindings.nu
$env.config.keybindings = (
    $env.config.keybindings
    | append {  # history_menu using fzf
        name: fzf_history_menu_fzf_ui
        modifier: control
        keycode: char_r
        mode: [emacs, vi_normal, vi_insert]
        event: {
            send: executehostcommand
            cmd: "commandline edit --insert (cat $nu.history-path | fzf --height 70% --layout reverse --border +s --tac | str trim)"
        }
    }
    | append {
        name: fuzzy_file
        modifier: control
        keycode: char_t
        mode: emacs
        event: {
        send: executehostcommand
        cmd: "commandline edit --insert (fzf --layout=reverse --preview 'bat --color=always --style=numbers --line-range=:500 {}')"
        }
    }
)
# 在你的config.nu里
source <path_to_keybind.nu>

效果

2024-10-19_15-35-59.gif2024-10-19_15-43-39.gif
fuzzy_filehistory

Completions

nu_scripts仓库中提供了部分命令的补全脚本,一定程度上可以节省搜命令的时间,比如下面这些

 ls ./custom-completions/
╭────┬───────────────────────────┬──────┬──────┬─────────────╮
│  # │           name            │ type │ size │  modified   │
├────┼───────────────────────────┼──────┼──────┼─────────────┤
│  0 │ custom-completions\adb    │ dir  │  0 B │ 2 weeks ago │
│  1 │ custom-completions\bat    │ dir  │  0 B │ 3 weeks ago │
│  2 │ custom-completions\btm    │ dir  │  0 B │ 3 weeks ago │
│  3 │ custom-completions\cargo  │ dir  │  0 B │ 3 weeks ago │
│  4 │ custom-completions\curl   │ dir  │  0 B │ 3 weeks ago │
│  5 │ custom-completions\docker │ dir  │  0 B │ 3 weeks ago │
│  6 │ custom-completions\eza    │ dir  │  0 B │ 2 weeks ago │
│  7 │ custom-completions\gh     │ dir  │  0 B │ 2 weeks ago │
│  8 │ custom-completions\git    │ dir  │  0 B │ 3 weeks ago │
│  9 │ custom-completions\mvn    │ dir  │  0 B │ 3 weeks ago │
│ 10 │ custom-completions\npm    │ dir  │  0 B │ 2 weeks ago │
│ 11 │ custom-completions\pytest │ dir  │  0 B │ 2 weeks ago │
│ 12 │ custom-completions\scoop  │ dir  │  0 B │ 3 weeks ago │
│ 13 │ custom-completions\ssh    │ dir  │  0 B │ 2 weeks ago │
│ 14 │ custom-completions\tar    │ dir  │  0 B │ 3 weeks ago │
│ 15 │ custom-completions\vscode │ dir  │  0 B │ 2 weeks ago │
│ 16 │ custom-completions\winget │ dir  │  0 B │ 3 weeks ago │
╰────┴───────────────────────────┴──────┴──────┴─────────────╯

效果

terminal-5.webp


💲Prompt

Prompt 的美化方案有很多,比较知名的有 starship,ohmyzsh,ohmyposh;这里采用 ohmyposh

此前 omp 采用 Powershell 编写,后来为了兼容性用 go 重写,现在适用于 powershell,nushell,fish,zsh,bash 等等,甚至在安卓上也可以食用;

oh my posh 对自定义的支持程度非常高,支持的Prompt内容也很广泛,包括但不限于

  • OS
  • docker
  • git
  • java、python、golang、rust...
  • path
  • Execution Time

添加一些prompt对开发体验有一定提升。我在官方提供的主题上进行了自定义,配置文件放在后面仅供参考

显示效果如下图所示

nushell.webp

Theme

Oh My Posh 提供了非常丰富的主题,通过Get-PoshThemes命令可以查看浏览效果

terminal.webp

找 icon 可以去nerd-font cheat-sheet

掘金中部分icon显示不出来,原文发布于个人博客中,可去原文查看,

// File: themes\omp.json
  {
    "$schema": "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json",
    "blocks": [
      {
        "alignment": "left",
        "segments": [
          {
            "type": "text",
            "style": "powerline",
            "template": "<#92b0ed>╭─</>"
          },
          {
            "background": "#29315a",
            "foreground": "#92b0ed",
            "style": "diamond",
            "leading_diamond": "\ue0b6",
            "template": "<b>{{ .Icon }} </b>",
            "type": "os",
            "properties": {
              "windows": " Windows",
              "arch": " Arch",
              "ubuntu": " Ubuntu"
            }
          },
          {
            "background": "#8891e0",
            "foreground": "#090909",
            "powerline_symbol": "\ue0b0",
            "properties": {
              "folder_icon": "󱧬 ",
              "folder_separator_icon": "/",
              "home_icon": "",
              "style": "letter",
              "mixed_threshold": 4,
              "mapped_locations": {
                "E:/OneDrive - 商业版/Archives/markdown_notes/vluv": "Vluv's Space ",
                "E:/OneDrive - 商业版/Archives/markdown_notes/Markdown": "My Notes 󰍔",
                "C:/Users/24138/AppData/Local": "LOCAL APPDATA "
              }
            },
            "style": "powerline",
            "template": " <#000>  </><b>{{ .Path }}</b> ",
            "type": "path"
          },
          {
            "background": "#29315A",
            "foreground": "#43CCEA",
            "foreground_templates": [
              "{{ if or (.Working.Changed) (.Staging.Changed) }}#e0af68{{ end }}",
              "{{ if and (gt .Ahead 0) (gt .Behind 0) }}#ff4500{{ end }}",
              "{{ if gt .Ahead 0 }}#bb9af7{{ end }}",
              "{{ if gt .Behind 0 }}#bb9af7{{ end }}"
            ],
            "powerline_symbol": "\ue0b0",
            "properties": {
              "branch_max_length": 25,
              "fetch_stash_count": true,
              "fetch_status": true,
              "fetch_upstream_icon": true
            },
            "style": "powerline",
            "template": " {{ .UpstreamIcon }}{{ .HEAD }}{{if .BranchStatus }} {{ .BranchStatus }}{{ end }}{{ if .Working
  .Changed }} \uf044 {{ .Working.String }}{{ end }}{{ if and (.Working.Changed) (.Staging.Changed) }} |{{ end }}{{ if .S
  taging.Changed }} \uf046 {{ .Staging.String }}{{ end }}{{ if gt .StashCount 0 }} \ueb4b {{ .StashCount }}{{ end }} ",
            "trailing_diamond": "\ue0b4",
            "type": "git"
          },
          {
            "background": "#9ece6a",
            "foreground": "#ffffff",
            "powerline_symbol": "\ue0b0",
            "style": "powerline",
            "template": " \ue718 {{ if .PackageManagerIcon }}{{ .PackageManagerIcon }} {{ end }}{{ .Full }} ",
            "type": "node"
          },
          {
            "type": "rust",
            "style": "powerline",
            "powerline_symbol": "",
            "background": "#f7768e",
            "foreground": "#c31414",
            "template": " <b> Rust </b>{{ if .Error }}{{ .Error }}{{ else }}{{ .Full }}{{ end }} "
          },
          {
            "type": "java",
            "style": "powerline",
            "powerline_symbol": "\ue0b0",
            "background": "#f7768e",
            "foreground": "#c31414",
            "template": " <b> JDK</b>{{ if .Error }}{{ .Error }}{{ else }}{{ .Full }}{{ end }} "
          },
          {
            "type": "python",
            "style": "powerline",
            "powerline_symbol": "\ue0b0",
            "background": "#bb9af7",
            "foreground": "#100e23",
            "template": " \ue235 {{ if .Error }}{{ .Error }}{{ else }}{{ if .Venv }}{{ .Venv }} {{ end }}{{ .Full }}{{ e
  nd }} "
          },
          {
            "type": "go",
            "style": "powerline",
            "powerline_symbol": "\ue0b0",
            "background": "#90d8f7",
            "foreground": "#100e23",
            "template": "<b> 󰟓 Go{{ .Full }} </b>"
          },
          {
            "background": "#bb9af7",
            "foreground": "#100e23",
            "style": "powerline",
            "powerline_symbol": "\ue0b0",
            "template": " \ue620 {{ if .Error }}{{ .Error }}{{ else }}{{ .Full }}{{ end }} ",
            "type": "lua"
          }
        ],
        "type": "prompt"
      },
      {
        "alignment": "right",
        "segments": [
          {
            "foreground": "#8aadf4",
            "properties": {
              "style": "dallas",
              "threshold": 0
            },
            "style": "diamond",
            "template": " {{ .FormattedMs }}s in ",
            "type": "executiontime"
          },
          // {
          //   "foreground": "#e0af68",
          //   "style": "diamond",
          //   "template": "  RAM {{ (div ((sub .PhysicalTotalMemory .PhysicalFreeMemory)|float64) 1073741824.0) }}/{{
  (div .PhysicalTotalMemory 1073741824.0) }}GB ",
          //   "type": "sysinfo"
          // },
          {
            "foreground": "#bb9fee",
            "style": "diamond",
            "template": "\uf489  {{ .Name }} ",
            "type": "shell"
          },
          {
            "foreground": "#ddcca4",
            "properties": {
              "time_format": "3:04 PM"
            },
            "style": "diamond",
            "template": "󰅐 {{ .CurrentDate | date .Format }}",
            "type": "time"
          }
          // {
          //   "type": "owm",
          //   "style": "diamond",
          //   "foreground": "#7dcfff",
          //   "template": "{{.Weather}} {{.Temperature}}{{.UnitIcon}}",
          //   "properties": {
          //     "api_key": "🤖",
          //     "location": "Chengdu,CN",
          //     "units": "metric",
          //     "enable_hyperlink": true,
          //     "http_timeout": 400,
          //     "cache_timeout": 15
          //   }
          // }
        ],
        "type": "prompt"
      },
      {
        "alignment": "left",
        "newline": true,
        "segments": [
          {
            "type": "text",
            "style": "powerline",
            "template": "<#92b0ed>\u2514 </>"
          },
          {
            "foreground": "#86e1fc",
            "foreground_templates": [
              "{{ if gt .Code 0 }}#ef5350{{ end }}"
            ],
            "properties": {
              "always_enabled": true
            },
            "style": "plain",
            "template": " </>",
            "type": "status"
          }
        ],
        "type": "prompt"
      }
    ],
    "final_space": true,
    "version": 2
  }

🛠️CLI & TUI

下面是一些比较实用/有意思的命令行工具

TUI

  • gitui Blazing 💥 fast terminal-ui for git written in rust 🦀 类似于 lazygit,在终端中管理 git repo,适合不想动鼠标的人 terminal-3.webp
  • btop A monitor of resources 任务管理器 TUI 版,同样适合纯键盘操作 terminal-2.webp
  • yazi 💥 Blazing fast terminal file manager written in Rust, based on async I/O. 支持 windows 平台的 terminal file manager,除此之外 midnight commander 也支持 windows;适合纯键盘操作 terminal-4.webp

CLI

  • bat A cat clone with syntax highlighting and Git integration. 相比 cat 多了语法高亮 terminal-1.webp

  • zoxide A smarter cd command. Supports all major shells. 快速切换目录

      z foo              # cd into highest ranked directory matching foo
      z foo bar          # cd into highest ranked directory matching foo and bar
      z foo /            # cd into a subdirectory starting with foo
    
      z ~/foo            # z also works like a regular cd command
      z foo/             # cd into relative path
      z ..               # cd one level up
      z -                # cd into previous directory
    
      zi foo             # cd with interactive selection (using fzf)
    
      z foo<SPACE><TAB>  # show interactive completions (zoxide v0.8.0+, bash 4.4+/fish/zsh only)
    

下面三个都是搜索类的工具,ripgrep 是 grep 的替代品(项目名意为 R.I.P grep),VSCode 的快速搜索便是用的 ripgrep,fzf 可以与其它的工具相结合,用于模糊搜找文件,历史记录等等..

  • ripgrep ripgrep recursively searches directories for a regex pattern while respecting your gitignore
  • fd A simple, fast and user-friendly alternative to find.
  • fzf 🌸 A command-line fuzzy finder;

MISC