点文件 -- 开发第一课

01 Sep 2023 6372 words 22 minutes BY-SA 4.0
develop

在 github 上搜索 dotfiles 可以找到至少二十万的代码仓库。 甚至有人“暴论”点文件是学校没教的重要一课。 那么,什么是点文件呢?

注册表 v.s. 纯文本格式配置文件

在 Unix 刚刚问世的时候,利用利用纯文本作为软件配置方式的思路就被定下来了。例如许多 POSIX 兼容的系统中会有一个目录 /etc (甚至 Windows 也有 C:\Windows\System32\Drivers\etc)用来存储纯文本格式配置文件 ( editable text configuration )。在这之后 Windows 3.0 才引入了注册表,通过二进制文件的数据库来存储软件的配置,同时提供一个图形化用户界面的软件(注册表编辑器)来修改软件的配置。

早期 Windows 引入注册表是有进步意义的:那时 Unix 运行在性能更好的大型机上,而 Windows 运行的性能较弱的微机。然而随着技术的进步,注册表的优势被削弱,而劣势则暴露无疑。目前, GNU/Linux 除了 gtk 系的一些桌面在用数据库外,几乎所有软件都采用纯文本格式的配置文件。即便是微软开发的 powershell 和 VS Code 也使用纯文本格式的配置文件。毕竟,比起下图中的代码补全,又有谁愿意去打开根本记不住的 HKEY 开头的注册表路径去配置软件呢?

json schema

从点文件到标准化

作为一名开发人员,你很可能在你的整个职业生涯都要使用并改进你的点文件,点文件很可能是你从事过最长的项目。

– Anish Athalye Managing Your Dotfiles

Unix 将配置文件分为 2 类,一类是系统管理员 ( root 用户)编辑的 /etc ,是所有用户共用的。另一类是每个用户专属的配置文件。用户的配置文件比所有用户共用的配置文件拥有更高的优先级。早期这些文件被放在家目录下,以点开头,故称点文件。 Unix 会隐藏点开头的文件所以平时这些文件不会被看到。

随着时间的推移,各个平台都开始通过标准来确定配置文件的存储路径。

例如 GNU/Linux 采用 Freedesktop 的 XDG 标准,将原来的 ~/.my_app 分成多个不同的目录分别存储共享资源、缓存、配置。这样的好处是:

但并不是所以平台都分得这么细,例如在 Windows 上软件就不得不从 C:\Users\%USERNAME%\AppData\Local\my_app 自行分出几个子目录用来分别存储共享资源、缓存、配置,或者另创建 C:\Users\%USERNAME%\AppData\Local\my_app-data 来存储共享资源等。

所以从引入 XDG 标准后,原先的备份 ~/.my_app 就变成了备份 ~/.config/my_app 了。因为 .config 仍是以点开头,所以通常不加区分地统称点文件。

值得注意的是 XDG 标准定义了一些路径用来存储特定文件:

这意味着软件不能把名字命名为 fonts, backgrounds 等等。

开发者开发软件时要遵守每一个平台的标准,但记住每个平台下的标准很麻烦。所以许多语言都能找到支持这些标准的库。

被点文件配置的常见软件类别

使用不同语言、不同软件的开发者点文件往往差异很大。按照 https://wiki.archlinux.org/title/Dotfiles#User_repositories , 包括以下类别:

每类软件单独拿出来介绍都足以构成一篇长篇大论。例如:

不再赘述。如有需要请自行搜索

常见的需要配置的部分

REPL 主题

许多语言的 REPL 默认的提示符都非常丑陋。 用户通常希望自定义提示符来显示当前平台的种类、当前所在的路径、时间、 git 信息等。 在这些语言中, shell 是 REPL 使用最频繁的语言。有很多用户喜爱自定义他们的 shell 。 一些主题封装了自定义的代码并允许用户进一步配置某些细节。笔者个人非常看重可配置性。

