Windows 的开发好痛苦

windows 的开发好痛苦作者:christine dodrill(已获授权),全栈开发

译者:弯月

来源:CSDN(ID:CSDNnews)

以下为译文:

本文表达的观点可能与你的看法有所不同。本文没有针对任何个人或组织,只是我个人在 Windows 上开发时屡屡受挫有感而发。文中的观点只代表个人。

最近,由于我需要在 Oculus Quest 2(VR一体机)上使用 VR,因此不得不经常使用 Windows。为了使用 Virtual Desktop,我必须把 Windows 作为主力机器。下文记录了我在 Windows 上尝试一些“基本”的开发任务时,所遭遇的痛苦经历。

01

文本编辑器

多年以来,我已经习惯了使用 Vim,以至于我的思维方式都习惯了 Vim。作时,我只需要使用键盘专心致志地工作,因为我的注意力都集中在当前的输入上。另外,我已经习惯了 Emacs 的设置,而且特别依赖于 Vim 模拟和各种稀奇古怪的小设置。

我努力尝试在 Windows 上使用同样的 Emacs 设置(并去掉一些显然不可能的操作,比如在 Windows 上使用 Nix 等),但很快我就发现,这完全是在浪费时间。将 Linux/macOS 的配置改成 Windows 需要修改的地方太多了。算了,我还是直接使用 VSCode 吧。它在 NixOS 上运行良好,所以在 Windows 上应该问题不大吧?

首先我安装了 Vim 插件 vscodevim。安装好插件后,我打开了一个文件夹。用 :open 可以打开一个文件然后进行输入。然后,我想使用 :vsplit 垂直打开另一个文件,于是我输入了 :vsplit bar.txt,结果当前窗口却被垂直分割了,而不是在垂直分割的窗口中打开我需要的文件。当然,这也许是我非常习惯的另一个技巧而已(尽管这个行为在原版vim上非常好用),我询问过的其他人都不这么用(甚至有人完全不知道这个命令还能这么用),但这个动作已经深入了我的肌肉记忆,因此丧失这种用法让我倍感沮丧。我不得不重新训练十多年的肌肉记忆。

Vim 有一个叫做 whichwrap 的功能,当光标移动到行尾或行首时,可以使用方向键将光标移动到下一行的行首,或上一行的行尾。我从 2013 年 11 月就在 Vim 中加入了这个设置,然后甚至忘了自己曾经加过这个设置,以至于我以为这是 Vim 的默认行为。

但是,很显然我错了。

要想改正这个问题,只能在 VSCode 的 settings.json 中加入下面这一行:

代码语言:javascript代码运行次数:0运行复制“`javascript{ “vim.whichwrap”: “h,l,,[,]”}

很烦人,但至少可以正常使用。

Vim 中有寄存器的概念,有命名和未命名之分,近似于大多数桌面环境中的剪贴板,在我的 Emacs 设置中,剪贴板和删除寄存器是一样的。如果复制一大段文字到删除寄存器中,实际上就是放到剪贴板中。如果我向剪贴板中放入一些内容,实际也会自动放到删除寄存器中。这个操作其实非常方便。

然而这并不是 vscodevim 中的默认操作,不过有个选项可以实现这一点:

代码语言:javascript代码运行次数:0<svg fill="none" height="16" viewbox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M6.66666 10.9999L10.6667 7.99992L6.66666 4.99992V10.9999ZM7.99999 1.33325C4.31999 1.33325 1.33333 4.31992 1.33333 7.99992C1.33333 11.6799 4.31999 14.6666 7.99999 14.6666C11.68 14.6666 14.6667 11.6799 14.6667 7.99992C14.6667 4.31992 11.68 1.33325 7.99999 1.33325ZM7.99999 13.3333C5.05999 13.3333 2.66666 10.9399 2.66666 7.99992C2.66666 5.05992 5.05999 2.66659 7.99999 2.66659C10.94 2.66659 13.3333 5.05992 13.3333 7.99992C13.3333 10.9399 10.94 13.3333 7.99999 13.3333Z" fill="currentcolor">运行<svg fill="none" height="16" viewbox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="M4.5 15.5V3.5H14.5V15.5H4.5ZM12.5 5.5H6.5V13.5H12.5V5.5ZM9.5 2.5H3.5V12.5H1.5V0.5H11.5V2.5H9.5Z" fill="currentcolor" fill-rule="evenodd">复制```javascript{ "vim.useSystemClipboard": true}

