wincent

wincent

强大灵活的开发环境配置系统

wincent是一个针对macOS和Linux平台的高度可定制系统配置框架。它使用自研的Fig配置工具,提供dotfiles管理、软件包安装、键盘定制、shell增强等功能。该项目为开发者提供了一个全面而灵活的开发环境配置方案,可满足个性化需求。

dotfiles系统配置VimZshGitGithub开源项目

"点文件"和系统配置

这些点文件亲切地献给最初由比尔·乔伊创造的vi编辑器,我与它度过了许多愉快的夜晚[^1]

— Greg Hurrell,改编自唐纳德·克努特的话

概述

特性

点文件

一套点文件,我从2000年代初期就开始调整和修改(自2009年起使用版本控制)。特点包括:

  • 通过括号粘贴模式实现Vim中的合理粘贴。
  • 在本地和远程主机上,无论是否在tmux内,都可以访问本地剪贴板(通过Clipper)。
  • Vim和tmux中的完整鼠标支持(窗格/分割调整大小、滚动、文本选择)。
  • tmux内Vim的焦点获得/失去事件。
  • 进入Vim时切换光标形状。
  • 终端中的斜体支持。
  • 捆绑了(不过多的)一些有用的Vim插件
  • 保守的Vim配置(很少覆盖核心功能;大多数更改是不引人注目的增强;一些额外功能通过<Leader><LocalLeader>映射暴露)。
  • 相对克制的Zsh配置,类似Bash但带有一些Zsh特性,如右侧提示符、自动cd钩子、命令执行时间显示等。
  • 通过Base16 Shell实现统一的颜色处理(跨Kitty和Vim)。
  • 加密版本控制敏感内容文件(通过git-cipher)。
  • 全面的Hammerspoon 配置

Homebrew

在macOS上,"homebrew"方面安装了一堆有用的软件

键盘自定义

在macOS上,我们使用Karabiner-Elements,在Linux上,我们使用Interception Tools和其他一些工具来进行以下更改:

  • 使Caps Lock键在单击时作为退格键,与其他键组合时作为左Control键。单独长按Caps Lock键会触发重复的退格事件。
  • 使回车键在单击时作为回车键,与其他键组合时作为右Control键。单独长按回车键会触发重复的回车事件。
  • 同时按下两个Shift键可切换Caps Lock开关。
  • 使我的外接Realforce键盘上的功能键表现得像苹果键盘上的"媒体"键。

以下仅在macOS上:

  • 在我的外接Realforce键盘上交换Option和Command键。
  • 使Realforce键盘上的"应用程序"键(右侧额外的修饰键)表现为"fn"键。
  • 将Control-I映射到F6(仅在终端中),以便在Vim中可以独立于Tab键进行映射1
  • 使Realforce键盘上的"暂停"键(功能键行最右侧)表现为"电源"键(实际上是睡眠)。
  • 添加一个"SpaceFN"层,可以通过按住空格键同时按其他键来激活;我用这个在任何应用程序中使光标键在或接近主行可用。

Zsh

函数

  • ag:透明地包装ag可执行文件,为该命令提供一个集中设置默认值的地方(因为它没有"rc"文件)。
  • bounce:如果终端不在前台,则弹跳macOS Dock图标。
  • color:更改终端和Vim配色方案。
  • fd:使用快速的bfssk"查找目录";自动cd到选定的目录。
  • fh:"在历史中查找";选择历史项将其插入命令行但不执行。
  • history:覆盖(较小的)默认历史计数。
  • jump(别名为j):跳转到已哈希的目录。
  • regmv:批量重命名文件(例如regmv '/\.tif$/.tiff/' *)。
  • scratch:创建一个随机临时scratch目录并cd进入。
  • tick:移动现有的时间扭曲(例如tick +1h);见下面tw的描述了解时间扭曲。
  • tmux:包装器,重新连接到已存在的会话,或根据当前目录名创建新会话;此外,寻找.tmux文件来设置窗口和窗格(注意,首次遇到给定的.tmux文件时,包装器会询问用户是否信任或跳过它)。
  • tw("时间扭曲"):覆盖GIT_AUTHOR_DATEGIT_COMMITTER_DATE(例如tw -1d)。

提示符

Zsh配置了以下提示符:

这里可以看到:

  • 简洁的左侧提示符,包括:
    • 当前目录的最后一个组件(可能将$HOME缩写为~)。
    • 提示符标记,即"重右尖括号装饰"(即\u276f,或UTF-8中的e2 9d af)。
  • 扩展的右侧提示符,在必要时自动隐藏以为长命令腾出空间,包含:
    • 上一个命令的持续时间,使用自适应单位(秒、分钟、小时、天,取决于持续时间)。
    • 当前版本控制分支名称。
    • 当前版本控制工作树状态,使用与git status中相匹配的颜色:
      • 绿点表示已暂存的更改。
      • 红点表示未暂存的更改。
      • 蓝点表示未跟踪的文件。
    • 当前工作目录的完整版本(同样,将$HOME缩写为~)。