笔者一开始在点文件中写了一些功能,后来发觉代码量开始变多,而且可能对其他人有用就单独提出来封装成一个个 zsh/tmux/vim 插件了。

zsh

笔者默认的 shell 是 zsh。 powerlevel10k 是目前性能最好的 zsh 主题,其获取 git 信息的部分用 C++ 实现从而在性能上成功超越了之前的 powerlevel9k 。

zsh

还有很多 REPL 笔者并没有找到很好的主题,甚至只好自己动手实现了一些轮子。

bash

笔者一般交互用 zsh ,但日常写 shell 脚本还是用 bash 。

bash

tcl

也是一种 shell 。几乎是 EDA 行业的标准配置语言。

tclsh

wish

expectp

vivadop

xsctp

python

配置方法

python

其实笔者一般用 ptpython 或者与 ipython 兼容但性能更快的 ptipython 。

关于 ipython 性能问题的报告

octave

matlab 的开源解释器。

octave

perl

有一说一, perl 做数据驱动编程真不错。

reply

lua

luap

neovimp

texluap

pandocp

translate-shell

translate-shell: 笔者嫌弃现在能找到的命令行翻译软件颜值太低时随手写的软件。

translate-shell

trans

高能预警。

gdb

嗯, gdb 也是一个 REPL !

gdb-prompt: 一个 gdb 主题

gdb-prompt

lftp

配置方法

lftp

还有一些 REPL 目前没有提供自定义提示符的功能:

状态栏

一些软件的状态栏也是可以自定义的:

(neo)vim

vim

tmux

tmux

色彩高亮

高亮代码

man

help

declare

高亮命令

grc

eza

高亮命令行输入

wrong perl

correct perl

高亮补全

fzf-tab

补全

每种 shell 的补全语法各不相同。一般是软件开发者都是用一些库来自动生成补全的脚本:

有些语言没找到类似的库就直接自己造轮子吧……

杂项

点文件管理

为什么我希望将我的点文件放在 GitHub 上?

– Github does dotfiles

最常见的管理方式就是 git 。例如笔者平时把点文件托管在 github 上的一个仓库里,每当有换新电脑时就会执行如下操作:

cd
git clone --depth=1 --bare https://github.com/Freed-Wu/Freed-Wu
git config core.bare false
git reset --hard

一个窍门是 github 允许用与自己用户名相同的仓库作为 github 用户主页的 profile 。所以我们可以利用这一特性将点文件的仓库名设置为用户名,从而让点文件的 README 在 github 用户主页被展示。

一些其他的管理方法见 https://wiki.archlinux.org/title/Dotfiles#Tools 。对 Nix 用户,home manager 也是个不错的方法。

笔者倾向于把所有平台的点文件放在一起。例如笔者的点文件里其实包含几个平台家目录下的点文件:

对于不同发行版的 /etc 下的不同配置,笔者倾向于在不同的仓库分别管理,因为不同发行版可能会使用不同的镜像,配置等。

联动

Github codespace

Github 支持用点文件自定义代码空间。例如笔者自己用点文件定义的代码空间:

gh cs create -RFreed-Wu/Freed-Wu -mbasicLinux32gb -dwzy
# wait about 3 minutes to install needed programs and zsh/vim/tmux plugins
gh cs ssh

github codespace

Docker

docker 镜像

docker pull freedwu/Freed-Wu:main
docker run --rm -it --name=test --gpus=all -p 8022:22 freedwu/Freed-Wu:main

结果类似 Github 代码空间。

https://user-images.githubusercontent.com/32936898/199681341-1c5cfa61-4411-4b67-b268-7cd87c5867bb.png https://user-images.githubusercontent.com/32936898/199681363-1094a0be-85ca-49cf-a410-19b3d7965120.png https://user-images.githubusercontent.com/32936898/199681368-c34c2be7-e0d8-43ea-8c2c-d3e865da6aeb.png