Skip to main content

· 5 min read

我的工作流中会同时使用Vim(Neovim)和tmux来完成代码的“编写、运行、修改“这个循环,有时会开启多个tmux窗格和vim窗口。这篇文章介绍我最近发现的如何在这二者窗格之间无缝切换。

Vim

我会在vim中开启多个窗口完成代码编辑工作,例如在另一个窗口中参考API或者是两个有关系的代码块在两个buffer中。我使用<Leader>h/j/k/l 来在vim中切换多个窗口。我的<Leader>为空格键。

Windows in Vim

在上图中,我使用<Leader>j<Leader>k从上下两个窗口切换。

tmux

虽然各类浮动或靠边的终端已经可以比较容易的运行在Neovim中,有时仍有其他需求让我需要使用tmux:例如

  1. 退出Neovim之后去看一下其他shell的运行结果。
  2. 希望分割不同层次的工作。
  3. 没有使用Neovim的时候。

我在tmux的配置为:前缀键为<Ctrl-Space>,使用vi mode-keys,所以我在不同窗口之间切换的方式是:<Ctrl-Space>j/k/h/l

set-window-option -g mode-keys vi

# change default prefix
unbind-key C-b
set-option -g prefix C-Space
bind-key C-Space send-prefix

隔阂

  1. 这两者之间的体验不同,有时候我希望切换到某个窗口按了几次键没有作用才发现我混淆了二者。这很容易让我从上述循环中分神。
  2. tmux的前缀键需要按到ctrl,如果经常按过去,小拇指保护协会发出强烈抗议。尤其是,试一试ctrl+space这个按键,如果还是大拇指按下space,小拇指则会非常痛苦。
  3. 由于我不想使用Ctrl作为修饰键,所以我一直避免在我的Neovim配置中使用Ctrl键,这导致我的Vim命令空间的有很大一个损失,经常找不到还能绑定的键。

解决

我找到了一个非常棒的Vim/tmux插件:vim-tmux-navigator,这个仓库既作为一个vim插件,也作为一个tmux插件,我想要的二者之间的无缝切换。

太长不看版:这使得你可以使用同一套窗口导航快捷键,例如我现在使用<Ctrl-h/j/k/l>这一套快捷键来导航。具体实现可以参考仓库代码,其实是给导航的快捷键包了一层“检验是否在Vim中以及是否需要跳出Vim”的逻辑。

配置并不复杂:

  • 使用你的Vim插件管理器安装该插件(Vim-Plug/Packer/...)
  • 使用TPM(Tmux插件管理器)安装该插件
  • 使用<Ctrl-h/j/k/l> 作为你的Vim窗口导航快捷键。(也许可以设置为其他值,但是这对我而言已经足够好了,我还没有了解更多)

Ohhh,另外第三个缺点怎么办?Ctrl键仍然在非常反人类的位置,我们这么大规模的使用Ctrl,对小拇指可不是个好消息。今天上午我在想这个问题,结合以前的经验,我找到了一个很多人用的修改键盘映射的软件。也许不同平台有不同的这样的软件,我在Mac上使用的是Karabiner-Elements。

把中英文切换键(也就是Capslock键)映射为Ctrl,这估计是很多人的操作了。再使用右Command键作为中英文切换,OK,我还多利用起了一个几乎没有作用的右Command键。

效果

我现在并不Care我在使用什么软件,只要是分割窗口,我使用同一套快捷键切过去就可以。这极大减少了我工作流的中断,也许这对你也有用!

· 8 min read

我算是最晚写年终总结的人吧?也许本来我也没想起来写,是因为我觉得过年在老家有些无聊。 就像2020年我也没有总结,应该是因为当时还有挺多事情的,这个年过的就稍微有点闲了。

起因

从年初来说,应该是刚刚忙完大三上一系列课程,肝的或者不肝的,水的或者不水的,然后寒假前夕看到一篇文章。我印象里是复旦大学生存指南,也许不是(但是这仍是一部非常有意义的小册子,推荐给所有大学生看,"四年时间是我们最宝贵也最沉重的投资,你想好怎么使用了吗?"的金句振聋发聩。)我决心探索一番:我究竟适合什么样的生活?或者说认真考虑随大流读研是我想要的吗?

所以我决定找一份实习,看看工作怎样。

阳光

找实习的过程并不尽如人意,前后面了字节三次,也许觉得我不符合预期,也许觉得我水平不行,给我挂了。最后我找了个学校旁边的阳光出行,离公寓非常近。