嵌套的shell通过额外的提示符字符表示。例如,一个嵌套的shell:

两个嵌套的shell:

root shell通过不同颜色的提示符字符和"root"字样表示:

root shell内的嵌套如下所示:

两个嵌套的shell:

如果上一个命令以非零状态退出(通常表示错误),会显示一个黄色感叹号:

如果存在后台进程,会显示一个黄色星号:

依赖项

平台状态

平台状态
macOS:1st_place_medal: 目前测试最多的平台,也是涉及方面最多的平台(因为我的日常驱动是 macOS 13 "Sonoma")
Arch Linux:2nd_place_medal: 测试较少,涉及方面较少,但可能会在未来发展,因为我在"休闲"台式机上使用 Arch Linux
Red Hat Linux 及相关系统(如 CentOS):skull: 已放弃,但在过去(2011-2018 年)这是我在工作中全职使用的发行版

安装

克隆

开发在 main 分支进行,但为了避免给之前在 master 分支是主线时克隆仓库的人带来不便,通过 pre-push 钩子(更新本地分支)和 post-receive 钩子(更新远程分支)保持旧分支的更新。

macOS

git clone --recursive https://github.com/wincent/wincent.git

Arch Linux

sudo pacman -Syu sudo pacman -S git ruby tmux vim git clone --recursive https://github.com/wincent/wincent.git
  • git:用于克隆仓库。
  • ruby:使 git-cipher 能够运行(也用于构建 Command-T)。
  • tmux:仅为舒适性(例如,可以查看滚动记录)。
  • vim:因为 nvim 方面需要 Vim(它运行 vim 来执行 :helptags 更新)。

安装

⚠️ 警告:很多 不同的东西可以安装或配置(参见 aspects/ 目录)。除非你希望你的机器完全像我的一样——这是不太可能的——你可能不想安装 所有 东西。也许你甚至不想要 "dotfiles""nvim" 方面的所有内容。请在继续安装之前检查每个方面的内容;你甚至可能只想查看配置文件并借鉴你觉得有趣或有用的部分(除非另有说明,所有内容都在 公共领域)。

在撰写本文时,这些是可能随时间变化的方面(请查看 aspects/ 目录 以获取最新列表):

  • 仅在 macOS 上:
    • automator:用于 Automator 的脚本
    • automount:设置 macOS 的自动挂载功能
    • backup:备份脚本
    • cron:设置 cron 文件
    • defaults:设置 macOS 的默认值(即偏好设置)
    • fonts:安装 Source Code Pro 字体文件
    • homebrew:安装和更新 Homebrew
    • karabiner:配置 Karabiner-Elements(键盘定制)
    • launchd:配置 launchd
    • nix:通过 Nix 包管理器安装包
    • node:安装 Node.js
    • ruby:安装 Ruby gems
    • ssh:管理本地 SSH 配置
    • violentmonkey:设置 UserScripts
  • 仅在 Linux 上:
    • apt:使用 apt-get 安装包
    • aur:从 Arch User Repository 安装包
    • avahi:管理 Avahi zeroconf("Bonjour")网络守护进程
    • interception:设置 Interceptions Tools(键盘定制)
    • locale:设置 /etc/locale.conf
    • pacman:通过 Pacman 包管理器安装包
    • sshd:管理 sshd
    • systemd:设置从 systemd 运行的服务
  • 在 macOS 和 Linux 上:
    • dotfiles:在 $HOME 中创建指向此仓库中 dotfiles 的符号链接
    • meta:测试配置框架
    • shell:将使用的 shell 设置为 zsh
    • terminfo:设置 terminfo 数据库条目以支持斜体和 256 色
    • nvim:配置 Neovim 和 Vim

示例

./install dotfiles nvim # 仅安装 "dotfiles" 和 "nvim" 内容。 ./install dotfiles # 仅安装 "dotfiles"。 ./install dotfiles --step # 在每个步骤提示确认。 ./install dotfiles --check # 进行干运行,显示将要更改的内容。 ./install # 安装所有内容。 ./install ^homebrew # 安装除 "homebrew" 方面外的所有内容。 ./install --help # 列出所有方面、描述和选项。

这会使用 n 设置本地 Node 环境,然后使用 Fig 复制 dotfiles 并配置机器。

