点文件 -- 开发第一课

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