在阳光实习的组长是一个看起来挺年轻的大哥,也许是为了照顾实习生,他坚持让我用两周来学习Go,熟悉语言用完整的两周,其实我第一周就觉得自己能使用这门语言了。本来在学校里就是一门课新学一门语言,最后还要交作业,用全职的两周太奢侈了。后面一周我就边摸鱼边看技术花边新闻(指类似阮一峰博客里的周刊之类的东西)。后面我就在做一个内部平台的维护,BTW,前端也是我用 Vue 一起维护(因为人手不够,前端的人手似乎总是不够的,这也许和我们目前在舆论里对前端的劝退有关,但是这些岗位又是那么重要)

中间我发现有一些代码犯了 "Repeat Yourself" 的问题,显然之前有的开发者为了进度做了先拷贝再小修改的问题。并且我也遇到到因为进度原因,没有人愿意重构这个地方的经典状况。直到我离职,那个代码依旧是那个样子。 一共做了两个月,把学习的两周和春节算上,应该也就一个月多点,我就离职了。

中间有一个特别经典的事情,组长开会说我们这个组工作时长并不长啊,上面可能会怎么怎么看我们组...实际上原因是五个人里准点下班的有三个(笑),平均下来时长就不高了。并且提议我们6点后在公司做一些其他事情。因为当时我已经过了阿里云的三面了,第二天提了离职。(组长也许觉得是因为说了那些事情才导致我离职的,其实不是,虽然这种不好的风气我也不喜欢,并且我当时完成自己的任务很容易,自然也很准时)

武汉,以及春天

开学的第一周是线上教学,然而我先和李老师去了一趟武汉,虽然武汉一直在常见的阴雨天气里,但是因为停留的四五天非常短暂,所以它自然留给旅人一种美妙的回忆。在武汉约在武大的老朋友一起逛校园,赏樱花。于磨山的林间小路骑车寻找艺术馆,在山的那边湖的那边和李老师做小型摩天轮。

在武汉的某一个早上接到了杭州打来的 HR 面电话,这意味着开学我就可以去那边实习啦。

因为想要兼顾学校和实习,所以我搬家到了一个中间点,并在这里度过了春天和夏天。

云原生?云原生是什么?

直到7月之前,我的大部分精力都在实习上(也许排第二的是通勤,笑)。在阿里云云原生某小组实习的第一个任务挺有挑战的,不过也没那么挑战。说到底别人看出了任务的必要性,收集了实现路径上的一些方法,明确了关键节点的可行性,最后交给我来完成。不过我入职后的三周都扑在这个上面了。

此时,课业是第二位的,我上了每周五的课。周末做作业,并且感谢小组成员们带我飞,团队有一些工作甚至没给我安排。

在公司的实习是蛮有意思的。设计和实现都要做,也许实习生做前一部分少一些,但是也是有的。我觉得遗憾的地方是,没有从头完成一个独立的事情(也许"从头"也比较模糊,且罢),所以毕设是一个很好的机会。

磕磕碰碰中,在真实场景里遇到了代码质量这样熟悉又陌生的名词。以前总是读,但是很少想,也很少实践,但是这些功能之外的东西,在实习里碰到了更多。

夏天快要过去了,我回忆起来的场景总是:刚刚结束期末考试的7月份,去和李老师散步的时候遇到的云彩。

阅读,阅读,还有网上冲浪

秋天回到了学校旁边的公寓,我也只是有时候去公司。我买了一些书,并且开始喜欢红楼梦和水浒传。不知不觉中冬天便来了。我参与了 cuetorial.com 的翻译,在后面阅读 Linus 自传 Just For Fun 的时候,才意识到这是一种与千里之外的人合作创造的乐趣。

2021 我做出了自己选择,有意思的事情但愿我都记录下来了。

· 3 min read

本书的英文名是 The Pragmatic Programmer: From Journeyman to Master 也就是大约两年前我开始写第一篇博客的时候, 作为博客名称的 Journeyman。意思是勤奋但不杰出的运动员(或者别的什么)。(有意思的是英语总是把一个很复杂的意思组合到一个词里,扯远了)这个词其实就是我,哈哈,动机是好的,但是有时候也不勤奋。

第二遍看《程序员修炼之道--从小工到专家》的时候,我又感觉到之前很多事情的道理已经有所阐明,感慨虽然时代略有不同,但职业图景并无太大变化。