注意: 鉴于这些 dotfiles 中包含了 ~/.config/git/config,任何本地修改或覆盖都应该添加到 ~/.config/git/config.local 中;例如:

git config --file ~/.config/git/config.local user.name "John Doe" git config --file ~/.config/git/config.local user.email johndoe@example.com

故障排除

一般故障排除

./install 有几个有用的选项:

# 在"检查"(干运行)模式下运行。 ./install --check # 在运行期间显示调试信息。 ./install --debug # 在运行每个任务之前确认(--step),并从特定方面("dotfiles") # 的特定任务开始执行(--start-at-task)。 ./install --step --start='make directories' dotfiles

./install 在首次运行时挂起

如果在全新的操作系统安装上运行,而你之前从未使用过 sudo./install 可能在请求你输入密码后看似挂起。这是因为 sudo 可能在首次运行时显示一个"讲座"2,需要你对提示做出响应。在 ./install 的上下文中运行时,你永远看不到这个提示,因为 sudo 在子进程中运行,这导致运行挂起。

为避免这种情况,只需在运行 ./install 之前运行一次 sudo -v

许可证

除非另有说明,此仓库的内容属于公共领域。详情请参阅 LICENSE

作者

此仓库由 Greg Hurrell <greg@hurrell.net> 编写和维护。其他提交过补丁的贡献者按字母顺序包括:

  • Anton Kastritskiy
  • Hashem A. Damrah
  • Joe Lencioni
  • Jonathan Wilkins
  • Keng Kiat Lim
  • Mark Stenglein
  • Matthew Byrne
  • Michael Lohmann
  • Stone C. Lasley
  • Victor Igor
  • Zac Collier

此列表由以下命令生成:

:read !git shortlog -s HEAD | grep -v 'Greg Hurrell' | cut -f 2-3 | sed -e 's/^/- /'

安全性

commit ec49be762ff3("feat(dotfiles): automatically sign commits on personal machines",2022-06-19)和 commit 97143b5d7635("feat(dotfiles): sign commits everywhere except codespaces",2022-06-20)开始,我开始使用与我的工作和个人电子邮件地址对应的 GPG 密钥签署此仓库和其他仓库中的大多数提交。 GitHub会用"已验证"徽章标记这类提交。要使用git命令行可执行文件查看签名信息,你可以运行git show --show-signaturegit log --show-signature等命令。请注意,为了能够实际验证这些签名,你需要相应的公钥副本,否则Git会显示:

gpg: 签名于 2022年7月11日 星期一 11:50:35 CEST
gpg:                使用 RSA 密钥 B0C9C204D656540BDCDA86229F6B84B5B1E9955E
gpg:                签发者 "wincent@github.com"
gpg: 无法检查签名:没有公钥

你可以通过以下方式获取公钥:

# 方法一:根据Git显示的密钥指纹直接下载:
gpg --keyserver pgp.mit.edu --recv-key C7C225A18975180C4485A1E070516DBB88E4F779
gpg --keyserver pgp.mit.edu --recv-key B0C9C204D656540BDCDA86229F6B84B5B1E9955E

# 方法二:通过搜索电子邮件地址选择可能的匹配项:
gpg --keyserver https://pgp.mit.edu/ --search-keys greg@hurrell.net
gpg --keyserver https://pgp.mit.edu/ --search-keys wincent@github.com

如果你信任GitHub,也可以直接从GitHub获取密钥:

curl https://github.com/wincent.gpg | gpg --import

获取这些密钥后,Git会显示:

gpg: 签名于 2022年7月11日 星期一 12:28:32 CEST
gpg:                使用 RSA 密钥 B0C9C204D656540BDCDA86229F6B84B5B1E9955E
gpg:                签发者 "wincent@github.com"
gpg: Greg Hurrell <wincent@github.com> 的签名正确 [未知]
gpg: 警告:此密钥未经可信签名认证!
gpg:          无法确定签名是否属于所有者。
主密钥指纹: 2F44 69E0 C1FA 72AA C0A5  60C9 6210 6B56 923F 3481
     子密钥指纹: B0C9 C204 D656 540B DCDA  8622 9F6B 84B5 B1E9 955E