这样删除寄存器就与我想象的一样了。

Emacs 可以控制插件的加载顺序。如果需要在语言支持插件加载之前加载项目本身的插件,这个功能就会非常有用,这样可以保证在语言服务器运行之前设置正确的环境变量。

据我所知,VSCode 无法配置这一点。在某个项目中我必须禁用 Go 插件并重载 VSCode,等待 direnv 设置生效之后,再重新启用 Go 插件。如果能指定插件加载顺序,实现这一点就非常容易,但显然 VSCode 不允许你控制加载顺序。

02

开发工具

我使用的终端是 st,shell 是 fish。这个组合其实非常好,因为加载速度很快,并且 fish 支持很多好用的功能,例如基于历史的自动补齐等。更不用说,st 还支持选择即复制、右键粘贴的功能,在需要快速移动文本时非常方便。

Git 并不是默认开发工具之一。这一点非常令我非常惊讶。我手工安装了 Git,但发现它安装了自己的 bash、perl 和 coreutils。这一点在意料之中(许多 Git 的命令都是用 Perl 和 shell 脚本写的),但这已经是我的系统中安装的第三份 bash 了。

作为一个 NixOS 用户,这应该并不是什么大问题。我的 NixOS 上至少有 8 个不同版本的 bash。但是,安装那些 bash 的主要原因是我可以切换到不同的版本,并回到某个过去的旧系统。然而这三个 bash 都是有用的,但它们互相不知道彼此的存在(而安装这些 bash 的应用程序似乎也是对的,它们采用了保守的策略,自己安装自己的 bash,减少兼容性问题)。

安装完之后 git 就可以正常用了。我很高兴地发现 Windows 会默认安装 ssh 甚至 ssh-keygen。这一点非常方便,我不需要再装一个 bash 了。

Windows Terminal 许多方面的设计都还不错,但也犯了许多错误。我很高兴看到它实现了与 xterm 的兼容性。测试这一点的常见做法是打开一个使用鼠标的 curses 应用(如 Weechat 或终端版的 Emacs),然后随便点击鼠标。这样就可以看出终端模拟器是否与之兼容。我用ssh连接到服务器,登录到 tmux 中,然后点击了 Weechat 中的一个频道名。

结果什么都没有发生。

腾讯AI 开放平台 腾讯AI 开放平台

腾讯AI开放平台

腾讯AI 开放平台 161 查看详情 腾讯AI 开放平台

我又点击了一次,还是什么都没有发生。

我很奇怪,做了一些调查,然后发现原来是 Windows 自带的 ssh 版本太老了。这一点可以理解,在 Windows 系统中加入某个工具时,最好还是选择比较老的版本,这样才能保证长期的兼容性。这并不是最好的选择,但从长期支持的角度来看,也是一种方案。网上建议我下载新版的 OpenSSH。

我下载了 zip 包并解压,然后发现了许多二进制文件,而且没有任何说明该如何安装。好吧,毕竟是系统的核心部分。另一个评论说,WSL 中修复了该问题,我试试看。

WSL(Windows下的Linux子系统)是一个技术奇迹,有了它,Windows 用着就顺手多了。当然,如果它的默认选择不是 Ubuntu 就更好了。当然,我不是说 Ubuntu 不好。我只是说它并不是我习惯的发行版而已。

但是,我可以用它 ssh 到我的服务器上,然后实现 Weechat 中的点击。