石头汤:如何引领众人把一件事做成?石头汤就是这样一个故事,有时候你需要的就是务必亲自充当团队的催化剂。完成启动杂役(start fatigue),这件事令我有体会的地方在于,前两日我发现有人在带头翻译cuetorials.com,我想到如果有更多人因此去学习CUE,就更利于我们事业的发展。因为我们的工作是部分基于CUE的,而这是一门并不大众化的配置语言。所以我也兴致勃然地参与了部分翻译工作。当又一次看到这个故事的时候,我才意识到我就是故事里跟风的村民,不是说村民的工作没有意义,只是如果能总是“充当团队的催化剂”,主动完成启动杂役,我们就总能掌握主动,推动更多人完成工作。

调试

如果程序存在Bug,修复他而不是指责

作为一篇读书笔记,未完。

· One min read
Sébastien Lorber
Yangshun Tay

Docusaurus blogging features are powered by the blog plugin.

Simply add Markdown files (or folders) to the blog directory.

Regular blog authors can be added to authors.yml.

The blog post date can be extracted from filenames, such as:

  • 2019-05-30-welcome.md
  • 2019-05-30-welcome/index.md

A blog post folder can be convenient to co-locate blog post images:

Docusaurus Plushie

The blog supports tags as well!

And if you don't want a blog: just delete this directory, and use blog: false in your Docusaurus config.

· 8 min read

这两日实习期间,要做三个X功能下的子功能,在X功能下已经有F1~Fn,n个子功能,其中间相似度很高,所以新添加三个子功能的工作基本是复制粘贴,但是每个功能有其若干关键词不同。实现这三个功能由我和一位带我的同事共同完成,但是由于vim的替换功能之给力,让我倒是提前完成了我的部分,跟leader说后,他又分配了我一部分,我还是提前半小时左右完成工作摸鱼等下班了。

例如原来已有功能的是XXX,我们要添加的新功能关键词是YYY,那么我们要把其中一个函数从:UpdateXXXFoo改名为UpdateYYYFoo

涉及的改动大概有如下这两种:

  1. 涉及整个文件内的改动,例如从XXXFence.go复制出来一个YYYFence.go,这里面的函数、注释、字符串(例如写入日志的)都还是以XXX命名的
  2. 涉及在原有文件上增加一部分,例如给新功能注册路由。

那么涉及这两种的替换时,vim的替换如何发挥作用呢?

首先我们来看vim的替换的基本用法:

:s/foo/bar/g

这个命令把这一行遇到的所有foo替换为bar,如果没有,就什么都不做

:s (冒号是命令的一部分)表示替换命令,是substitute的缩写,然后用斜杠提示替换前的单词foo,再一个斜杠提示替换后的单词bar,再一个斜杠表示替换标志g

这个g表示替换这一行的所有foo,如果你指向替换第一个,可以用:s/foo/bar,不过就vim的效率思路,你应该直接用c指令去替换(扯远了)

能不能给力点啊?

来到前面这个问题,如果全局里的XXX要替换为YYY怎么办呢?答案是:

:%s/foo/bar/g

比上一个命令多的一个百分号,表示在整个文件进行替换

按照第一种改动,整个文件里的XXX都要改为YYY,可以直接这么操作。

%是怎么起作用的呢?其实他等价于1,$,也就是从第一行到最后一行生效这个命令($是最后一行的一个符号),换句话说,上一个命令可以写作

:1,$s/foo/bar/g

其实每个人一看到这种命令就有种自然的恐惧感,啊这又是什么,怎么就$都出来了,如果知道下面这个问题,其实1,$也没有那么可怕

:2,5<命令>

表示的就是这个命令从第二行到第五行生效,这种x,y表示从第x行到第y行执行接下来的命令是vim命令的一个常用操作

顺便:.表示的是当前行

能不能再给力一点啊?

其实在上面这些,大多数现代IDE都有好用的替换功能,例如IDEA的快捷键是Ctrl+R,全局替换对话框是Ctrl+Shift+R,但是至今我都没有找到,如何选中一个区域进行替换,而这时vim依然有这种操作。

区域替换,先来个例子,原来一个文件里就是用来定义枚举量的,文件内容像这样:

...

RequestXXXOperationA:=1
RequestXXXOperationB:=2
RequestXXXOperationC:=3

...