从密码学角度来看,这里发生了什么?

  • GPG密钥由公钥和私钥组成,通常称为公钥和私钥(一起称为"密钥对")。顾名思义,密钥所有者必须保密私钥部分,但公钥部分可以自由共享。
  • 简单来说,"签名"意味着使用私钥加密被签名文档内容的哈希值(在这种情况下,"文档"是一个提交)。
  • 公钥可用于解密哈希值,然后将其与内容进行比较以确认匹配。这就是我们看到上面"gpg: 签名正确"时发生的情况;这意味着Greg Hurrell wincent@github.com的公钥验证了签名确实是由该地址对应的私钥创建的。
  • 因为只有所有者可以访问私钥,所以只有所有者可以用它创建签名;但相反,因为每个人都可以访问公钥,所以任何人都可以验证这些签名。
  • GPG密钥还有两个额外的概念:"子密钥"是与主密钥关联的密钥;"用途"描述了这些密钥各自扮演的角色(例如"签名"、"加密")。
  • 实际上,主密钥始终是"签名"密钥,GPG默认会创建一个"加密"子密钥。用户可以添加/删除额外的子密钥并为它们分配用途。
  • 我创建"签名"子密钥用于制作签名,并每年轮换一次(我将主密钥保持"离线",以防我的机器被入侵时被黑客攻击)。

这些是密码学的基本原理。从密码学的角度来看,签名是"正确的",但为什么会有那个可怕的"警告"呢?这是因为在此之上还有一个叫做"信任网络"的层。正确的签名给了我们数学上的确定性,即特定的私钥确实被用来产生给定的签名,但这并不能告诉我们存在于该加密之上和周围的人类世界的任何信息。也就是说,密钥被用来制作签名,但使用密钥的是否真的是我?我真的是那个自称Greg Hurrell的住在马德里的英俊澳大利亚人,还是事实上我是一个在北极海使用卫星连接的潜水艇上运作的秘密犯罪组织的一部分?

信任网络的作用是将你在人类层面的信任关系与底层的数字实体联系起来。通过运行gpg --edit-key $KEY并按下trust,你可以明确记录你对任何给定密钥的信任级别,你还可以做一些事情,比如参加"密钥签名派对",在那里你可以亲自见到人们,通过你认为适当的方式验证他们的身份,然后相互签署对方的公钥。随着时间的推移,这些行为的累积效果是建立一个信任可以传递应用的连接网络:如果你信任A,A信任B,那么你也可以信任B。话虽如此,如何实际建立一个有用的信任网络超出了本README的范围,在我多年的互联网经历中,我从未参加过密钥签名活动或从事其他有助于将我的密钥整合到有用的信任网络中的活动。

[^1]:晚上是用vi衍生品度过的,而不是和比尔·乔伊在一起。

Footnotes

  1. 在Linux上不需要这样做,因为我们可以通过Kitty配置实现相同的效果。

  2. 参见 man sudoers

编辑推荐精选

即梦AI

即梦AI

一站式AI创作平台

提供 AI 驱动的图片、视频生成及数字人等功能,助力创意创作

扣子-AI办公

扣子-AI办公

AI办公助手,复杂任务高效处理

AI办公助手,复杂任务高效处理。办公效率低?扣子空间AI助手支持播客生成、PPT制作、网页开发及报告写作,覆盖科研、商业、舆情等领域的专家Agent 7x24小时响应,生活工作无缝切换,提升50%效率!

Keevx

Keevx

AI数字人视频创作平台

Keevx 一款开箱即用的AI数字人视频创作平台,广泛适用于电商广告、企业培训与社媒宣传,让全球企业与个人创作者无需拍摄剪辑,就能快速生成多语言、高质量的专业视频。

TRAE编程

TRAE编程

AI辅助编程,代码自动修复

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

AI工具TraeAI IDE协作生产力转型热门
蛙蛙写作

蛙蛙写作

AI小说写作助手,一站式润色、改写、扩写

蛙蛙写作—国内先进的AI写作平台,涵盖小说、学术、社交媒体等多场景。提供续写、改写、润色等功能,助力创作者高效优化写作流程。界面简洁,功能全面,适合各类写作者提升内容品质和工作效率。

AI辅助写作AI工具蛙蛙写作AI写作工具学术助手办公助手营销助手AI助手
问小白

问小白

全能AI智能助手,随时解答生活与工作的多样问题

问小白,由元石科技研发的AI智能助手,快速准确地解答各种生活和工作问题,包括但不限于搜索、规划和社交互动,帮助用户在日常生活中提高效率,轻松管理个人事务。

热门AI助手AI对话AI工具聊天机器人
Transly

Transly

实时语音翻译/同声传译工具

Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。

讯飞智文

讯飞智文

一键生成PPT和Word,让学习生活更轻松

讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。

AI办公办公工具AI工具讯飞智文AI在线生成PPTAI撰写助手多语种文档生成AI自动配图热门
讯飞星火

讯飞星火

深度推理能力全新升级,全面对标OpenAI o1

科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。

热门AI开发模型训练AI工具讯飞星火大模型智能问答内容创作多语种支持智慧生活
Spark-TTS

Spark-TTS

一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型

Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。

下拉加载更多