也许我应该看看在 WSL 中运行类 NixOS 的系统难不难,但 WSL 没办法运行 systemd,所以还是算了。

有人说,通过命令行界面基本命令(如改变目录、列出文件、下载文件等)的设计方式可以学到很多知识。在 PowerShell 中,这些命令是 Get-ChildItem、Set-Location 和 Invoke-WebRequest。而它也提供了别名 ls、dir、cd 和 wget(这些别名的选项并不一定兼容,所以如果你想做一些特别的事情,就需要习惯PowerShell的用法)。

另一个讨厌的地方是 Ctrl-D 并不会结束会话。不过这一点可以通过以下方式实现:

PS C:Usersxena> code $profile

然后向.ps1文件中加入:

Set-PSReadlineOption -EditMode Emacs

保存并重新打开PowerShell。

如果是第一次编辑 PowerShell 配置,那你必须修改执行策略,才能在本机执行脚本。我理解为什么要这样做,因为 PowerShell 很强大,这个策略能避免很多脚本攻击。但这个策略同样禁止了 profile 的执行。所以你需要选择 PowerShell 脚本的安全级别。通常,我会选择 RemoteSigned。

我使用的主题是 oh my fish,所以搜索了一下 oh my powershell,希望能找到一些功能完备的工具。结果很幸运。

一番研究后我看到了一个名为 sorin 的主题,大致如下:

Windows 的开发好痛苦项目本地依赖

我必须在 WSL 中利用Nix实现这一点。VSCode 有很好的集成,但我希望能更加有更加原生的方法。03

Windows的优点

对于开发人员而言,Windows 最大的优点是向后兼容。过去 30 年的任何程序都可以直接安装,并且都能运行。

所有我玩过的游戏都是 Windows 的,也不需要像 Linux 版 Steam 那样修改设置才能运行游戏。所有与 VR 有关的功能也都运行良好。所有下载下来的游戏都能玩,不需要修改 GPU 驱动的路径。而且几乎报告的任何问题都能得到妥善解决。

总的来说,我想我可以忍受 Windows 上的开发体验。虽然不是最理想的设置,但确实可以坚持完成工作。尽管我很怀念 NixOS。NixOS 会惯坏你,给你留下许多不切实际的习惯,而且一旦养成很难遗忘。

所以最后的结论就是没有结论。

原文链接:https://www.php.cn/link/76ef690583787dbd1405245dc8d9d72a

声明:本文为CSDN翻译,转载请注明来源。

以上就是Windows 的开发好痛苦的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/404704.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
浙江大学最新Nano Letters:面向实时网络入侵检测系统的自整流忆阻器
上一篇 2025年11月6日 20:43:19
Akka tell 操作消息顺序性深度解析:保证与限制
下一篇 2025年11月6日 20:43:48

相关推荐

  • 修复Django电商项目中AJAX过滤产品列表图片不显示问题

    在Django电商项目中,当使用AJAX动态加载过滤后的产品列表时,常遇到图片无法正常显示的问题。这通常是由于前端模板中图片加载方式(如data-setbg属性结合JavaScript库)与AJAX动态内容更新机制不兼容所致。解决方案是直接在AJAX返回的HTML中使用标准的标签来渲染图片,确保浏览…

    2026年5月10日
    000
  • 开源免费PHP工具 PHP开发效率提升利器

    推荐开源免费PHP开发工具以提升效率:VS Code、Sublime Text轻量高效,PhpStorm专业强大;调试用Xdebug、Kint、Ray;依赖管理选Composer;代码质量工具包括PHPStan、Psalm、PHP_CodeSniffer;数据库管理可用%ignore_a_1%MyA…

    2026年5月10日
    000
  • Matplotlib 地图中多类型图例的创建与优化

    Matplotlib 地图中多类型图例的创建与优化Matplotlib 地图中多类型图例的创建与优化Matplotlib 地图中多类型图例的创建与优化Matplotlib 地图中多类型图例的创建与优化

    本教程旨在解决matplotlib地图可视化中,如何在一个图例中同时展示颜色块(如区域分类)和自定义标记(如特定兴趣点)的问题。文章详细介绍了当传统`patch`对象无法正确显示标记时,如何利用`matplotlib.lines.line2d`创建标记图例句柄,并将其与颜色块图例句柄合并,从而生成一…

    2026年5月10日 用户投稿
    100
  • Golang JSON序列化:控制敏感字段暴露的最佳实践

    本教程探讨golang中如何高效控制结构体字段在json序列化时的可见性。当需要将包含敏感信息的结构体数组转换为json响应时,通过利用`encoding/json`包提供的结构体标签,特别是`json:”-“`,可以轻松实现对特定字段的忽略,从而避免敏感数据泄露,确保api…

    2026年5月10日
    000
  • 怎么在PHP代码中实现图片上传功能_PHP图片上传功能实现与安全处理教程

    首先创建含enctype的HTML表单,再用PHP接收文件,检查目录、移动临时文件,验证类型与大小,生成唯一文件名,并调整php.ini限制以确保上传成功。 如果您尝试在PHP项目中添加图片上传功能,但服务器无法正确接收或保存文件,则可能是由于表单配置、文件处理逻辑或安全限制的问题。以下是实现该功能…

    2026年5月10日
    100
  • Golang gRPC流式请求异常处理

    在Golang的gRPC流式通信中,必须通过context.Context处理异常。应监听上下文取消或超时,及时释放资源,设置合理超时,避免连接长时间挂起,并在goroutine中通过context控制生命周期。 在使用 Golang 和 gRPC 实现流式通信时,异常处理是确保服务健壮性的关键部分…

    2026年5月10日
    000
  • Go语言mgo查询构建:深入理解bson.M与日期范围查询的正确实践

    本文旨在解决go语言mgo库中构建复杂查询时,特别是涉及嵌套`bson.m`和日期范围筛选的常见错误。我们将深入剖析`bson.m`的类型特性,解释为何直接索引`interface{}`会导致“invalid operation”错误,并提供一种推荐的、结构清晰的代码重构方案,以确保查询条件能够正确…

    2026年5月10日
    100
  • vscode上怎么运行html_vscode上运行html步骤【指南】

    首先保存文件为.html格式,再通过浏览器或Live Server插件打开预览;推荐安装Live Server实现本地服务器运行与实时刷新,提升开发体验。 在 VS Code 上运行 HTML 文件并不需要复杂的配置,只需几个简单步骤即可预览页面效果。VS Code 本身是一个代码编辑器,不直接运行…

    2026年5月10日
    100
  • 修复点击时按钮抖动:CSS垂直对齐实践

    本文探讨了在Web开发中,交互式按钮(如播放/暂停按钮)在点击时发生意外垂直位移的问题。通过分析CSS样式变化对元素布局的影响,我们发现这是由于按钮不同状态下的边框样式和内边距改变,以及默认的垂直对齐行为共同作用所致。核心解决方案是利用CSS的vertical-align属性,将其设置为middle…

    2026年5月10日
    100
  • Golang goroutine与channel调试技巧

    使用go run -race检测数据竞争,结合runtime.NumGoroutine监控协程数量,通过pprof分析阻塞调用栈,利用select超时避免永久阻塞,有效排查goroutine泄漏、死锁和数据竞争问题。 Go语言的goroutine和channel是并发编程的核心,但它们也带来了调试上…

    2026年5月10日
    000
  • 使用 Jupyter Notebook 进行探索性数据分析

    Jupyter Notebook通过单元格实现代码与Markdown结合,支持数据导入(pandas)、清洗(fillna)、探索(matplotlib/seaborn可视化)、统计分析(describe/corr)和特征工程,便于记录与分享分析过程。 Jupyter Notebook 是进行探索性…

    2026年5月10日
    000
  • 如何在HTML中插入表单元素_HTML表单控件与输入类型使用指南

    HTML表单通过标签构建,包含action和method属性定义数据提交目标与方式,常用input类型如text、password、email等适配不同输入需求,配合label、required、placeholder提升可用性,结合textarea、select、button等控件实现完整交互,是…

    2026年5月10日
    100
  • 前端缓存策略与JavaScript存储管理

    根据数据特性选择合适的存储方式并制定清晰的读写与清理逻辑,能显著提升前端性能;合理运用Cookie、localStorage、sessionStorage、IndexedDB及Cache API,结合缓存策略与定期清理机制,可在保证用户体验的同时避免安全与性能隐患。 前端缓存和JavaScript存…

    2026年5月10日
    200
  • HTML5网页如何实现手势操作 HTML5网页移动端交互的处理技巧

    首先利用原生touch事件实现滑动判断,再通过preventDefault解决滚动冲突,接着引入Hammer.js处理复杂手势,最后通过优化点击区域、避免事件冲突和增加视觉反馈提升体验。 在移动端浏览器中,HTML5网页可以通过触摸事件实现手势操作,提升用户体验。虽然原生JavaScript提供了基…

    2026年5月10日
    000
  • 深入理解 Express.js 中 next() 参数的作用与中间件机制

    本文深入探讨 express.js 中间件函数中的 `next()` 参数。它负责将控制权传递给请求-响应周期中的下一个中间件或路由处理程序。文章将详细解释 `next()` 的工作原理、中间件的注册与执行顺序,以及不正确使用 `next()` 可能导致请求挂起的风险,并通过代码示例和实际应用场景,…

    2026年5月10日
    000
  • 创建指定大小并填充特定数据的Golang文件教程

    本文将介绍如何使用Golang创建一个指定大小的文件,并用特定数据填充它。我们将使用 `os` 包提供的函数来创建和截断文件,从而实现快速生成大文件的目的。示例代码展示了如何创建一个10MB的文件,并将其填充为全零数据。掌握这些方法,可以方便地在例如日志系统或磁盘队列等场景中,预先创建测试文件或初始…

    2026年5月10日
    000
  • Python命令怎样使用profile分析脚本性能 Python命令性能分析的基础教程

    使用Python的cProfile模块分析脚本性能最直接的方式是通过命令行执行python -m cProfile your_script.py,它会输出每个函数的调用次数、总耗时、累积耗时等关键指标,帮助定位性能瓶颈;为进一步分析,可将结果保存为文件python -m cProfile -o ou…

    2026年5月10日
    000
  • JavaScript 闭包:理解闭包原理与内存泄漏问题

    闭包是函数访问其外部作用域变量的能力,即使外部函数已执行完毕。如 inner 函数引用 outer 中的 count,形成闭包,使变量持久存在。闭包本身无害,但可能因延长变量生命周期导致内存泄漏,例如事件监听器引用大对象时。若未及时清理 DOM 事件或定时器,闭包会阻止垃圾回收,造成内存占用过高。解…

    2026年5月10日
    100
  • JavaScript 动态菜单点击高亮效果实现教程

    本教程详细介绍了如何使用 JavaScript 实现动态菜单的点击高亮功能。通过事件委托和状态管理,当用户点击菜单项时,被点击项会高亮显示(绿色),同时其他菜单项恢复默认样式(白色)。这种方法避免了不必要的DOM操作,提高了性能和代码可维护性,确保了无论点击方向如何,功能都能稳定运行。 动态菜单高亮…

    2026年5月10日
    200
  • c++如何实现UDP通信_c++基于UDP的网络通信示例

    UDP通信基于套接字实现,适用于实时性要求高的场景。1. 流程包括创建套接字、绑定地址(接收方)、发送(sendto)与接收(recvfrom)数据、关闭套接字;2. 服务端监听指定端口,接收客户端消息并回传;3. 客户端发送消息至服务端并接收响应;4. 跨平台需处理Winsock初始化与库链接,编…

    2026年5月10日
    100

发表回复

登录后才能评论
关注微信