你添加了一个新功能,也要添加对应的枚举量,于是你先复制了一份XXX关键字的枚举量:

...

RequestXXXOperationA:=1
RequestXXXOperationB:=2
RequestXXXOperationC:=3

RequestXXXOperationA:=1
RequestXXXOperationB:=2
RequestXXXOperationC:=3

...

现在你不能用全局替换(显然的),如果用IDE替换,免不了先放对光标位置,再输入两个字符串,再点击三下replace这一顿操作

更有效率的方式是什么呢?先用

Vjj

(行可视模式选择,光标在第二个RequestXXXOperationA这一行)当然怎么选中是无所谓的,如果你刚粘贴完,光标在RequestXXXOperationC这一行,Vkk选中他们

这时再按:,你会发现命令里不只出现了冒号,他们是这样的:

:'<,'>

这是由vim自动补全的,这里的'<'>共同表示选中的区域(你也能猜到这表示了选中的区域的左右边界),他们和你刚刚看到的2,5表示的没有什么区别,都是限制了接下来命令的范围

你再接着敲完这个命令:

:'<,'>s/foo/bar/g

这样你就能选中刚才刚复制的部分进行替换了,不会影响到文件的其他部分。

能不能再给力一点啊?

其实再说就不是替换命令的部分了,vim的命令存在缓冲区(或者历史记录)

如果你输入冒号,再按上下键,就能找到你曾经输入过的命令

这么一来,如果你要复制三个文件并进行替换,并且其中混杂着蛇形命名法和驼峰命名法的关键字,如XxxYyy要替换为AaaBbb,而在另一个部分则是xxx_yyy替换为aaa_bbb,那么重复输入不同的替换词,一遍遍的点击replace将是接下来至少半小时的噩梦。

如果你在命令历史记录找到了合适的命令,不妨直接改一改用于这一次替换,或者你刻意把这个命令写成可以复用的模式就不用改了。

好好利用历史记录将极大加快你的替换进度。

结语

当我们不得不Ctrl-v时,不妨用vim让我们懒一点

一点碎碎念

这种高度重合的代码,是不是应该重构,这是另一个话题。

· 4 min read

站在2020年中,看2019年,确实是平凡的一年。想比今年所见证的历史,去年所经历的一切似乎都不可避免的蒙上一层平淡的滤镜。

2019之始大概是大一的寒假。我应该是在疑惑,学长大一都做了些什么,为什么看起来这么厉害。在后来的一年里我才逐渐了解到,诸多我当时遇到的学长原来是其中的佼佼者。 但仅就当时而言,想要像那些学长一样,我选择了一个方向:微信小程序。

大概一个“小”字,让初学者比较放心。

比较顺利的是,我找到了一个小组能让我边做边学。虽然以现在的视角来看,我们用非常稚嫩的方式刻画用户需求,边学习工具边练习使用,并且进度管理约等于没有。但是那确实是我不可多得的一次,完全以一个两眼一抹黑的状态,闯入软件工程大坑的经历。倘若真的有什么学到的东西,我觉得是隐约感受到这个专业的“什么都自学”的氛围(这也在后来无数课里被我验证了)

最有意思的是通过该项目负责人——一个颇为泼辣的妹子——我认识了陶姐,用一种我这种内向的人无法理解的方式(闯入人家的火锅局谈笑风生)。后来我受陶之邀参与了大创,另一个令人比较蛋疼的故事。

在国庆之前的那个夏天,那个想起来我就头秃的小学期。我们三人做了一个RPG横版过关游戏的demo。论肝之程度确实比之后来三人开房写代码至3点还差了些,但这就是所谓“第一次”。

那份代码,后来三人统计3k行的C++代码,现在我确实不敢看了。奇迹的是三人在QQ代码管理和手动代码Merge的情况下,仍按时完成了2周的大作业。 因为10月的大事情,8月我就回到学校了。在9月后的没有周末的日子里,我无数次的期盼赶紧国庆,不只是因为这是一个盛会,更因为半夜12点去拉到王府井席地睡一会,排练完5点回来,实在是顶不住。

那会儿我确实充实又快乐,初来乍到本部,有很多之前只能见几次的小伙伴,结果是我在学院路乐不思蜀。 吸奶茶+学院路大party 中间是我

写着写着就变成流水账,确实非我本意。以此一篇练习,作为博客开篇吧。 另:写成流水账正好呼应开头2019无大事好像也没问题

· One min read
Gao Wei

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet