├── .gitignore ├── docs ├── .vitepress │ └── config.js ├── Mac App │ ├── day-45.md │ ├── day-46.md │ ├── day-47.md │ ├── day-48.md │ ├── day-49.md │ ├── day-50.md │ ├── day-51.md │ ├── day-52.md │ ├── day-53.md │ ├── day-54.md │ ├── day-55.md │ ├── day-56.md │ └── day-57.md ├── chrome │ ├── day-31.md │ ├── day-32.md │ ├── day-33.md │ ├── day-34.md │ ├── day-35.md │ ├── day-36.md │ └── day-37.md ├── for-mac.md ├── for-window.md ├── index.md ├── keybinding.md ├── public │ ├── favicon.ico │ ├── images │ │ ├── day-38-1.png │ │ ├── day-38-2.png │ │ ├── day-39-1.png │ │ ├── day-48-1.png │ │ ├── day-48-2.png │ │ ├── day-48-3.png │ │ ├── day-48-4.png │ │ ├── day-49-1.png │ │ ├── day-49-2.png │ │ ├── day-49-3.png │ │ ├── day-50-1.png │ │ └── day-50-2.png │ └── logo.png ├── terminal │ ├── day-38.md │ ├── day-39.md │ ├── day-40.md │ ├── day-41.md │ ├── day-42.md │ ├── day-43.md │ └── day-44.md ├── vim │ ├── day-1.md │ ├── day-10.md │ ├── day-11.md │ ├── day-12.md │ ├── day-13.md │ ├── day-14.md │ ├── day-15.md │ ├── day-16.md │ ├── day-17.md │ ├── day-18.md │ ├── day-2.md │ ├── day-3.md │ ├── day-4.md │ ├── day-5.md │ ├── day-6.md │ ├── day-7.md │ ├── day-8.md │ └── day-9.md └── vscode │ ├── day-19.md │ ├── day-20.md │ ├── day-21.md │ ├── day-22.md │ ├── day-23.md │ ├── day-24.md │ ├── day-25.md │ ├── day-26.md │ ├── day-27.md │ ├── day-28.md │ ├── day-29.md │ └── day-30.md ├── package.json ├── pnpm-lock.yaml └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | docs/.vitepress/dist 3 | .env 4 | .DS_Store 5 | **/.DS_Store 6 | .DS_Store? 7 | *.DS_Store 8 | docs/.pnpm-debug.log -------------------------------------------------------------------------------- /docs/.vitepress/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | title: "Just Vim It", 3 | description: "A simple vim tutorial for who haven't learn \ use \ know about vim", 4 | lang: "zh-CN", 5 | lastUpdated: true, 6 | // add the favicon file in public folder (public folder shoul not in vitepress but root ) and add the head prarm asll below 7 | head: [ 8 | ['link', { 9 | rel: 'icon', 10 | type: 'image/x-icon', 11 | href: '/favicon.ico' 12 | }], 13 | ], 14 | themeConfig: { 15 | siteTitle: "Just Vim It", 16 | logo: '/logo.png', 17 | nav: [{ 18 | text: 'About Nauxscript', 19 | link: 'https://github.com/Nauxscript/' 20 | }, ], 21 | socialLinks: [{ 22 | icon: 'github', 23 | link: 'https://github.com/Nauxscript/Just-Vim-It' 24 | }, ], 25 | sidebar: [{ 26 | text: "介绍", 27 | items: [{ 28 | text: "写在前面", 29 | link: "/index.md" 30 | }, 31 | { 32 | text: "Mac 环境准备", 33 | link: "/for-mac.md" 34 | }, 35 | { 36 | text: "Window 环境准备", 37 | link: "/for-window.md" 38 | }, 39 | { 40 | text: "改键建议及设置参考", 41 | link: "/keybinding.md" 42 | }, 43 | ] 44 | }, 45 | { 46 | text: 'Vim', 47 | items: [{ 48 | text: 'Day 1:起步', 49 | link: '/vim/day-1.md' 50 | }, 51 | { 52 | text: 'Day 2:行相关命令', 53 | link: '/vim/day-2.md' 54 | }, 55 | { 56 | text: 'Day 3:认识 vim 语法', 57 | link: '/vim/day-3.md' 58 | }, 59 | { 60 | text: 'Day 4:删改重做命令提升效率', 61 | link: '/vim/day-4.md' 62 | }, 63 | { 64 | text: 'Day 5:认识可视化模式', 65 | link: '/vim/day-5.md' 66 | }, 67 | { 68 | text: 'Day 6:什么是文本对象?', 69 | link: '/vim/day-6.md' 70 | }, 71 | { 72 | text: 'Day 7:让移动再次快起来!', 73 | link: '/vim/day-7.md' 74 | }, 75 | { 76 | text: 'Day 8:掌握搜索命令', 77 | link: '/vim/day-8.md' 78 | }, 79 | { 80 | text: 'Day 9:vim-easymotion', 81 | link: '/vim/day-9.md' 82 | }, 83 | { 84 | text: 'Day 10:数字与 `.` 的威力', 85 | link: '/vim/day-10.md' 86 | }, 87 | { 88 | text: 'Day 11:多文件跳转的奥妙', 89 | link: '/vim/day-11.md' 90 | }, 91 | { 92 | text: 'Day 12:vim-surround', 93 | link: '/vim/day-12.md' 94 | }, 95 | { 96 | text: 'Day 13:替换字符和多文本选中', 97 | link: '/vim/day-13.md' 98 | }, 99 | { 100 | text: 'Day 14:大小写、注释与提示', 101 | link: '/vim/day-14.md' 102 | }, 103 | { 104 | text: 'Day 15:窗口管理大法', 105 | link: '/vim/day-15.md' 106 | }, 107 | { 108 | text: 'Day 16:快速删除一个函数', 109 | link: '/vim/day-16.md' 110 | }, 111 | { 112 | text: 'Day 17:vim 的宏操作', 113 | link: '/vim/day-17.md' 114 | }, 115 | { 116 | text: 'Day 18:调用 vscode 命令', 117 | link: '/vim/day-18.md' 118 | }, 119 | ] 120 | }, 121 | { 122 | text: "VScode", 123 | items: [{ 124 | text: "Day 19:文件与窗口基础操作", 125 | link: '/vscode/day-19.md' 126 | }, 127 | { 128 | text: "Day 20:常用窗口操作", 129 | link: '/vscode/day-20.md' 130 | }, 131 | { 132 | text: "Day 21:全局搜索命令", 133 | link: '/vscode/day-21.md' 134 | }, 135 | { 136 | text: "Day 22:开发常用小技巧", 137 | link: '/vscode/day-22.md' 138 | }, 139 | { 140 | text: "Day 23:挖掘快捷键场景", 141 | link: '/vscode/day-23.md' 142 | }, 143 | { 144 | text: "Day 24:Git 常用操作", 145 | link: '/vscode/day-24.md' 146 | }, 147 | { 148 | text: "Day 25:Snippet 代码片段", 149 | link: '/vscode/day-25.md' 150 | }, 151 | { 152 | text: "Day 26:代码重构工具", 153 | link: '/vscode/day-26.md' 154 | }, 155 | { 156 | text: "Day 27:VSpaceCode 插件", 157 | link: '/vscode/day-27.md' 158 | }, 159 | { 160 | text: "Day 28:Git 神器 lazygit", 161 | link: '/vscode/day-28.md' 162 | }, 163 | { 164 | text: "Day 29:终端的基本操作", 165 | link: '/vscode/day-29.md' 166 | }, 167 | { 168 | text: "Day 30:Debug the Bug", 169 | link: '/vscode/day-30.md' 170 | }, 171 | ] 172 | }, 173 | { 174 | text: "Chrome", 175 | items: [{ 176 | text: "Day 31:浏览器中的 Vim", 177 | link: '/chrome/day-31.md' 178 | }, 179 | { 180 | text: "Day 32:Vimium-c 页面操作", 181 | link: '/chrome/day-32.md' 182 | }, 183 | { 184 | text: "Day 33:Vimium-c 搜索与查找", 185 | link: '/chrome/day-33.md' 186 | }, 187 | { 188 | text: "Day 34:Vimium-c 标签页操作", 189 | link: '/chrome/day-34.md' 190 | }, 191 | { 192 | text: "Day 35:Vimium-c 再拓展", 193 | link: '/chrome/day-35.md' 194 | }, 195 | { 196 | text: "Day 36:Chrome 开发者工具", 197 | link: '/chrome/day-36.md' 198 | }, 199 | { 200 | text: "Day 37:Chrome 的 Debug", 201 | link: '/chrome/day-37.md' 202 | } 203 | ] 204 | }, 205 | { 206 | text: "Terminal", 207 | items: [{ 208 | text: "Day 38:初识命令行界面操作", 209 | link: '/terminal/day-38.md' 210 | }, 211 | { 212 | text: "Day 39:什么是 zellij", 213 | link: '/terminal/day-39.md' 214 | }, 215 | { 216 | text: "Day 40:zellij 的高级使用", 217 | link: '/terminal/day-40.md' 218 | }, 219 | { 220 | text: "Day 41:认识 zsh-vi-mode", 221 | link: '/terminal/day-41.md' 222 | }, 223 | { 224 | text: "Day 42:进阶 zsh-vi-mode", 225 | link: '/terminal/day-42.md' 226 | }, 227 | { 228 | text: "Day 43:zsh 常用插件", 229 | link: '/terminal/day-43.md' 230 | }, 231 | { 232 | text: "Day 44:zsh 自定义快捷键", 233 | link: '/terminal/day-44.md' 234 | } 235 | ] 236 | }, 237 | { 238 | text: "Mac App", 239 | items: [{ 240 | text: "Day 45:Manico", 241 | link: "/Mac App/day-45.md" 242 | }, 243 | { 244 | text: "Day 46:Moom", 245 | link: "/Mac App/day-46.md" 246 | }, 247 | { 248 | text: "Day 47:Alfred 搜索初体验", 249 | link: "/Mac App/day-47.md" 250 | }, 251 | { 252 | text: "Day 48:Alfred Clipboard", 253 | link: "/Mac App/day-48.md" 254 | }, 255 | { 256 | text: "Day 49:Alfred Snippets", 257 | link: "/Mac App/day-49.md" 258 | }, 259 | { 260 | text: "Day 50:Alfred 的 Workflow", 261 | link: "/Mac App/day-50.md" 262 | }, 263 | { 264 | text: "Day 51:MacOS 系统快捷键", 265 | link: "/Mac App/day-51.md" 266 | }, 267 | { 268 | text: "Day 52:Finder 快捷键", 269 | link: "/Mac App/day-52.md" 270 | }, 271 | { 272 | text: "Day 53:文本编辑快捷键", 273 | link: "/Mac App/day-53.md" 274 | }, 275 | { 276 | text: "Day 54:Obsidian 中的 vim", 277 | link: "/Mac App/day-54.md" 278 | }, 279 | { 280 | text: "Day 55:Obsidian 常用文件操作", 281 | link: "/Mac App/day-55.md" 282 | }, 283 | { 284 | text: "Day 56:Obsidian 编辑常用命令", 285 | link: "/Mac App/day-56.md" 286 | }, 287 | ] 288 | } 289 | ], 290 | algolia: { 291 | appId: 'RVMP1DL10N', 292 | apiKey: 'b6698444fb6414c2328728cdbc9eb681', 293 | indexName: 'just-vim-it', 294 | debug: false 295 | }, 296 | laslltUpdatedText: "最后更新", 297 | footer: { 298 | message: 'Released under the MIT License.', 299 | copyright: 'Copyright © 2022-present Nauxscript' 300 | } 301 | }, 302 | } -------------------------------------------------------------------------------- /docs/Mac App/day-45.md: -------------------------------------------------------------------------------- 1 | # Manico -------------------------------------------------------------------------------- /docs/Mac App/day-46.md: -------------------------------------------------------------------------------- 1 | # Moom 2 | -------------------------------------------------------------------------------- /docs/Mac App/day-47.md: -------------------------------------------------------------------------------- 1 | # 远近闻名:Alfred 搜索初体验 2 | 3 | 相信刚开始使用 MacOS 时,你一定去搜索过类似 “Mac 必备软件” 的问题,然后查看各种作者分享的什么 “十大必备 Mac 软件”、“Mac 效率神器” 等等的文章,各种软件纷至沓来,眼花缭乱;不过大概率他们都会提到一个软件,就是我们今天的主角 ———— Alfred;十篇文章里面有九篇都会提到它,还有一篇没有大概率是因为作者是小白或者作者没有坚持使用下来。可以说 Alfred 是一个超全能神器,你甚至百分之九十以上的电脑操作都可以在上面完成,只要你掌握了它,那我们就来了解一下它的一些基础使用和功能。 -------------------------------------------------------------------------------- /docs/Mac App/day-48.md: -------------------------------------------------------------------------------- 1 | # Alfred 的 Clipboard 2 | 3 | ## clipboard 的功能 4 | 5 | Clipboard,顾名思义即为剪贴板;对于常常在~~屎山~~代码中徜徉的我们来说,把一坨或多坨~~屎~~代码从这移到那的情况时有发生(虽然移完依然改变不了它的本质),而通过 Alfred 的 Clipboard,我们可以查看我们一段时间内复制过的内容,并把它重新粘贴出来,这样我们就可以非常方便地完成~~代码搬运~~写代码的任务。 6 | 7 | ## 命令配置 8 | 9 | 在 Alfred 的偏好设置页面中的 Clipboard History 中,我们可以看到默认功能是关闭的,要打开我们需要把 `Keep Plain Text`、`Keep Images`、`Keep Files List` 打开(或者只打开你需要的功能,比如你只想在复制文本的时候存入 Alfred 的剪切板,则只打开第一个),同时也可以设置剪切板记录的自动清除时间。这里笔者使用的是默认配置: 10 | 11 | 12 | 同时,我们可以配置 Clipboard 的查看命令和清除命令: 13 | 14 | - `cb`:查看剪切板记录 15 | - `clear`:清除剪切板记录 16 | 17 | 这时我们激活 Alfred 后使用 `cb` 会出现 “show the clipboard / snippets viewer”,再按下回车即可查看当前的剪切板记录。 18 | 19 | 当然,我们也可以配置快捷键,不过它有可能和我们其他的软件冲突,这里不推荐大家配置这个快捷键。 20 | 21 | 如下图前四个部分配置: 22 | 23 | ![image-1](./../public/images/day-48-1.png) 24 | 25 | ## 剪切板操作 26 | 27 | - 增:通过系统的复制组合键 `command` + `c` 即可向 Alfred 的 Clipboard 添加一条记录; 28 | - 删:通过上面提到的配置命令 `clear` 即可清空,可以选择清空五分钟内、十五分钟内或全部记录;也可以在上图的配置页面中的 “Clear All History Now” 清空所有; 29 | - 改: 30 | - 查:通过上面提到的自己配置的命令如 `cb` 或自定义的快捷键查看; 31 | 32 | ## 其他配置 33 | 34 | ![image-2](./../public/images/day-48-3.png) 35 | ![image-3](./../public/images/day-48-4.png) 36 | 37 | 1. 显示 snippets:如无需求,建议关闭,感觉挺影响操作的; 38 | 2. 存储其他设备复制的内容:如无需求,建议关闭,不然我们在手机、平板上面复制的内容也会保存在 Clipboard 中; 39 | 3. 直接粘贴到当前聚焦位置:如无需求,建议关闭; 40 | 4. 设置剪切板单条记录大小限制:如无需求,建议默认设置即可; 41 | 5. 忽略剪切板操作的应用(即不存储该应用上复制的内容):如果一些应用上的内容涉及敏感信息,建议添加到这里; 42 | 43 | 还有其他的一些细节配置如 “Move items to top of clipboard history when used” 这些大家可以自己根据自己的需求摸索配置,这里就不展开说了。 44 | 45 | 总而言之,对于 Clipboard 功能有利于我们去管理剪切板的内容,使得我们的 复制 / 粘贴 不再是一个单项操作,而是一个模块式的功能,可以增删改查,可以配置个性化设置等,这也是 Alfred 的特色功能之一。 -------------------------------------------------------------------------------- /docs/Mac App/day-49.md: -------------------------------------------------------------------------------- 1 | # Alfred 的 Snippets 2 | 3 | 在前面的训练中,我们学习了 VScode 的 Snippets;而 Alfred 的 Snippets 也是一样的效果:通过键入简短的命令而快速生成一段预设的文本内容;比如笔者写博客的时候常常需要输入固定的时间格式的当前时间文本片段,就可以通过 Snippets 达到快速输入当前时间的效果(当然 Snippets 的功能远不止如此,这里是举个简单例子)。 4 | 5 | ## 基础配置 6 | 7 | 打开 Alfred 的设置页面的 Snippets 栏,我们可以先配置 Snippets 的快捷键(笔者设置的为 `ctrl` + `option` + `s`,配置后再任何时候按下快捷键即可调出 Alfred 并进入 Snippets 搜索状态,可以快速搜索已添加的 Snippet 记录)以及 Snippets 的搜索前缀(笔者设置为 `sp`,激活 Alfred 键入该前缀也可以快速搜索已添加的 Snippets 记录)。 8 | 9 | 界面下方分为左右两块区域: 10 | 11 | 1. 集合列表,每个集合中可以添加多条 Snippet; 12 | 2. Snippet 列表,即已添加的记录列表; 13 | 14 | ![image-1](./../public/images/day-49-1.png) 15 | 16 | ## 创建 17 | 18 | 在集合列表和 Snippet 列表的右下角都有一个加号,点击即可添加对应的合集或在对应合集中添加一条新的 Snippet 记录; 19 | 已前面提到的固定的时间格式的当前时间文本片段,先创建一个集合 tool: 20 | 21 | ![image-2](./../public/images/day-49-2.png) 22 | 23 | 其中: 24 | 25 | - Name:即为该集合的名称,在查找的时候可用作关键词; 26 | - Affix:前缀,后续的查找的时候可用作关键词; 27 | - suffix:后缀,用于集合自动展开 28 | 29 | 点击右下的 save 即可创建一个新的集合;创建后选中新建的集合,点击右边的 Snippet 记录右下方的加号,添加一条新记录: 30 | 31 | ![image-3](./../public/images/day-49-3.png) 32 | 33 | - Name:名称,在查找的时候可用作关键词; 34 | - Keyword:关键字,后续的查找的时候可用作关键词; 35 | - Type:类型,又分为: 36 | + Plain Text Snippet(纯文本片段) - Match destination formatting on paste (匹配粘贴时的目标格式); 37 | + Rich Text Snippet(富文本片段) - Retain formatting on paste where possible (尽可能保留粘贴时的格式); 38 | - Snippet:文本片段内容; 39 | 40 | ## 使用 41 | 42 | 我们添加了 Snippet 后可以: 43 | 44 | - 通过图一设置的 viewer hotkey 的组合键激活 Snippet 搜索,再键入已添加的集合或 Snippet 名称或关键字搜索,如笔者的 `ctrl` + `option` + `s` 激活搜索,再键入 `tool` 然后选择 Snippet, 或键入 `date` 或 `nndate` 直接搜索对应 Snippet,选中后通过 `command` + `v` 即可粘贴该 Snippet 内容到对应位置; 45 | - 激活 Alfred 后键入自己设置的图一中的 Snippet keyword 加空格加已添加的 Snippet 名称或关键字搜索,如笔者的 `sp` + ` date` 或 + ` nndate`,选中后通过 `command` + `v` 即可粘贴该 Snippet 内容到对应位置; 46 | 47 | :::tip 自动填充到光标所在位置 48 | 由于在[昨天的训练](./day-48.md#其他配置)中把 Clipboard 的 `Auto-paste on return` 设置关闭了,所以在上面提到的使用方法的第二、三点中选中 Snippet 后需要通过粘贴把对应文本输出,如果开启了 `Auto-paste on return` 则选中了 Snippet 后就会自动填充到光标所在位置,不过我们使用的时候更多是通过使用方法中的第一种方式,所以这个设置保持关闭就好,以免影响 Clipboard 的使用。 49 | ::: 50 | 51 | ## placeholder 52 | 53 | 在本文第三张图中,可以看到右下方有个 `{}`,点击它即可查看 Snippet 中可以使用的一些占位符,比如笔者的 “date” 中使用的 `{datetime}` 即为时间占位符,可以输出当前时间;其他的占位符大家可以自行了解,这里只讲有点特殊的两个: 54 | 55 | - Clipboard and History:通过该占位符可以插入 Alfred 剪切板中的记录,如 `{clipboard}` 会把剪切板的最新一条的记录内容插入到当前 Snippet 中;也可以通过添加数字指定要插入的对应顺序的剪切板记录,如 `{clipboard:1}` 则为插入第二条(从 0 开始); 56 | - Cursor:光标位置,和 [VScode Snippet](../vscode/day-25.md#配置自己的-snippet) 的光标位置设置,通过这个占位符可以定义输出 Snippet 文本片段后光标的位置,不过也是要打开 Clipboard 的 `Auto-paste on return` 设置。 57 | 58 | ## 自动展开 59 | 60 | 在本文的第一张图可以看到,此时右边的 Snippet “date” 的 keyword 显示的是 `nndate`,而在第三张图中,我设置的 keyword 明明是 `date`;关键就在于第二张图中我给 tool 集合设置的前缀 `nn`,该前缀会和单条 Snippet 中设置的 keyword 值合并为一个; 61 | 62 | 这是因为在我们打开了图一中的 `Automatically expand snippets by keyword` 选项,这就是自动展开。 63 | 64 | 开启这个设置后,我们在任何地方键入已添加的 Snippet 的关键字时,会替换成对应的文本片段,比如我的 Snippet “date” 的关键字是 `date`,那我在输入 date 是则会变成 `YYYY-MM-DD HH:mm:SS` 格式的当前时间文本值;但问题是我们在日常使用中 “date” 这个单词也是很常用的,所以为了区分开触发 Snippet 的情况与正常使用的情况,我们为集合加上了一个前缀,这样其内部的 Snippet 触发时的规则就比较特异而又有规律了,比如我的 Snippet “date” 则会在我键入 `nndate` 时触发。 65 | 66 | 可以看出,指令(即类似上面的 `nndate`)的组成是:**分组前缀 Affix + Snippet 记录的 Keyword + 分组 Keyword**; 67 | 68 | 说到这里,关于自动展开的几个要点就很明了了,即**指令不要有歧义**,比如如果笔者的 `date` 指令没有设置所在集合的前缀,则在正常输入 date 时却变成了时间文本片段,这就导致了问题;而且即使如笔者那样设置了前缀,也不是万无一失,所以官方给出了这几点建议: 69 | 70 | - Snippet 要以非字母数字开头;可以用 `!` / `:` / `^` 等符号开头; 71 | - 在 Keyword 中不要使用正常词汇,以防止错误的展开,如上面的 `date`; 72 | - 使用不常用的大写形式,比如末尾大小的方式,如 `datE` 73 | - 使用双重字母,如 `ddate`; 74 | 75 | 以上几点其实就是为了防止我们在正常输入中意外地展开;而尽可能地使指令特异化。 76 | 77 | ## 分享 78 | 79 | Alfred 也提供了 Snippets 的导出,我们可以通过导出功能与朋友或社区分享自己的 Snippets 配置,正所谓众人拾柴火焰高,要从社区中来,到社区中去。操作也很简单,在集合列表中选中某条记录点击右键,选择 `export` 即可导出为 Alfred 专用的 Snippet 文件;导入也很简单,双击别人导出的 Snippet 文件,即可自动导入。 -------------------------------------------------------------------------------- /docs/Mac App/day-50.md: -------------------------------------------------------------------------------- 1 | # Alfred 的 Workflow 2 | 3 | Workflow 即工作流,wiki 百科解释: 4 | 5 | > 工作流(Workflow),是对工作流程及其各操作步骤之间业务规则的抽象、概括描述。 工作流建模,即将工作流程中的工作如何前后组织在一起的逻辑和规则,在计算机中以恰当的模型表達并对其实施计算。 工作流要解决的主要问题是:为实现某个业务目标,利用计算机在多个参与者之间按某种预定规则自动传递文档、信息或者任务。 6 | 7 | 笔者理解工作流即为对业务流程的抽象化,使业务过程的逻辑形成一定的节点之间连接而成的 “流”,通过层层链接而把业务描述成一定格式。 8 | 9 | 对于 Alfred 的 Workflow,我们也可以简单地理解其为某些通过脚本文件描述成流程的拓展功能,这些脚本可以用 `Shell`、`JavaScript`、`Ruby` 等等语言来写;当然,这节训练我们并不会教大家如何写一个 Workflow(三言两语也说不完),这里主要教大家如何导入别人的 Workflow 以及推荐一些好用的 Workflow。 10 | 11 | ## 导入与使用 12 | 13 | 拿 [`gharlan/alfred-github-workflow`](https://github.com/gharlan/alfred-github-workflow) 来举例,我们进入它的仓库,直接点击 Download 下载,可以发现下载了一个以 `.alfredworkflow` 结尾的文件,双击运行,即会弹出下图弹框: 14 | 15 | ![image-1](../public/images/day-50-1.png) 16 | 17 | 其中左上区域是这个 Workflow 的一些信息,右边的区域是为它的脚本内容,可以看到它的脚本是用 PHP 写的。点击 `Import` 即可导入。 18 | 19 | 使用也很简单,比如该 Workflow 是提供了一个前缀 `gh`,激活 Alfred 后键入 `gh` + [空格] + [关键字],即可在 github 搜索对应的内容,并且搜索结果会直接显示在 Alfred 预选列表(第一次使用需要 github 账号授权);键入 `gh` + [空格] 则会显示自己账号的仓库内容。比如: 20 | 21 | ![image-2](../public/images/day-50-2.png) 22 | 23 | 详细用法查看下载的 Workflow 的文档即可,不同的 Workflow 有不同的用法,不过一般大同小异。 24 | 25 | ## Workflow 推荐 26 | 27 | - 有道翻译:https://github.com/whyliam/whyliam.workflows.youdao 28 | - https://github.com/vitorgalvao/alfred-workflows#newpath- 29 | - https://github.com/alexchantastic/alfred-open-with-vscode-workflow 30 | - https://github.com/zenorocha/alfred-workflows#ip-address-v120--download 31 | - https://github.com/jsumners/alfred-emoji -------------------------------------------------------------------------------- /docs/Mac App/day-51.md: -------------------------------------------------------------------------------- 1 | # 回归本源:MacOS 系统快捷键 2 | 3 | 经过前面五十天的训练,相信大家已经对 “使用键盘操作电脑” 这件事有一个自己的习惯积累和认识了,各种软件、插件、快捷键,无一不是为了让我们更加方便快捷地使用键盘来达到想要的操作;今天的训练我们回归本源,了解一下 MacOS 系统级的组合快捷键,其中相对一步份我们都已经在前面的训练中了解学习过了的,顺便回顾一下。 4 | 5 | ## 常用命令 6 | 7 | - `command` + `,`:打开设置页,绝大部分软件通用 8 | - `command` + `q`:退出软件 9 | - `command` + `ctrl` + `q`:锁屏 10 | - `command` + `tap` / `command` + `shift` + `tap`:触发一次则快速切换到上一个使用的软件窗口,多次触发则会显示当前打开了的软件列表并向右切换,而 `command` + `shift` + `tap` 则是向左切换 11 | - `command` + `h`:隐藏软件窗,隐藏后可以通过 `command` + `tap` 切换到该软件而让它显示出来; 12 | - `command` + `m`:隐藏软件窗到底部 Dock 栏,隐藏后无法通过 `command` + `tap` 切换到该软件而让它显示出来;可以通过 `command` + `tap` 切换到该软件,松开 tab 但不松开 command,然后按下 option 键,即可让改软件重新从 Dock 调出来; 13 | - `command` + `` ` ``:切换同一个软件中的多个窗口,如 VScode 打开多个工作区窗口时即可用它切换; 14 | 15 | :::tip HHKB 键盘改键方案 16 | 对于一些使用 HHKB 的朋友来说,由于键盘中的 `esc` 是在 `` ` `` 键的位置,而无法直接输入 `` ` ``,所以我们可以通过 Karabiner 配置 `command` + `esc` 映射为 `command` + `` ` ``,具体的规则参考之前的 [Karabiner 的映射规则导入](./../keybinding.md#全局)。 17 | ::: 18 | 19 | - `command` + `f`:全屏; 20 | - `command` + [左 / 右方向键]:切换桌面; -------------------------------------------------------------------------------- /docs/Mac App/day-52.md: -------------------------------------------------------------------------------- 1 | # 分门别类:Finder 快捷键 2 | 3 | 虽说对于程序员在日常的 MacOS 使用中,一般是使用命令行工具浏览文件和进行文件操作,不过对于大部分人来说,GUI 界面还是更加舒服适用,但是在使用 GUI 界面时,又不想手离开键盘使用鼠标来点点点,那就要了解一下 Finder 的一些快捷键了 4 | 5 | ## 常用命令 6 | 7 | - `↓↑←→`:选择文件 8 | - `command` + `↓` / `command` + `o`:进入文件夹或打开文件; 9 | - `command` + `↑`:返回上一层; 10 | - `command` + `[`:后退; 11 | - `command` + `]`:前进; 12 | - `command` + `d`:复制选中的文件; 13 | - `command` + `i`:显示选中的文件简介; 14 | - `shift` + `command` + `n`:新建文件夹; 15 | - `command` + `delete`:删除文件; 16 | - `command` + `n`:新建 Finder 窗口; 17 | - 按住 `option` 同时移动文件到另一文件夹会拷贝该文件夹; 18 | 19 | 其实如上一节课一般,这些快捷键在我们练习 VScode、Chrome 等软件的时候其实以及使用过了,因为对于大部分软件来说,其快捷键的设计和定义都会跟系统的设计保持一致,所以一样的逻辑,我们掌握了之后,在其他的软件使用,往往功能也大差不差甚至如出一辙。 -------------------------------------------------------------------------------- /docs/Mac App/day-53.md: -------------------------------------------------------------------------------- 1 | # 聊胜于无:文本编辑快捷键 2 | 3 | ## 常用命令 4 | 5 | - `command` + `←`:移动光标到行首 6 | - `command` + `←`:移动光标到行尾 7 | - `ctrl` + `a`:移动光标到行首 8 | - `ctrl` + `e`:移动光标到行尾 9 | - `option` + `←`:向左移动一个单词 10 | - `option` + `→`:向右移动一个单词 11 | - `option` + `delete`:向左删除到单词首 12 | - `ctrl` + `d`:基于光标向右删除 13 | - `shift` + `command` + `←`:选中到行首 14 | - `shift` + command + `→`:选中到行尾 15 | - `shift` + `←`:向左选中 16 | - `shift` + `→`:向右选中 17 | - `shift` + `option` + `←`:向左选中到单词首 18 | - `shift` + `option` + `→`:向左选中到单词尾 19 | - `ctrl` + `p`:移动到上一行 20 | - `ctrl` + `n`:移动到下一行 21 | - `ctrl` + `b`:光标左移动 22 | - `ctrl` + `f`:光标右移动 -------------------------------------------------------------------------------- /docs/Mac App/day-54.md: -------------------------------------------------------------------------------- 1 | # Obsidian 中的 vim 2 | 3 | ## 开启 vim 模式 4 | 5 | 在设置中找到 `Editor (编辑器)` `Vim key bindings (Vim 键绑定)`,打开开关,此时会提示要求键入在命令行中退出 Vim 的命令,这是为了防止不会使用 Vim 的人误开开关,键入对应命令即可打开 Vim 模式(如果你不知道是什么,那不需要往下看了,回去前面的 Vim 章节复习去吧)。 6 | 7 | 开启之后,我们还有安装一个 Obsidian 的 Vim 插件 `Vimrc Support`,以提供我们通过文件配置键位映射等设置的方式;Obsidian 要安装插件需要关闭设置中的 `hird-party plugin (第三方插件)` 中的 `safe mode(安全模式)`;关闭后在该设置下方的 `Community plugins (社区插件市场)` 中即可安装 `Vimrc Support`; 安装后可以在设置页面的左侧边栏底部看到已安装的第三方插件,点击 `Vimrc Support`,可以看到 `Vimrc Support` 默认读取的配置文件为 `.obsidian.vimrc`,我们可以通过命令行在当前仓库中创建该文件,以供我们配置 Vim 的映射。 8 | 9 | ## vim 映射规则 10 | 11 | ## 使用系统剪切板 12 | 13 | ## 映射 obsidian 命令 14 | 15 | ## 使用 `Space` 定义命令 16 | 17 | ## 快捷键入 `[[]]` -------------------------------------------------------------------------------- /docs/Mac App/day-55.md: -------------------------------------------------------------------------------- 1 | # Obsidian 常用文件操作 2 | 3 | 既然要用键盘来操作一个软件,并且还是一个笔记类软件,文件操作肯定是少不了的,所以我们这章节训练先来了解一下 Obsidian 中关于文件常用操作。 4 | 5 | ## 常用命令 6 | 7 | - `command` + `n`: 创建新⽂件 8 | - `command` + `w`: 关闭⽂件 9 | - `shift` + `←` / `→:` 切换屏幕 10 | - `command` + `p`:打开⽂件 / 查看最近打开的⽂件 / 键入未存在的文件名可以直接创建文件,需要更改配置: 11 | + 在设置中的快捷键面板,搜索 `快速切换` 或 `switcher`,默认快捷键是 `command` + `o`,把它修改为 `command` + `p`,这样更改是为了和 VScode 的使用保持一致;但默认的 `command` + `p` 是打开命令面板,所以把打开命令面板改 `command` + `shift` + `p`,这样可以和 VScode 保持一致 12 | + 聚焦待续下拉框后使用 `command` + `enter` 可以在新的 tab 打开对应文件 13 | - `space` + `df`:删除文件 14 | - `command` + `\`:左右分屏,在设置中的快捷键面板,搜索 `左右拆分` 或 `split vertically` 15 | - `command` + shift + `\`:上下分屏,在设置中的快捷键面板,搜索 `上下拆分` 或 `split horizontally` 16 | - `command` + `shift` + `p`:搜索命令 17 | - `command` + `shift` + `t`:恢复关闭的⽂件 18 | 19 | 可以看出,一如上一节的 vim 映射,我们的快捷键、vim 等配置更多是尽可能和 VScode 保存一致,这样可以减少我们使用 Obsidian 的心智负担,并且让我们使用得更顺手,而这样配置后,使用起来就非常丝滑了。 -------------------------------------------------------------------------------- /docs/Mac App/day-56.md: -------------------------------------------------------------------------------- 1 | # Obsidian 编辑常用命令 2 | 3 | 在使用 Obsidian 的过程中,我们不免要输入一些常用的 markdown 语法,虽然语法简单,但相对也比较琐碎,而 Obsidian 提供了一下快捷键让我们可以快速地完成这些琐碎的输入过程。 4 | 5 | ## 常用命令 6 | 7 | - `command` + `e`:切换编辑 / 预览模式 8 | - `command` + b:加粗选中文本,即在选中文本前后插入 `**` 9 | - `command` + i:使选中文本变为斜体,即在选中文本前后插入 `*` 10 | - `command` + k:使选中文本变为链接语法,即 `[选中文本](链接)` 11 | - `command` + -:使所在行变为无序列表,即在所在行最前添加 `-`,需配置;在设置中的快捷键面板中搜索 `toggle bullet list(无序列表)`,把对应项设为该快捷键即可 12 | - `` ` ``:行内代码块,键入 `` ` `` 即可 13 | - `` ``` ``:多行代码块,键入 `` ``` `` 即可 14 | - `command` + `/`:注释选中代码 15 | - `command` + `enter`:添加 todo 元素,建议该功能置空,这样可以使用 command + enter 新建一行,和 VScode 或其他软件保持一致 16 | - `option` + `↑` / `↓`:上下移动行,需配置;搜索 `move line down(与下一行互换)` / `move line down(与上一行互换)` 与 VScode 保持一致 17 | - `f2`:更改当前文件名 18 | - 标签折叠:在 vim 中,默认的折叠代码操作为: 19 | 20 | + `zM`:折叠全部代码 21 | + `zR`:展开全部代码 22 | + `za`:展开 / 折叠当前行代码 23 | 24 | 为了保持一致的操作,我们可以通过 `.obsidian.vimrc` 添加映射配置: 25 | 26 | ```shell 27 | exmap foldAll obcommand editor:fold-all 28 | nmap zM :foldAll 29 | exmap unfoldAll obcommand editor:unfold-all 30 | nmap zR :unfoldAll 31 | exmap toggleFold obcommand editor:toggle- fold 32 | nmap za :toggleFold 33 | ``` 34 | 通过这样的配置,我们就可以使用 vim 折叠代码的命令折叠 Obsidian 中的各类标签了。 -------------------------------------------------------------------------------- /docs/Mac App/day-57.md: -------------------------------------------------------------------------------- 1 | # Obsidian 双链快捷键 2 | 3 | ## 常用命令 4 | 5 | ### 双链 6 | 7 | - 添加双链 8 | - 链接到页面的标题 9 | - 添加双链的别名 10 | - 预览 11 | 12 | ### 嵌入视频 13 | 14 | - 嵌入网络视频 15 | - 嵌入本地视频 16 | 17 | ### -------------------------------------------------------------------------------- /docs/chrome/day-31.md: -------------------------------------------------------------------------------- 1 | # 异曲同工:浏览器中的 Vim 2 | 3 | 通过前面 30 天两个部分的训练,相信能坚持下来的朋友基本对于 vim 的使用以及全键盘操作有了更深刻的理解;而对于一个日常在 gayhub 冲浪、面向谷歌、百度开发的 coder 来说,浏览器也是日常使用频率非常高的软件,如果你是一个前端开发,那就更不用说了。既然如此,那肯定要让 vim 把浏览器的场景也覆盖才可以。 4 | 5 | ## Vimium-c 6 | 7 | [Vimium-c](https://github.com/gdh1995/vimium-c) 是国人基于 [Vimium](https://github.com/philc/vimium) 做的一个谷歌浏览器 vim 插件,比原本有更多好用的功能,而且支持中文,对中文使用者更友好。 8 | 9 | ## 基本操作 10 | 11 | - `?`:唤出帮助面板;在帮助面板可以看到所有当前的快捷键及其功能(包括自己自定义的也会在这里显示); 12 | - `j` / `k` / `u` / `d`:向上滚动、向下滚动 和 上翻半页、下翻半页;基本和 vim 原生定义一致;当然为了让操作更统一我们也可以重新设置一下上下翻半页为 `ctrl` + `u` / `d`; 13 | - `J` / `K`:向 左 / 右 切换标签页; 14 | 15 | :::danger 16 | 对于 Chrome 自带的或官方的网页,如默认主页、谷歌应用商店、浏览器设置页或一些插件提供的如掘金主页等页面,是无法使用 Vimium-c 的,作者有提到一些解决方案,但笔者尝试过后都不甚完美,遂放弃了如 `J` `K` `o` (后面的训练会提到的功能) 的操作;切换标签页笔者直接用 `shift` + `tap` / `左shift` + `tab` + `右shift` 左右切换;`o` 的搜索用 `command` + `l` 聚焦地址栏功能来替换,但会带来无法从地址栏回到页面,下面会提供解决方案。 17 | ::: 18 | 19 | - `H` / `L`:前进 / 后退,非常常用; 20 | - `gg` / `G`:跳到顶部 / 跳到底部,与 vim 逻辑一致; 21 | - `f`:按下 `f` 后,页面所有课点击的位置都会有对应的标记,输入对应标记即可点击对应位置;类似 [vim-easymotion](./../vim/day-9.md#插件vim-easymotion) 22 | - `F`:和 `F` 类似,不过会以新标签页的形式打开页面; 23 | 24 | :::tip 双击扩展 25 | 在 Vimium-c 设置页面中的 [自定义快捷键] 中添加如下配置: 26 | 27 | ![配置](https://pic.imgdb.cn/item/62c8406df54cd3f9378be8d3.jpg) 28 | 29 | 这样我们在页面中触发 `ctrl` + `f` 激活标记后,输入对应标记即可双击对应位置。 30 | ::: 31 | 32 | :::tip 地址栏回到页面 33 | 利用的是一个浏览器自定义搜索引擎的 hack:在谷歌浏览器设置的 [搜索引擎] 栏中进入 [管理搜索引擎和网站搜索],在 [网站搜索] 中添加如下配置: 34 | 35 | ![设置](https://pic.imgdb.cn/item/62c83f6df54cd3f93789cf27.jpg) 36 | 37 | 这样我们在地址栏中只要键入 `u` 就会有 `back to page` 选择,选中即可聚焦到页面中。 38 | ::: 39 | 40 | :::warning hover 扩展 及 部分网站冲突 41 | 如 [Vimium-c 仓库 issue](https://github.com/gdh1995/vimium-c/issues/86) 中讨论,hover 的功能可以自行配置,但是 hover 效果是无法完美模拟出的。 42 | 如网页版的 VScode 与 YouTube 等自带一些扩展快捷键的网站会有不同情况的与 Vimium-c 冲突。 43 | ::: 44 | -------------------------------------------------------------------------------- /docs/chrome/day-32.md: -------------------------------------------------------------------------------- 1 | # 循序渐进:Vimium-c 页面操作 2 | 3 | 上一个训练中,我们了解了 Vimium-c 的基本使用,在网上冲浪时网页内的基本操作都可以用键盘完成了;今天来继续了解一些更好用更有用的功能,让我们的全键盘之旅更加丝滑。 4 | ## 页面操作 5 | 6 | 上一个训练我们学习内容主要是与页面的浏览有关,但对于大部分网页来说,用户的交互也是页面内容的一部分,如输入、复制粘贴等;这些 Vimium-c 当然也有它对应的键盘操作: 7 | 8 | - `gi`:聚焦当前页面的输入框,如果有多个输入框,则会聚焦第一个,切可以通过 `tab` 切换可聚焦的输入框; 9 | - `yy`:复制当前标签⻚地址; 10 | - `p`:在当前标签⻚的地址栏粘贴复制了的内容并跳转; 11 | - `P`:新建标签⻚并在地址栏粘贴复制了的内容并跳转; 12 | - `x`:关闭当前标签页; 13 | - `r`:刷新; 14 | - `V` / `yv`:进入文本选择模式; 15 | 16 | :::tip 如何抉择插件的操作和原生的操作 17 | 如 `x` / `r` 刷新、关闭以及上一个训练的 `J` / `K` 切换标签页,在 Vimium-c 中提供了对应的操作按键,但同时浏览器也自带了对应的操作组合键,那我们该如何去选择呢? 18 | 19 | 首先要分辨出他们有何异同优缺: 20 | 21 | - Vimium-c 的按键更简单易用,但在一些网页可能会失效(系统级的页面),而且加载页面的过程中是有可能会卡顿的而导致无法使用它的快捷键 22 | - Chrome 自带的快捷键一般为组合键,相对来说比较复杂一点;但它全局可用,也不存在失效的情况;而且逻辑一致,比如 `shift` + `tab` 在 Chrome 中是标签页切换,在 VScode 中也是,这其实可以减轻我们的学习成本和心智负担。 23 | 24 | 所以一些通用级别的操作笔者一般使用默认的,就如这里提到的四个操作,而一些特异操作则遵循插件的逻辑。 25 | ::: 26 | 27 | :::tip 键位映射 28 | 在 VScode 的 vim 中,我们习惯了 `H` / `L` 跳到行首行尾的操作,在 Vimium-c 中,为了使用方便以及不割裂,我们也可以配置一下映射;不过由于普通模式下的 `H` / `L` 是前进、后退的功能,所以我们可以映射 Vimium-c visual mode 模式下的键位;如下: 29 | 30 | ``` 31 | mapKey <$> 32 | mapKey <0> 33 | ``` 34 | 35 | ![映射](https://pic.imgdb.cn/item/62ca327ef54cd3f937b52780.jpg) 36 | ::: -------------------------------------------------------------------------------- /docs/chrome/day-33.md: -------------------------------------------------------------------------------- 1 | # 小同大异:Vimium-c 搜索与查找 2 | 3 | 今天是第 33 天训练,也是 Chrome 部分的第 3 天;前两天的训练了解了 Vimium-c 的基本操作,今天来说说它的搜索与查找功能。当然,今天会学到的命令中,使用的都是我们 vim 中学过的按键,它们小部分还是对应一样的功能,但有大部分的功能却相去甚远;所谓小同大异。 4 | 5 | ## 小同 6 | 7 | - `/`:搜索页面中的文本,和 vim 的操作保持一致; 8 | - `n` / `N`:配合 `/` 使用,跳到上一个 / 下一个结果; 9 | 10 | ## 大异 11 | 12 | - `o` / `O`:唤起多功能搜索框,小写 `o` 为在选中记录后在本页打开,`O` 为在新标签页打开;搜索框有以下功能: 13 | 14 | + 直接输入链接; 15 | + 模糊搜索网页浏览历史记录; 16 | + 直接调取 Vimium-c 配置的搜索引擎搜索:默认搜索引擎可以在 Vimium-c 设置页的 [默认搜索引擎] 设置,其设置格式可以参考该项下方的 [自定义搜索引擎] 中的链接格式; 17 | + 根据前缀匹配对应搜索:在 Vimium-c 设置页的 [自定义搜索引擎] 配置,格式可参考已有的配置;配置后即可使用简写前缀进行快速地在对应链接中查找;如默认已配的 github 搜索,使用 `gh` 即可快速打开github 并搜索输入的内容; 18 | 19 | 输入以上任一内容即可显示搜索的列表,`enter` 即可跳转; 20 | 21 | - `b` / `B`:显示搜索框,搜索收藏夹中的内容;大小写差异同上; 22 | - `ge` / `gE`:功能和 `o` / `O` 一致;但会自动填充当前的地址栏地址到搜索框中;如果当前地址是已配置的搜索引擎的地址,则会把当前搜索的内容填充在搜索框中;大小写差异同上; 23 | - `T`:搜索当前打开的标签页,选中记录可以切换标签页,用于标签页笔记多的时候; 24 | 25 | :::tip 使用建议 26 | 还是如昨天的训练所说的,要对比分辨相同或类似功能下 Chrome 已有的命令和插件提供的命令的差异; 27 | 比如 Chrome 的 `command` + `l` 聚焦搜索框后,其实即可达到上面提到的 `o` / `b` 等功能,而想要在新的页面打开我们可以通过 `command` + `enter` 来跳转(在原页面跳转是输入后键入 `enter`),甚至可以通过 `shift` + `enter` 在新的窗口打开搜索的内容;而对应的搜索引擎即为 Chrome 中配置的默认引擎,当然 Chrome 也可以扩展多个搜索引擎以及对应简写前缀(如前面训练提到的 `back to page`);甚至搜索标签页也能通过 `shift` + `command` + `a` 达到更好的效果(可以搜索到最近关闭的标签页);而对于日常也使用 Alfred 的人来说,`o` / `b` 的功能也能达到;所以可以根据自己的需求或者考虑心智负担的前提下去选择不同的使用习惯。 28 | ::: 29 | 30 | :::tip 扩展设置 31 | 使用 Vimium-c 下来有人可能发现,插件在部分如 `chrome-extension://` 开头的链接无法使用;这时候我们根据 Vimium-c 设置页中 [高级选项] 中的 [一些可选权限] 中对应所需的设置开启即可。 32 | ::: -------------------------------------------------------------------------------- /docs/chrome/day-34.md: -------------------------------------------------------------------------------- 1 | # 顺手拈来:Vimium-c 标签页操作 2 | 3 | 对于一个面向谷歌程序员,日常就是在写 Bug 与 查 Bug 直接反复横跳;为了查找一个报错原因,我们往往从百度查到必应,从必应查到谷歌,大大小小随随便便可能就几十个标签页;为了让我们可以在标签页中旋转跳跃,无论 Vimium-c 还是 Chrome 自身,都给我提供了不少的快捷键命令。 4 | 5 | ## 操作命令 6 | 7 | - `g` + `0`:切换到左起指定位置的标签页;比如要切换到左起第二个标签页,即可输入 `2g0`;直接输入 `g0` 则跳到左起第一个标签页;但这个组合键按起来比较麻烦,我们可以把其映射为 `g` + `H`; 8 | 9 | :::tip Vimium-c 键位映射 10 | 首先查到要映射的功能的指令;比如 `g` + `0`,我们可以在 Vimium-c 设置页面的唤起帮助页(输入 `?`;在普通页唤起的帮助页不会显示对应的指令)查到对应指令为 `firstTab`;然后在设置页的 [自定义快捷键] 栏中添加新一行为 `map gL firstTab`,即可完成映射。 11 | ::: 12 | 13 | - `g` + `$`:切换到右起指定位置的标签页,同上;也为了方便起见,我们可以映射为 `g` + `L`(映射方式同上); 14 | - `g` + [number]: 切换到对应 [number] 顺序的标签页; 15 | - `t`:打开新的标签页;可以在 Vimium-c 设置页中的 [] 设置打开新标签页时的链接;Chrome 的组合键 `command` + `t` 也是打开新标签页,不过不支持配置新标签页的默认打开链接,需要插件支持,比如 [New Tab Redirect](https://chrome.google.com/webstore/detail/new-tab-redirect/icpgjfneehieebagbmdbhnlpiopdcmna); 16 | - `yt`:在新标签页打开当前页面; 17 | - `x`:关闭当前标签页;Chrome 默认组合键为 `command` + `w`,也是 MacOS 中系统默认的关闭标签页的组合键,在大部分存在标签页形式的软件中都可以用; 18 | - `X`:重新打开上一个关闭的标签页;Chrome 默认组合键为 `command` + `shift` + `w`,也是 MacOS 系统级的打开上一组关闭标签页的组合键; 19 | - `W`:在新的窗口打开当前页面; 20 | - `^`:切换到最近查看过的标签页;即使用这个快捷键可以在两个标签页间快速切换;为了方便起见,可以映射为 `g` + `[`,映射方法参考第一条; 21 | - `<<`:向左移动标签页; 22 | - `>>`:向右移动标签页; 23 | - `option` + `p`:固定当前标签页;固定后则页面常驻标签栏中; 24 | 25 | :::tip Vimium-c 中 `option` + [字母] 组合键失效解决方案 26 | 在部分非英文布局键盘中,可能会出现该情况,根据 [vimium-c/issues/246](https://github.com/gdh1995/vimium-c/issues/246) 中插件作者描述,是因为部分 `option` + [字母] 组合键被 MacOS 映射为特殊字符了;出现失效的情况把 Vimium-c 的设置页中的 [一些功能开关] 中的 [忽略键盘布局] 选上,即可解决问题。 27 | ::: -------------------------------------------------------------------------------- /docs/chrome/day-35.md: -------------------------------------------------------------------------------- 1 | # 浅尝辄止:Vimium-c 再拓展 2 | 3 | 经过这几天的 Vimium-c 训练,相信你已经基本了解了怎么使用 Vimium-c 来完成在浏览器上的大部分操作,虽然你未必立刻熟练掌握它,但随着你不断地在网上冲浪时使用它,最终你会达成全键盘操作 Chrome 日常冲浪。前几天讲的大部分是一些常用功能,Vimium-c 当然还有许多你日常用不到的功能,我们今天来拓展了解一下,也许在某些特殊场景,我们会用得上他。 4 | 5 | ## 操作命令 6 | 7 | - `m` + [字母]:在当前页面创建一个新的标记,语法与 [vim mark](../vim/day-11.md#标记定位) 一致;但只在当前页面有效,如果页面路径变化,则会清除该标记;在我们阅读一下文档之类的时候可以一用; 8 | - `` ` `` + [字母]:跳转到对应标记,语法与 [vim mark](../vim/day-11.md#标记定位) 一致; 9 | - `g` + `u`:访问当前网址的上一层;如 `http://example.com/b/c` 的上一层则为 `http://example.com/b` 10 | - `g` + `U`:访问当前网址的首页; 11 | 12 | :::tip `gU` 失效问题 13 | 笔者在使用时出现了 `g` 和**左** `shift` + `u` 键入的 `gU` 无法跳转到首页的情况,但 `g` 和**右** `shift` + `u` 键入的 `gU` 却可以;此时把 Vimium-c 的设置页中的 [一些功能开关] 中的 [映射键盘右侧(或左侧)的修饰键] 取消选中即可正常使用。 14 | ::: 15 | 16 | - `i`:暂停识别 Vimium-c 的命令;`esc` 退出;在一些自带快捷键的网站或者快捷键和 Vimium-c 冲突的网站可以使用这个方式暂停使用 Vimium-c 比如 YouTube。 17 | - `option` + `f`:连续点击网页中的链接和按钮; 18 | - `f2`:从当前文本框移走焦点,其实 `esc` 也是一样效果;我推荐用 `esc`,而且推荐对 `esc` 进行一个系统级的映射,如[参考](../keybinding.md#全局)。 19 | -------------------------------------------------------------------------------- /docs/chrome/day-36.md: -------------------------------------------------------------------------------- 1 | # 一见如故:Chrome 开发者工具 2 | 3 | 开发者工具(Chrome devTool),AKA f12 杀手,AKA 你把报错信息截图给我看看,可以说是我们的老朋友了。日常开发打开它的时间是非常大量的,那就一定要了解一下它的一些常用操作的命令了。 4 | 5 | ## 常用操作 6 | 7 | - 打开 / 关闭 开发者工具; 8 | + `command` + `option` + `i`:打开开发者工具; 9 | + `command` + `option` + `j`:打开开发者工具并激活 `console` 栏; 10 | + `command` + `option` + `c` / `command` + `shift` + `c`:打开开发者工具并激活 `element` 栏且激活鼠标选中元素模式,即此时鼠标可以选中页面元素; 11 | - `ctrl` + `` ` ``:打开 `console` 面板;会在开发者工具面板底部打开该面板; 12 | - `command` + `k`:清空 `console` 面板输出; 13 | - `command` + `p`: 搜索该网站静态资源文件; 14 | - `command` + `shift` + `p`:搜索开发者工具中的可用命令; 15 | - `command` + `[` / `]`:切换开发者工具中的标签栏; 16 | - `esc`:在 `source panel` 中 显示 / 隐藏 底部面板; 17 | 18 | ## 采用 VSCode 快捷键方式 19 | 20 | 在开发者工具中键入 `command` + `k` + `command` + `s` 可以进入快捷键查看面板(是不是和 VSCode 如出一辙?),在面板顶部的 `Match shortcuts from preset` 中,可以切换为 `visual studio code`,切换后部分快捷键就会和 VScode 的保持一致。 -------------------------------------------------------------------------------- /docs/chrome/day-37.md: -------------------------------------------------------------------------------- 1 | # 如出一辙:Chrome 的 Debug 2 | 3 | 我们在前面的训练中已经了解了怎么在 VScode 中使用快捷键进行代码的 Debug,但是在大部分时候,我们都是在 Chrome 上 Debug,为了尽可能提高我们的效率,我们必须要了解一下它的快捷键操作。 4 | 5 | ## 基础操作 6 | 7 | - `command` + `b` / `command` + `shift` + `b`:在光标所在行打断点,如果该行已有断点则取消该断点;区别是用第一个组合键取消断点时,会完全取消,在 BreakPoint 面板中不会有记录留下;而用第二个组合键来取消则该断点时,断点标记不会完全消失,会变成半透明样式,且记录还会在 Breakpoints 面板上,以供随时重新打上该断点; 8 | - `command` + `'` / `f10`:step over; 9 | - `command` + `;` / `f11`:step into; 10 | - `shift` + `command` + `;`:step out; 11 | - `command` + `\` / `f5`:停止当前的断点; 12 | - `command` + `f8`:停止所有的断点; 13 | 14 | 可以看到,这部分的命令和之前的练习 [VScode Debug](../vscode/day-30.md) 中是类似的,这样一来我们的快捷键使用也会更加统一。 15 | 16 | ## 小技巧 17 | 18 | - `command` + `shift` + `e`:把选中的代码值输出到 console 面板; 19 | - `command` + `shift` + `o`:打开跳转到函数面板,与前面的 [VScode 单文件搜索符](../vscode/day-21.html#快捷搜索符号)类似;不过选择列表中只有函数,不会显示变量等其他的值; 20 | - `ctrl` + `g`:弹出输入框,输入数字可跳转到指定行; 21 | 22 | 在这几个命令的使用过程中或者前面提到的一些命令你可以发现,有些地方还是要用到鼠标操作,比如选中代码变量,比如在代码面板和代码文件面板的切换,这是肯定的;因为我们无法也没有必要要求所有操作都用键盘操作,只有在适合的场景用适合的方法,才能最大地提提高我们的效率。 -------------------------------------------------------------------------------- /docs/for-mac.md: -------------------------------------------------------------------------------- 1 | # Mac 环境准备 2 | 3 | ## vscode 环境准备: 4 | 1. 安装 vscode [vim](https://marketplace.visualstudio.com/items?itemName=vscodevim.vim) 拓展 5 | 2. 根据 vscode vim 中 Install 部分的说明对电脑进行设置(mac) 6 | 7 | ## 键位映射准备 8 | - 推荐使用 [karabiner-elements](https://karabiner-elements.pqrs.org/) 进行键位映射,映射规则如下: 9 | 1. ctrl 与 caps lock 互换;在日常中,caps lock 键的作用其实不大而 ctrl 键的使用频率更高,但在他们的位置上却相反,所以换过来会更适合我们日常用(可能部分朋友是使用 caps lock 进行输入法中英文切换,这时候我们可以使用搜狗输入法或其他可以使用 shift 键切换中英文的输入法就可以了) 10 | 2. ctrl + hjkl 映射为 方向键;这可以使我们在 insert mode 中方便地移动光标 -------------------------------------------------------------------------------- /docs/for-window.md: -------------------------------------------------------------------------------- 1 | # Window 环境准备 2 | 3 | ## vscode 环境准备: 4 | 1. 安装 vscode [vim](https://marketplace.visualstudio.com/items?itemName=vscodevim.vim) 拓展 5 | 6 | ## 键位映射 7 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # Just Vim It 2 | 这是一个纯小白入门 vim 的训练,这里有两个关键点 3 | 1. 使用于纯小白的(或者已经接触过vim但想构建一套基础,使用日常工作的vim方案的朋友),如果你不属于这样的人群,那可能这个训练并不适合你,因为可能在本训练中的一些快捷键设置、使用习惯和你已养成的并不相符 4 | 2. 这是一个入门训练,本训练只能保证在你认真使用、学习后,可以在日常、工作的代码工作中使用vim完成日常会用到的操作,更深一层的技巧则是在于你本人的探索 5 | 6 | ## 写在前面 7 | 8 | 由于我的主要使用场景是在 vscode 中使用 vim,以及在命令行中简单使用,所以大部分时候是围绕着 vscode 中的 vim 使用场景展开,但只要跟着全程训练坚持下来,再加上你聪明的小脑袋瓜子,将会很容易地知道并掌握如何在其他软件(如 webstorm、sublime、chrome、obsidian)中使用 vim 来脱离对鼠标的以来,甚至不仅仅 vim,你会想要找到更多更全面的方式,如 MacOS 下的 Alfred (假设你没有使用过它),所以对于 vim 的掌握程度或熟练程度,它只取决于你有多想摆脱频繁移动手去使用鼠标以及你使用 vim 的次数。 9 | 10 | ## 环境准备 11 | * **一台电脑**(mac 或 linux 为佳,window 的话我随后再试试有何不同,在 issue 区会有一些常见问题,也可自行查找) 12 | - [ Mac 环境 ](./for-mac.md) 13 | - [ Window 环境 ](./for-window.md) 14 | * **一个键盘** 15 | * **鼠标 / 触控板**(本训练无法也不会教你完全不使用鼠标 / 键盘操作 16 | * **坚持的心** 17 | 18 | :::tip 提示 19 | 在 issue 区会有一些常见问题,也可自行查找 20 | ::: 21 | 22 | :::tip 提示 23 | 24 | - 建示示练习 vim 之余,也练习一下电脑盲打,尤其是对于符号键位及功能键位,日常的使用时大部分人并没有非常规范地进行输入,常常是通过**一指禅**或是**移动整个手掌**来输入,这样的话输入效率也会降低,而正确(有些人喜欢杠正确这个词,或者说适宜大部分人、大部分场景)的键盘输入指法可以大大提高输入效率。大家不妨一试。 25 | 26 | - 我通过每天练习半个小时(早上10分钟,下午10分钟,晚上10分钟,大概两周),基本习惯了新的指法,且基本恢复原有的输入速度(甚至比原来更快了一些,因为击键的准确度上升了),并且对于百分之95的字符都可以盲打,所有我觉得大家都可以练习一下,是百利无一害的。 27 | 28 | ::: 29 | 30 | ## 一些说明 31 | 32 | 由于在该训练笔记是一天天地记录而成,可能一些名词、称呼在不同章节中有时不一致,特说明: 33 | 34 | - 操作、命令、组合键、快捷键 如无特殊说明,都为同一个意思 35 | - 资源管理器、文件浏览器、explorer 如无特殊说明,都为同一个意思 36 | - 编辑窗、编辑器窗口、editor 如无特殊说明,都为同一个意思 37 | 38 | ## 问题 / 反馈 39 | 在 issue 中会对一些大家可能或常见的问题进行补充和说明,遇到问题可以查阅 issue 或自己 google,也欢迎提 issue;如果文章中有错误等也麻烦大家指出,十分感谢! 40 | 41 | ## 最重要的一点 42 | 该训练是根据本人在 [@崔效瑞](https://github.com/cuixiaorui) 的 [键盘侠养成训练营](https://appewiejl9g3764.h5.xiaoeknow.com/p/course/ecourse/course_28y3lTEa0pnA2HVLtZiz1vQ2kH4) 中的笔记,本着共同进步、开源的精神整理而成,希望大家饮水不忘挖井人,多多支持他,再次感谢! -------------------------------------------------------------------------------- /docs/keybinding.md: -------------------------------------------------------------------------------- 1 | # 改键建议及参考 2 | 3 | ## 全局 4 | 5 | - 使用 karabiner 在全局把 `ctrl` + `[` 映射为 `esc`;因为日常使用 `esc` 的情况其实非常多,而未这样映射前我们在 vim 之外只能继续使用 `esc` 的按键达到这个功能;映射后我们再任意地方都可以使用 `ctrl` + `[` 达到 `esc` 功能;使用起来更加统一。使用 karabiner 映射时,在它的 `complex modifications` 栏中选中左下 `add rule`,然后通过弹出框上方的 `import more ...` 打开其规则列表页,搜索 `vim style escape key mapping`,第一个即为这个规则,点击导入即可。 6 | 7 | ## VScode 8 | 9 | ### VScode Vim 10 | 11 | ### 功能组合键映射 12 | 13 | ## Chrome 14 | 15 | ### Vimium-c 16 | 17 | ### 拓展设置 18 | 19 | - back to page 20 | 21 | ## Obsidian 22 | 23 | ## 未完待续... -------------------------------------------------------------------------------- /docs/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nauxscript/Just-Vim-It/d90da6160fffdbe5d1d5dfb78092e96a25ef281d/docs/public/favicon.ico -------------------------------------------------------------------------------- /docs/public/images/day-38-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nauxscript/Just-Vim-It/d90da6160fffdbe5d1d5dfb78092e96a25ef281d/docs/public/images/day-38-1.png -------------------------------------------------------------------------------- /docs/public/images/day-38-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nauxscript/Just-Vim-It/d90da6160fffdbe5d1d5dfb78092e96a25ef281d/docs/public/images/day-38-2.png -------------------------------------------------------------------------------- /docs/public/images/day-39-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nauxscript/Just-Vim-It/d90da6160fffdbe5d1d5dfb78092e96a25ef281d/docs/public/images/day-39-1.png -------------------------------------------------------------------------------- /docs/public/images/day-48-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nauxscript/Just-Vim-It/d90da6160fffdbe5d1d5dfb78092e96a25ef281d/docs/public/images/day-48-1.png -------------------------------------------------------------------------------- /docs/public/images/day-48-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nauxscript/Just-Vim-It/d90da6160fffdbe5d1d5dfb78092e96a25ef281d/docs/public/images/day-48-2.png -------------------------------------------------------------------------------- /docs/public/images/day-48-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nauxscript/Just-Vim-It/d90da6160fffdbe5d1d5dfb78092e96a25ef281d/docs/public/images/day-48-3.png -------------------------------------------------------------------------------- /docs/public/images/day-48-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nauxscript/Just-Vim-It/d90da6160fffdbe5d1d5dfb78092e96a25ef281d/docs/public/images/day-48-4.png -------------------------------------------------------------------------------- /docs/public/images/day-49-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nauxscript/Just-Vim-It/d90da6160fffdbe5d1d5dfb78092e96a25ef281d/docs/public/images/day-49-1.png -------------------------------------------------------------------------------- /docs/public/images/day-49-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nauxscript/Just-Vim-It/d90da6160fffdbe5d1d5dfb78092e96a25ef281d/docs/public/images/day-49-2.png -------------------------------------------------------------------------------- /docs/public/images/day-49-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nauxscript/Just-Vim-It/d90da6160fffdbe5d1d5dfb78092e96a25ef281d/docs/public/images/day-49-3.png -------------------------------------------------------------------------------- /docs/public/images/day-50-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nauxscript/Just-Vim-It/d90da6160fffdbe5d1d5dfb78092e96a25ef281d/docs/public/images/day-50-1.png -------------------------------------------------------------------------------- /docs/public/images/day-50-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nauxscript/Just-Vim-It/d90da6160fffdbe5d1d5dfb78092e96a25ef281d/docs/public/images/day-50-2.png -------------------------------------------------------------------------------- /docs/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nauxscript/Just-Vim-It/d90da6160fffdbe5d1d5dfb78092e96a25ef281d/docs/public/logo.png -------------------------------------------------------------------------------- /docs/terminal/day-38.md: -------------------------------------------------------------------------------- 1 | # 众神之地:初识命令行界面操作 2 | 3 | 众所周知,命令行工具,是操作系统露出的一个让用户触摸它的的灵魂的一片肌肤;与这片肌肤的亲密接触,你才能感受它灵魂深处的波涛汹涌;一个程序员不会使用命令行工具,就像西方人不知道耶路撒冷。虽然接下来这部分并不会教你怎么写命令行命令,但会教会你怎么在前端开发这种有限的 `润射` 使用中,把命令行工具玩出无限的花来(我瞎说的,如果你不认真去学习命令行的相关知识,你快捷键用得再 6 也没有用)。 4 | 5 | ## 常用命令行工具 6 | 7 | 常见的一下命令行工具(随便搜索列举一些比较受欢迎有知名度的,没有都体验过;由于没有使用过 Linux 系统,顾只推荐 MacOS 和 Window): 8 | 9 | - Terminal:MacOS 自带命令行; 10 | - iTerm2:MacOS & Window; 11 | - Warp:MacOS; 12 | - Tabby:MacOS; 13 | - Mobaxterm:MacOS & Window; 14 | - Window Terminal:Window,(笔者还使用 Window 时用的就是它,还不错,颜值也 ok); 15 | - ... 16 | 17 | [iTerm2](https://iterm2.com/) 作为 MacOS 端最受欢迎的命令行工具,提供了许多强大且好用的功能,可以说大部分人对于一款命令行工具的大部分需求,它都可以满足;所以命令行这一部分的训练是围绕着 iTerm2 来展开的;但又由于笔者使用的是 Warp,所以在每一章训练中会同步添加训练中介绍的 iTerm2 的功能对应的 Wrap 中的快捷键命令。 18 | 19 | ## iTerm 及其界面操作 20 | 21 | 安装 iTerm 极其简单,我们可以通过其官网链接下载,当然,MacOS 更推荐用 Homebrew 安装;通过 `brew install iterm2 --cask` 安装后,即可启动。 22 | 23 | :::tip iTerm2 窗口尺寸 24 | 初始安装的 iTerm2 的窗口尺寸可能会比较小(笔者的就是),可以在打开 iTerm2 后通过顶部的 `iTerm2 > Preference` 或 `command` + `,` 打开设置窗口,在 `Profiles` 的下图位置中可以设置。 25 | 26 | ![image-1](https://raw.githubusercontent.com/Nauxscript/Just-Vim-It/master/docs/public/images/day-38-1.png) 27 | ::: 28 | 29 | ### 分屏 30 | 31 | - `command` + `d`:左右分屏; 32 | - `shift` + `command` + `d`:上下分屏; 33 | - 切换分屏: 34 | + `command` + `option` + [方向键] 35 | + `command` + `[` / `]` 36 | 37 | ### 标签页 38 | 39 | - `command` + `t`:新建标签页; 40 | - `command` + `w`:关闭标签页; 41 | - `command` + [数字] / `command` + [方向键]:切换标签页; 42 | - `shift` + `command` + [方向键]:移动标签页; 43 | 44 | 由于 MacOS 的在快捷键上的统一性,可以发现标签页的快捷键其实和 Chrome 、VScode 的可以说是一模一样,只要习惯了这一套快捷键,在大部分 MacOS 上带有标签页的软件中你都可以使用。 45 | 46 | :::tip `command` + `enter` 全屏问题 47 | 当我们下载好 iTerm2 并在它内部使用 vim 时,你可能会发现当我们想用 `command` + `enter` 另起一行时,会变成全屏的效果(笔者遇到这个情况时一脸懵逼,完全不明白为什么它要把这个快捷键设置为全屏功能),为了使用方便,我们可以通过 `iTerm2 > Preference > Keys` 设置: 48 | 49 | 50 | ![image-2](https://raw.githubusercontent.com/Nauxscript/Just-Vim-It/master/docs/public/images/day-38-2.png) 51 | ::: 52 | ## Warp 界面操作 53 | 54 | [Warp](https://www.warp.dev/) 是命令行工具中的新秀,号称“为 21 世纪打造的命令行工具”。最近笔者在使用它,确实非常不错;颜值不错,皮肤什么的都可以调节,也可以跟随系统深色模式;功能不错,一些好用的功能别的工具可能要插件,但它基本原生支持,什么命令补全什么的;还有 Ai 命令识别等功能,确实值得一试。 55 | 56 | 以上的功能对应的快捷键和 iTerm2 基本一致,除了**不支持**: 57 | 58 | - `command` + [方向键]:切换标签页; 59 | - `shift` + `command` + [方向键]:移动标签页; 60 | 61 | 在 Wrap 中,只要键入 `command` + `p` 即可调出命令搜索面板,可以根据描述搜索所有的快捷键命令。 -------------------------------------------------------------------------------- /docs/terminal/day-39.md: -------------------------------------------------------------------------------- 1 | # 如虎添翼:什么是 zellij 2 | 3 | ## 安装 4 | 5 | zellij 的安装方式有几种,一般来说 MacOS 推荐使用 Homebrew 来安装,通过 `brew install zellij` 即可安装(个别朋友如果出现安装卡住或出错,可以换源试试); 6 | 7 | 安装后在命令行工具键入 `zellij` 即可启动 zellij(有点像废话),但这个命令有点长,正如 `lazygit` 命令一样,我们可以配置一个别名来方便启动 zellij; 8 | 9 | ```shell 10 | # 编辑 .zshrc 11 | vi ~/.zshrc 12 | ``` 13 | 14 | 添加 `alias zj="zellij"` 到末尾新一行,保存后退出命令行重新打开,测试使用 `zj`,如果可以启动 zellij 即为配置成功。 15 | 16 | :::tip 乱码问题 17 | 安装完进入 zellij 后,可能有部分朋友会发现 zellij 的底部操作提示栏有些地方显示一些问号,这时因为一些符号在当前符号集中无法显示,可以在打开 iTerm2 后通过顶部的 `iTerm2 > Preference` 或 `command` + `,` 打开设置窗口,在 `Profiles` 的下图中的 `Use built-in Powerline glyphs` 勾上即可。 18 | 19 | ![image-1](https://raw.githubusercontent.com/Nauxscript/Just-Vim-It/master/docs/public/images/day-39-1.png) 20 | ::: 21 | 22 | ## 使用 23 | 24 | zellij 的使用哲学简单易懂,和 VSpaceCode 插件很类似。进入 zellij 后,可以看到底部栏有一些键位以及其对应的功能类;如 `g` 为 `LOCK`,`p` 为 `PANEL`,`t` 为 `TAB` 诸如此类;比如我们有增加一个标签页,只需要使用 `Ctrl` + `t`,此时底部 `TAB` 选项会高亮,下方会出现一系列的按键提示,如 `n` 为 `New` 即 新建,`x` 为 `close` 即关闭等等,我们这时在键入一个 `n`,即可新建一个标签页,然后在按下 `enter`,即可聚焦当前标签页,进行输入命令等;如果要切换标签页,也是类似:先进入对应的 TAB 功能类,然后使用 `hjkl` 或方向键可以切换;总的来说其公式是: 25 | 26 | - `Ctrl` + [功能类] + [功能] 27 | 28 | 了解了这个,我们就可以去探索 zellij 的功能了。 29 | 30 | ### 窗格操作 31 | 32 | 昨天的训练我们学习了窗格的一系列操作;同样的,我们也可以用 zellij 来实现相同的操作: 33 | 34 | - `ctrl` + `p` + `r`:左右分屏; 35 | - `ctrl` + `p` + `d`:上下分屏; 36 | - 切换分屏: 37 | + `ctrl` + `p` + [方向键]:切换对应位置的窗格 38 | + `ctrl` + `p` + `p`:切换到下一个窗格 39 | 40 | ### 标签页操作 41 | 42 | 这时对应的一些标签页操作: 43 | 44 | - `ctrl` + `t` + `n`:新建标签页; 45 | - `ctrl` + `t` + `x`:关闭标签页(如果当前只有一个标签页则会退出 zellij); 46 | - `ctrl` + `p` + [方向键]:切换标签页; 47 | 48 | 其实以上这些操作都不需要记忆,只要记得上面提到的公式,不熟练的时候可以看看底部的文字提示,很快就可以练成肌肉记忆了。 -------------------------------------------------------------------------------- /docs/terminal/day-40.md: -------------------------------------------------------------------------------- 1 | # 高歌猛进:zellij 的高级使用 2 | 3 | ## session 会话 4 | 5 | ## sync 同步操作 6 | 7 | ## 滚动 8 | 9 | ## 清理 10 | 11 | ## 修改配置 -------------------------------------------------------------------------------- /docs/terminal/day-41.md: -------------------------------------------------------------------------------- 1 | # 一见如故:认识 zsh-vi-mode -------------------------------------------------------------------------------- /docs/terminal/day-42.md: -------------------------------------------------------------------------------- 1 | # 出神入化:进阶 zsh-vi-mode 2 | 3 | ## surround 老朋友 4 | 5 | ### 典型用法 6 | 7 | 8 | ### s-prefix 用法 9 | 10 | ### 切换 11 | 12 | ## 改键配置 13 | 14 | - L: 15 | - H: 16 | 17 | ## 复制功能配置 18 | 19 | ## setup 钩子 20 | 21 | ## 小特性 22 | 23 | - `ctrl` + a: 24 | - ctrl + x -------------------------------------------------------------------------------- /docs/terminal/day-43.md: -------------------------------------------------------------------------------- 1 | # 神兵利器:zsh 常用插件 -------------------------------------------------------------------------------- /docs/terminal/day-44.md: -------------------------------------------------------------------------------- 1 | # 自成一派:zsh 自定义快捷键 -------------------------------------------------------------------------------- /docs/vim/day-1.md: -------------------------------------------------------------------------------- 1 | # 起步:这是一个适合开始改变自己的日子 2 | 3 | ## 开始前 4 | 5 | 正如进入游戏后我们首先是尝试移动我们控制的人物,开始 vim 的第一步,当然就是控制光标的上下左右啦;在开始之前,先忘记我们常用的右下的方向键(如果你是一个臭打游戏的,把 w a s d 也忘记,谢谢你)。 6 | 7 | ## 模式切换 8 | 9 | 对于 vim 来说,有: 10 | 11 | - 命令模式(Command mode) 12 | - 输入模式(Insert mode) 13 | - 底线命令模式(Last line mode) 14 | 15 | 这三种模式,而我们目前只需要用到前两种,分辨我们当前在那种模式的方法也很简单: 16 | 17 | - 光标是一个方块,命令模式(Command mode) 18 | - 光标是一条线,输入模式(Insert mode) 19 | - 没有光标或光标是文字的下划线(vscode),且输入内容时显示在命令行或窗口的底部,并且底部内容前有一个 : ,底线命令模式(Last line mode) 20 | 21 | ### 切换 22 | 23 | - **命令模式 到 输入模式:** 在 命令模式 中按 `i` (这里只是举例子,有很多其他的按键也可以进入插入模式,如下面提到的 `a` 24 | - **输入模式 到 命令模式:** 在 输入模式 中按 `Ctrl + [` 或 `esc` 25 | - **命令模式 到 底线命令模式** 在 命令模式 中按 `:` (目前并不会马上用到底线命令模式,但为了防止有时候不小心进入了该模式,所以提一嘴) 26 | - **底线命令模式 到 命令模式** 在 底线命令模式 中输入 `q` 27 | 28 | ## 操作 29 | 30 | 基本的操作: 31 | 32 | - 光标移动:`h` 左,`j` 下,`k` 上,`l` 右 (命令模式中) 33 | - 光标前插入:`i` (即 insert) (命令模式中) 34 | - 光标后插入:`a` (即 after) (命令模式中) 35 | - 删除一整行:`dd` (命令模式中) 36 | 37 | ### 小练习 38 | 把下列句子按照第一句的正确顺序修改好并把多余的空行删除 39 | ``` 40 | this is a simple easy vim tutorial 41 | 42 | tutorial simple a easy this vim is 43 | is this tutorial vim simple a easy 44 | 45 | 46 | tutorial vim this is a easy simple 47 | tutorial easy vim simple a this is 48 | simple a vim easy tutorial is this 49 | 50 | tutorial is easy vim a simple this 51 | 52 | 53 | vim simple this tutorial a easy is 54 | a vim tutorial simple easy is this 55 | 56 | 57 | easy a simple vim is tutorial this 58 | vim tutorial is a easy simple this 59 | a this vim tutorial is easy simple 60 | this tutorial simple easy a is vim 61 | 62 | 63 | easy tutorial this simple a is vim 64 | a tutorial easy is this simple vim 65 | 66 | a tutorial vim is easy this simple 67 | simple this easy is vim tutorial a 68 | 69 | this tutorial is a easy simple vim 70 | vim is tutorial simple this easy a 71 | 72 | vim is simple this tutorial easy a 73 | easy a simple is vim this tutorial 74 | vim is tutorial simple a easy this 75 | this vim is tutorial simple easy a 76 | ``` 77 | 78 | ### 加点料 79 | * 跳到单词尾:`e` (命令模式中) 80 | * 跳到单词头:`b` (命令模式中) 81 | * 跳到下一个单词开头:`w` (命令模式中) 82 | * 删除光标所在行并进入输入模式:`cc` (命令模式中) 83 | -------------------------------------------------------------------------------- /docs/vim/day-10.md: -------------------------------------------------------------------------------- 1 | # 好辅助:数字与 `.` 的威力 2 | 3 | ## 数字 4 | 之前的训练中提到了数字的简单使用,如 `J` `K` 映射到 `5j` `5k`,以及使用一些插件 viw.easymotion 来减少数字的使用;这一部分我们会学习数字的使用语法以及为什么我们要减少数字的使用。 5 | 6 | ### 语法 7 | 数字可以让我们快速进行一些重复操作,比如我们需要删除 5 个单词,不使用数字的话我们需要输入 5 次 `dw`,但使用数字的话我们可以直接 `5dw` 或 `d5w` 即可;我们可以看到这两个命令数字在不同位置,一样的命令组合,效果也一样,这跟 vim 数字使用语法有关: 8 | 9 | - [数字] + operator + motion:如 `5dw` `3fe` 10 | - operator + [数字] + motion:如 `d5w` 11 | 12 | :::tip 什么是 motion 和 operator ? 13 | motion 可以理解为字符范围,分类如: 14 | - words motions 15 | `w` 移光标至下一词 16 | `b` 移光标至上一词 17 | `e` 移光标至词末 18 | - Left-right motion 19 | `h` 光标向左移一字节 20 | `l` 光标向右移一字节 21 | `$` 移光标至行末 22 | `0` 移光标至行首 23 | `^` 移光标至本行首个非空格的字节 24 | - Up-down motions 25 | `j` 光标向下移一行 26 | `k` 光标向上移一行 27 | `gg` 移光标至整个文本的首行首个非空格字节 28 | `G` 移光标至整个文本最后一行首个非空格字节 29 | - Other motions 30 | `%` 移光标至匹配括号的另一端 31 | `H` 移光标至窗口第一行 32 | `M` 移光标至窗口中间一行 33 | `L` 移光标至窗口最后一行 34 | 35 | operator 为操作,如 `d` `c` `s` `x` `f`,vim 中的增删改查命令都可以理解为 operator 36 | ::: 37 | 38 | ### 优点: 39 | 40 | 使用数字可以让我们的命令历史记录连贯,在做撤销、重做等操作时可以有简洁的历史记录;如 `5dw`,撤销的时候一步就会撤销到五个单词删除前而不是要撤销五次 41 | 42 | ### 缺点: 43 | 44 | 由于数字键的位置实在偏僻,以及在大多数情况下,我们需要比较长的思考反应时间才能使用到准确的数字达到想要的效果 45 | 46 | ## `.` 命令 47 | 48 | `.` 的作用是重复上一次的修改操作,这个修改操作是指: 49 | 50 | - 对字符做了更新(增删改):如 `d` `c` `x` 之类的 51 | - 离开插入模式之前的按键组合 52 | 53 | :::tip 提示 54 | 能够使用重复的达到效果就不用使用数字,这样有利于留下完整的回退痕迹。 55 | ::: -------------------------------------------------------------------------------- /docs/vim/day-11.md: -------------------------------------------------------------------------------- 1 | # 开发必备:多文件跳转的奥妙 2 | 3 | 在开发中,我们常常需要在多行代码、多个文件中来回穿梭,在方法与调用出翻来覆去;而 vim 对于这类情况,有它独特的理解和解决解决方案 —— 跳转。 4 | 5 | ## 何为跳转(jump) 6 | 7 | vim 会记录我们最近通过命令访问的位置(包括文件名、行号、列号),记录在一个叫 jump list 的列表中,而且每个窗口都会有一个单独的 jump list。顾名思义,jump list 中的每条记录都是一个跳转(jump),而会被记录在 jump list 的位置需要是一下的指令产生的: 8 | 9 | - `'` :跳转到标记的⾏,标记的具体解释在下一段 10 | - `` ` `` :跳转到标记的位置(⾏和列),标记的具体解释在下一段 11 | - `gg` : 跳转到头部 12 | - `gd` : 跳转到定义;这个在日常使用特别多,谨记; 13 | - `/` :向后搜索 14 | - `?` :向前搜索 15 | - `n` :重复上⼀次搜索,相同⽅向 16 | - `N` :重复上⼀次搜索,相反⽅向 17 | - `{` :跳转上⼀个段落 18 | - `}` :跳转下⼀个段落 19 | 20 | 而 `hjkl`、`shift` + `j` / `k` (即映射后的 `5j` `5k`)、`ctrl` + `f` / `b` / `u` / `d` (翻页 / 翻半页)等是不会记录在 jump list 的; 21 | 22 | :::tip 特别说明 23 | vim-sneak 的跳转只会记录一次 24 | ::: 25 | 26 | 由于 jump list 保留了光标的移动记录,我们可以通过 `:jumps` 查看 jump list,vim 会显示金近 100 条记录;我们也可以可以在 jump list 中选中记录进行对应位置的跳转。 27 | 28 | 但是使用 `:jumps` 查看 jump list 来进行跳转的操作比较繁琐,而且很多时候我们并不关心之前这么多的跳转,我们只在乎跳转的顺序,因为只有顺着 jump list 的顺序,我们总会跳到想去的位置,这时我们可以使用以下命令: 29 | 30 | - `ctrl` + `i`:跳转到 jump list 的后一个记录 31 | - `ctrl` + `o`:跳转到 jump list 的前一个记录 32 | 33 | :::tip 键位规律 34 | 如 `j` `k` 一样, `i` `o` 的按键位置也是一样的规律:表示下一个在左,表示上一个的在右 35 | ::: 36 | 37 | 如此这般,我们就可以在 jump list 中穿梭了;比如我们看到一个函数调用,想看看这个函数的内部实现,我们使用 `gd` 跳转到它定义的地方;阅读完内部实现后,我们使用 `ctrl` + `o` 就可以再跳回去原本看到函数的调用的位置继续我们的工作。 38 | 39 | ## 标记定位 40 | 41 | 上面我们提到了 `'` 和 `` ` `` 这两个和标记有关的指令,那什么是标记?即当我们光标在某行代码时,可能我们要短暂地离开当前行甚至当前文件,我们就可以用这个命令做个标记,等我们在别的地方想回来时,就可以像回城技能一样,一按命令就回到标记的行甚至标记的列。 42 | 43 | ### 命令 44 | 45 | - `m` + [小写字母]:只可在单个文件内跳转的标记;后面的为标记的标识符,用于跳转的指向;可以理解为当前标记的名字;下同 46 | - `m` + [大写字母]:可在多个文件之间跳转的标记 47 | 48 | 比如我们在某个位置执行 `mm`,然后在本文件中的其他位置只要使用 `'m` 就可以跳到标记的行,使用 `` `m `` 就可以跳到标记的行和列;当然我们也可以用其他字母如 `mf`,当相应的跳转命令也变成 `'f` 和 `` `f ``。 -------------------------------------------------------------------------------- /docs/vim/day-12.md: -------------------------------------------------------------------------------- 1 | # 进入包围圈:感受 vim-surround 神器的威力 2 | 3 | 在[第六天](./day-6.md)的训练中,我们学习了文本对象,学习了如何通过 `i` `a` 进行对一些符号、标签的内部内容进行修改和删除;但有一些时候,我们可能是需要操作包裹着这些内容的符号本身;而这就今天的主角 ——— vim-surround 插件的核心功能。 4 | 5 | ## vim-surround 6 | 7 | vim-surround 是关于“包围”的插件:如被括号、括号、引号、XML 标签等等包围。该插件提供映射,可以轻松地成对删除、更改和添加此类包围着内容的符号。它的命令是 `s` (请勿与删除并进入 insert mode 的 `s` 或 vim-sneak 的 `s` 混淆,这两个是 operator,而 vim-surround 的 `s` 更像是一个 motion,虽然我不确定这样说准不准确)。 8 | 9 | ### 命令示例 10 | 11 | 以下是 [vim-surround](https://github.com/tpope/vim-surround) 插件 github 仓库 readme 中举得例子;并非我想偷懒,而是官方举得例子实在是已经非常详尽: 12 | 13 | 我们有如下字符串,光标在它内部时 normal 模式下使用 `cs"'` 14 | ``` 15 | "Hello world!" 16 | ``` 17 | 18 | 则会变成以下这样: 19 | ``` 20 | 'Hello world!' 21 | ``` 22 | 23 | 这时我们使用 `cs'`,就变成了: 24 | ``` 25 |

Hello world!

26 | ``` 27 | 28 | 再使用 `cst"`,就回到最初的模样(疑惑为什么是 `t` 的人需要去复习一下[前面](./day-6.md#文本对象)了): 29 | ``` 30 | "Hello world!" 31 | ``` 32 | 33 | 删除包裹的符号,我们使用 `ds"`: 34 | ``` 35 | Hello world! 36 | ``` 37 | 38 | 如果我们把光标移到 `hello` 单词上,输入 `ysiw]`,则变成这样: 39 | ``` 40 | [Hello] world! 41 | ``` 42 | 43 | 如果我们要把中括号变成花括号并且单词和符号之间要有空格,我们可以使用 `cs]{` (如果使用 `}` 则添加的花括号是没有空格的,`)` `]` 同理): 44 | ``` 45 | { Hello } world! 46 | ``` 47 | 48 | 这时,我们还可以通过 `yssb` 或 `yss)` 来给整行添加包裹: 49 | ``` 50 | ({ Hello } world!) 51 | ``` 52 | 53 | 输入 `ds{ds)` 去掉所有包裹: 54 | ``` 55 | Hello world! 56 | ``` 57 | 58 | 对于前端开发来说,他是一个很有用的插件;比如我们现在有一个这样的标签: 59 | ```html 60 |

hello world

61 | ``` 62 | 63 | 这时我们使用 `V` 进入 linewise visual model(行内可视化模式),再键入 `S
`,就变成了: 64 | ```html 65 |
66 |

hello world

67 |
68 | ``` 69 | 70 | 在我们日常开发中,尤其是写 html 时,这非常好用。而且我们还可以使用 `.` 来重复执行 `ds` `cs` `yss` 这类的指令,一如我们之前提到那样。 71 | 72 | :::tip one more thing 73 | 练习群的朋友提到还有一个用法,即配合 `t` 来出来 xml 或 html 的标签包裹的场景,比如: 74 | 75 | ```html 76 | hello 77 | ``` 78 | 79 | 在 hello 中输入 `ysiwt` + `div`,则变成了: 80 | 81 | ```html 82 |
hello
83 | ``` 84 | 85 | 再输入 `ysst` + `div`,就成了: 86 | ```html 87 |
hello
88 | ``` 89 | ::: 90 | -------------------------------------------------------------------------------- /docs/vim/day-13.md: -------------------------------------------------------------------------------- 1 | # 变化之术:替换字符和多文本选中 2 | 3 | 前面学习了 `r` `c` 等可以修改文本的指令,再配合文本对象可以达到一个“快速”修改文本的效果,这里打双引号是因为,这些学过的修改替换文本,都是单个替换;而实际情况中,我们往往需要一次性修改多个地方的相同字符,比如修改一个变量名、函数名等;今天,我们就来了解一下选中和替换的操作。 4 | 5 | ## 替换 6 | 7 | 多文本替换的操作指令是 `:substitute`,一般直接用 `:s`;替换的完整指令公式是:`:[range]s[ubstitute]/{pattern}/{string}/[flags]`; 8 | 9 | ### 公式 10 | - `[range]`:指范围,可以使用如下几个指令: 11 | * `%`:匹配全文,建议只记忆这个就可以了,比较常用 12 | * `$`:匹配到尾部;并非如 `$s` 这样使用,而是搭配下面的数字键,如 `:12,$s/[文本]/[文本]`,即匹配从 12 行到页面尾部 13 | * [number],[number]:匹配从 [number] 行到 [number] 行,如 `:10,12s/[文本]/[文本]`,即匹配从 10 行到 12 行 14 | 15 | - `{pattern}`:正则表达式 16 | - `[flags]`: 17 | * `g`:匹配所有符合的字符;由于在使用 `s` 来匹配字符时,默认是匹配每一行的第一个,所以如果需要匹配所有,则需要加上 `/g` 18 | * `c`:弹出对话框来确认每一个替换 19 | - visual mode 下输入 `:`,可以注意到命令栏会显示 `:'<,'>`,这其实是指从选中区域的开头到选中区域的结尾,相当于给我们划定了一个 [range],这是我们接着输入 `s`,即可以选中文本进行替换 20 | ## 多选操作 21 | 22 | `gb` 命令可以选中与我们光标所在的单词相同的且未被选中的第一个单词;比如有: 23 | 24 | ``` 25 | number number 26 | number 27 | ``` 28 | 29 | 如果我们的光标在第一个 number 里面,并按下 `gb`,则会选中第一个 number;如果我们此时再按多一个 `gb`,则会选中第二个 number;如此类推。选中多个之后,我们就可以使用 `d` `c` 等命令来多光标修改了。 -------------------------------------------------------------------------------- /docs/vim/day-14.md: -------------------------------------------------------------------------------- 1 | # 得力辅助:大小写转换、注释与显示悬浮提示 2 | 3 | ## 大小写转换 4 | 5 | 在之前的训练开始前的准备中提到的改改键中,我们提到把 `control` 键与 `caps lock` 键互换,因为在大部分要输入大写的时候,我们都可以通过 `shift + [字母]` 来达到一样的效果; 6 | 7 | - `gu`:变小写 8 | - `gU`:变大小 9 | - `~`:大小写互换 10 | 11 | `gu` `gU` 后面可接 motion ,比如 `gue` 就可以把光标到单词末尾的字符变成小写,而 `gUiw` 就可以把当前单词变成全大写;与 `d` `c` 等操作符是一样的用法。而在 visul mode 中,我们可以直接使用 `u` `U`,即选中了一段文本后可以直接用这两个命令把所有的字母转换成大写或小写。 12 | 13 | ## 注释 14 | 15 | 平时在 vscode 中,注释的快捷键是 `command + /`,其实也能用,不过 vim 的注释命令除了单行注释、多行注释,还可以选中了行内的文本后进行行内注释;命令如下: 16 | 17 | - `gc`:单行注释,和 `command + /` 的效果一样;如在 js 文件中注释时是 `//` 开头 18 | - `gC`:多行注释,如在 js 文件中注释时是被 `/* */` 包裹 19 | 20 | 而且,这个命令在 visual mode 和 normal mode 是通用的。 21 | 22 | ## 显示悬浮提示 23 | 24 | 在日常开发中,我们常常会需要查看一些代码中的报错、警告或者一些代码提示等,但是大部分的编辑器,如 vscode,都是需要用鼠标移到被标记的代码中才能让悬浮提示框显示出来,而 vim 提供了一个命令,可以达到鼠标划入光标所在单词的效果,它就是 `gh`。记忆它也很简单,就记住 “h for hover”,即 `h` 是指 “hover” 的意思,我相信前端开发的小伙伴应该都能快速记住这个指令。 25 | -------------------------------------------------------------------------------- /docs/vim/day-15.md: -------------------------------------------------------------------------------- 1 | # 只手遮窗:窗口管理大法 2 | 3 | 在开发中,我们可能需要同时打开多个编辑窗口,二分屏、三分屏甚至更多,这时候在不同的窗口中切换焦点也就是一个大需求,而 vim 和 vscode,都有提供一套多编辑窗口的管理方法,任君选择。 4 | 5 | ## vim 的窗口管理 6 | 7 | ### 新建窗口 8 | - `control` + `w` + `v`:在当前窗口的左边或右边新建窗口 9 | - `control` + `w` + `s`:在当前窗口的上边或下边新建窗口 10 | 11 | ### 窗口切换 12 | - `control` + `w` + `h` `j` `k` `l`:切换到上 / 下 / 左 / 右方向的窗口 13 | - `control` + `w` + `v`:打开多个窗口时,在不同的窗口间相互切换,如只有两个窗口时,则在两个窗口间互相切换 14 | 15 | ### 关闭窗口 16 | - `control` + `w` + `c`:关闭当前窗口 17 | - `control` + `w` + `v`:保留当前窗口,关闭其他所有窗口 18 | 19 | ## vscode 的窗口管理 20 | 可能有些人(包括我)会觉得 vim 的窗口管理快捷键比较繁琐,尤其是使用过 vscode 的窗口管理快捷键的小伙伴,为了让我们管理得更顺手,我们可以结合 vscode 自身的快捷键再加上一些扩展的键位映射,达到和 vim 的窗口管理快捷键一样的效果。如下: 21 | 22 | ### 新建窗口 23 | 24 | - `command` + `\`:在当前窗口的左边或右边新建窗口 25 | - `command` + `control` + `\`:在当前窗口的上边或下边新建窗口 26 | 27 | ### 窗口切换 28 | 29 | - `shift` + `control` + `h` `j` `k` `l`:切换到上 / 下 / 左 / 右方向的窗口 (需要有将 `control` + `h` `j` `k` `l` 映射为方向键),并且在 vscode 的 `keybindings.json` 中添加如下映射,映射其实是把 `shift` + 方向键映射为 vim 的窗口切换键了: 30 | 31 | ```json 32 | { 33 | "key": "shift+left", 34 | "command": "vim.remap", 35 | "when": "vim.mode == 'Normal'", 36 | "args": { 37 | "after": ["", "h"] 38 | } 39 | }, 40 | { 41 | "key": "shift+right", 42 | "command": "vim.remap", 43 | "when": "vim.mode == 'Normal'", 44 | "args": { 45 | "after": ["", "l"] 46 | } 47 | }, 48 | { 49 | "key": "shift+up", 50 | "command": "vim.remap", 51 | "when": "vim.mode == 'Normal'", 52 | "args": { 53 | "after": ["", "k"] 54 | } 55 | }, 56 | { 57 | "key": "shift+down", 58 | "command": "vim.remap", 59 | "when": "vim.mode == 'Normal'", 60 | "args": { 61 | "after": ["", "j"] 62 | } 63 | } 64 | ``` 65 | 66 | :::info 多嘴一句 67 | 感觉 `shift` + `control` + `h` `j` `k` `l` 和 `control` + `w` + `h` `j` `k` `l` 其实是差不多的,改不改区别不大。 68 | ::: 69 | 70 | 71 | ### 关闭窗口 72 | - `command` + `w`:关闭当前窗口 73 | - `command` + `k` + `w`:保留当前窗口,关闭其他所有窗口 74 | 75 | :::tip 小提示 76 | 在vscode中如果关闭有未保存内容的窗口时,会弹出对话框; 77 | 这时如果按 `enter` 键,即为 “保存”, 78 | 按 `space` 键,是为 “不保存”。 79 | ::: -------------------------------------------------------------------------------- /docs/vim/day-16.md: -------------------------------------------------------------------------------- 1 | # 开发利器:快速删除一个函数 2 | 3 | 对于代码佬日常的开发工作中,常常需要把同事或者自己写的一些~~屎山~~代码函数删除;在之前的练习中,我们曾提到过 `p` 这个代指段落的文本对象,所以想到要删除一个函数我们可能会先想到用它来实现,比如 `dap` 如此这般;但因为段落的定义是空行之间的内容为不同段落,这在一些情况下无法满足我们删除一个函数的需求,如: 4 | 5 | ```js 6 | const test = (a = 1) => { 7 | console.log(a) 8 | a = 2 9 | 10 | setTimeout(() => { 11 | console.log(a) 12 | }, 500); 13 | } 14 | ``` 15 | 16 | 我们可以注意到,在函数内部有一个空行,这时我们在空行的上方或者下方使用 `dap`,则只会删除一半的函数。那有没有更好的方法呢?那肯定是有的,不过我们要先来了解一下 `%` 命令和 vim-indent-object。 17 | 18 | ## `%` - 匹配括号 19 | 20 | 在 vim 中,我们可以通过 `%` 来匹配括号,即括号 `()`、中括号 `[]`、大括号 `{}`,当我们的光标在括号上时,我们使用 `%` 可以跳到与当前括号成对的另外一个括号上。 21 | 22 | ## vim-indent-object - vim 缩进对象 23 | 24 | 这个是 vim 自带的一个扩展插件,该插件基于缩进级别定义了一个新的文本对象 `i`;即我们可以使用它来基于缩进进行一些操作,如 `>ii` 可以把同一个缩进级别的内容全部往右移动一个缩进(中间的 `i` 是指 [`inner`](./day-6.md#语法结构))。 25 | 26 | ## 删除函数 27 | 28 | 通过我们上面提到的两个指令,我们就可以来研究一下怎么删除一下函数了;对于大部分使用缩进的来规范语法结构的语言如 Python 、JavaScript 等,它们的函数也是有着明显的缩进规律的,这时,我们可以使用 `daI` 来实现删除函数,但前提是光标在函数的内部;但如果如下面这种情况: 29 | 30 | ```js 31 | const test1 = (a = 1) => { 32 | console.log(a) 33 | a = 11 34 | 35 | setTimeout(() => { 36 | console.log(a) 37 | }, 500); 38 | } 39 | 40 | const test2 = (a = 2) => { 41 | console.log(a) 42 | a = 22 43 | 44 | setTimeout(() => { 45 | console.log(a) 46 | }, 500); 47 | } 48 | ``` 49 | 50 | 如果光标在 test1 或 test2 函数名那一行并使用 `daI`,则会把两个函数都删除;因为对于这两个函数来说,它们有同样的缩进级别。当然,在大部分情况下,`daI` 都是够用了的;为了让我们用得更顺手一些,我们可以把 `ai` 映射成 `aI`: 51 | 52 | ```json 53 | "vim.operatorPendingModeKeyBindings": [ 54 | { 55 | "before": ["a", "i"], 56 | "after": ["a", "I"] 57 | } 58 | ], 59 | "vim.visualModeKeyBindings": [ 60 | { 61 | "before": ["a", "i"], 62 | "after": ["a", "I"] 63 | }, 64 | ] 65 | ``` 66 | 67 | 这样我们在可视化模式或者操作待决模式(operator pending mode)时可以直接使用 `i` 代替 `I`。 68 | 69 | 而为了弥补上面提到的 vim-indent-object 的短板,我们还可以通过 `%` 配合 `` 来实现删除函数;首先,对于光标在函数名所在行时(如上面提到的例子),我们可以使用 `V` 来选中当前行,然后需要把光标移动行末,即 `$`,这时光标在花括号上,再键入 `%`,这时候就可以选中到函数的闭合符处,最后键入 `d`,即可把函数删除;总的指令就是 `V$%d`。但是这么长一个命令未免太麻烦,这时我们就可以用 `` 来映射: 70 | 71 | ```json 72 | "vim.normalModeKeyBindings": [ 73 | { 74 | "before": ["", "d", "f"], 75 | "after": ["V", "$", "%", "d"] 76 | }, 77 | ], 78 | ``` 79 | 80 | 这样当我们光标在函数名那一行时就可以通过 `` + `df` 来快速删除一个函数了。再加上前面提到的光标在函数内部时的删除命令,基本可以应付大部分的情况了。 -------------------------------------------------------------------------------- /docs/vim/day-17.md: -------------------------------------------------------------------------------- 1 | # 告别重复:vim 的宏操作 2 | 3 | 在开发中,我们有时会面临需要重复大量相同的操作的情况,比如下面的代码: 4 | 5 | 我们需要把所有变量名为 `obj` 的对象修改为 `Obj` 并在前面添加 `_`,最终变成 `_Obj`,但是我们不能修改为数组的 `obj`,而且处于谨慎起见,我们不可以同事多光标去修改; 6 | 7 | ```js 8 | const obj = new Object() 9 | const obj = new Object() 10 | const obj = new Object() 11 | const obj = [] 12 | const obj = new Object() 13 | const obj = [] 14 | const obj = new Object() 15 | ``` 16 | 17 | 这时,你可能想起 `.` 命令,在[前面](./day-10.md)我们提到过,它可以重复执行上一个命令;但是对于当前的场景,有好像无法使用 `.`,这时就要请出终极大杀器 ———— 宏操作(macro)了。 18 | 19 | ## 宏操作 20 | 21 | 宏(macro)即可以把一系列的操作录制成组并暂存起来,然后通过特定的指令重复去触发执行。 22 | 23 | ### 命令 24 | 25 | - `q` + [字母]:开始录制,并把当前一次的录制命名为 [字母];如 `qa`,则当前录制的宏操作名称为 `a`,如 `qq`,宏操作则为 `q`;录制完后,再输入 `q` 则退出录制 26 | - `:reg` + [字母]:查看录制好的名为 [字母] 的宏操作 27 | - `@` + [字母]:调用名为 [字母] 的宏操作 28 | - `@@`:调用最后一次执行的宏操作 29 | - [数字] + `@` + [字母]:以 [数字] 次数重复执行名称为 [字母] 的宏操作 30 | - `q` + [大写字母]:在对应名为 [字母] 的宏操作后追加命令;比如我们录制一个宏操作为 a,他的功能是删除每行的第一个单词;则我们首先录制改宏操作:`qa^diw`;录制完后发现我们删除了第一个单词后,还需要把光标移到下一行,这时我们可以键入 `qAj`,即在宏操作 a 后面追加个 `j` 命令,就可以愉快地继续使用宏操作 a 了 31 | 32 | :::tip 注意 33 | 在录制宏操作时,名称无论输入的是大写字母还是小写字母,最终都会暂存为小写字母,而往宏操作追加时,则使用名称字母的大写进行追加。 34 | ::: 35 | 36 | 对于多次执行宏操作的时候,当出现无法执行对应操作时,会报错并停止执行;比如,我们使用宏操作进行批量替换特定文本,内容里有 10 个要替换的文本,而我们使用 [数字] + `@` + [字母] 的方式让操作执行 20次;当指令执行完第十次后发现已经没有可替换的文本时,vim 会报错并停下;利用这个特性,我们可以在一些重复操作中无心智负担地进行全量执行,比如大概预估要重复执行的次数,然后直接执行一个绝对大于数目的次数,就可简单安全地达到目的。 37 | 38 | ### 修改已暂存的宏 39 | 40 | 录制一个宏操作后 vim 会把录制的宏操作暂存在寄存器中;而修改一个已知的宏操作,其实是指修改寄存器中的内容;则我们的步骤是:获取宏操作的内容、修改该内容、重新储存回寄存器 41 | 42 | * 获取宏操作的内容: 43 | + `"` + [字母] + `p`:粘贴名称为 [字母] 的宏操作;`"` + [字母] 可以理解为获取该宏操作,而 `p` 就是粘贴;这时会把对应的宏命令粘贴在我们当前光标所在的位置中; 44 | + `:put ` + [字母]:与上面的效果一样,这时也会把对应的宏命令粘贴在我们当前光标所在的位置中(注意 put 后有个空格); 45 | * 修改该内容 46 | * 重新储存回寄存器:这一步其实是要把新的操作命令组合替代原来的宏操作的命令组合;同样先要输入 `"` + [字母] 获取到对应宏操作,此时 vim 会等待你接下来存入寄存器中的内容,把该内容作为原来宏操作 [字母] 的对应命令组合;此时我们可以键入 `yw` 、 `yy` 等可以向寄存器存入内容的命令(换言之,`d` 、 `c` 等命令也可以),把对应的宏操作 [字母] 的命令组合修改为我们新的内容。 47 | 48 | 比如还是上面提到的追加操作提到的宏命令,我们添加 `j` 后,发现在删除了第一个单词后,每行前面还有一个空格,所以在光标跳到下一行之前,还要把空格删掉;这时我们可以键入 `:put a`,此时会粘贴出 `^diwj`,然后我们把文本修改为 `^diwxj`,然后在 normal mode 把光标移动到 `^` 后(因为我要用 `yg_` 来选中,`yiw` 无法把字母和符号一起选中),输入 `"ayg_`,这时就修改完成可以再次愉快地继续使用宏操作 a 了 49 | 50 | ## 技巧 51 | 52 | 使用宏操作的过程中,我们有两点需要注意的: 53 | 54 | - 规范好光标的位置 55 | - 移录光标移动时使用相对位置 56 | 57 | 这两点其实都是为了确保光标在正确的位置以使宏操作可以按照它本应该的逻辑执行,避免发生意料之外的情况。 58 | -------------------------------------------------------------------------------- /docs/vim/day-18.md: -------------------------------------------------------------------------------- 1 | # 初出茅庐:调用 vscode 命令 2 | 3 | 经过这么多天的练习,相信大家对 vim 已经有了一定的了解;基本的常用命令,也已经不说熟悉也大概明了;作为 vim 章节的最后一节训练,我们会来探讨如何通过 vim 调用 vscode 的命令,以使我们在 vscode 中使用 vim 的过程中减淡操控的割裂感。 4 | 5 | :::tip 温馨提醒 6 | 本节提到的快捷键映射既为进一步的快捷键拓展,也是为了说明 vim 命令与 vscode 快捷键的如何融汇贯通,大家了解了映射原理后,就可尽情拓展自己的其他需求和场景的快捷键,举一反三才是最好的实践。 7 | ::: 8 | 9 | ## 从需求说起 10 | 11 | 在日常开发中,我们常常(可能)会有这几个需求: 12 | 13 | - 格式化文档 14 | - 重名名变量 15 | - 折叠代码 16 | 17 | 但是这几个“需求”,严格意义来说本来是不存在的;它们出现只是因为我们用了 vim;在我们还(大量)使用鼠标时,我们可以全选代码,然后右键格式化即可;折叠代码我们之间点行前的加减号就可以完成;或者有一些朋友之前已经很熟练使用这几个功能对应的 vscode 快捷键: 18 | 19 | - 格式化文档:`shift` + `alt` + `f` / `shift` + `option` + `f` 20 | - 重命名变量:`f2` 21 | - 折叠代码:`option` + `command` + '[' 22 | 23 | ## 使用 vim 调用 vscode 命令 24 | 25 | 虽然上面提到的 vscode 自带的快捷键已经可以实现对应的需求,但由于我们现在使用 vim 了,为了让组合按键更舒服,也为了降低记忆快捷键的心智负担,统一键位刻不容缓(夸张手法,其实看个人;你用的舒服其实不改也没有关系)。 26 | 27 | 我们先打开 vscode 的快捷键配置页面(非 json 文件;在 vscode 界面左下角齿轮按钮选项栏 - 键盘快捷方式或快捷键 `command + k + command + s` 打开),可以通过关键词搜索或组合键录制查找到格式化文档快捷键详细数据,在对应记录右键后选择 [复制命令 ID](copy command id),这时你复制到的内容其实是 `editor.action.formatDocument`,然后打开 vscode `setting.json`,配置如下内容: 28 | 29 | ```json 30 | "vim.normalModeKeyBindingsNonRecursive": [ 31 | ... 32 | { 33 | "before": ["", "f", "d"], 34 | "commands": ["editor.action.formatDocument"] 35 | } 36 | ... 37 | ] 38 | ``` 39 | 这就代表我们把 `` + `f` + `d` 映射成调用 vscode 的格式化文档命令 `editor.action.formatDocument`。 40 | 41 | 同理我们也可以把 `` + `[` 映射成折叠代码;但在使用折叠代码的命令时,我们会发现,折叠完代码后,一旦我们把光标往下移动,折叠的代码就又被展开了,这明显是不应当的;这时我们可以利用 vim 的 `$` 和 `%` 命令;即在折叠完后,我们把光标移到行尾所在的花括号(以 JavaScript 为例,即移到行尾的可闭合符号上),再使用 `%` 跳到另一侧的闭合符号,这样就可以避免展开折叠的代码块了。配置如下: 42 | 43 | ```json 44 | { 45 | "before": ["", "["], 46 | "commands": [ 47 | { 48 | "command": "editor.fold", 49 | }, 50 | { 51 | "command": "vim.remap", 52 | "args": { 53 | "after": ["$", "%"] 54 | } 55 | } 56 | ] 57 | } 58 | ``` 59 | 60 | 这样配置后,当我们使用 `` + `[` 折叠代码块时,折叠完后光标就在折叠后的代码块的后面了。同样的,重命名变量或其他的功能我们也可以重新映射新的快捷键。 61 | 62 | 在实际使用场景中,折叠代码的功能还是有许多其他问题,比如上面配置的命令是无法折叠 html 标签的;而 vim 中也有默认的折叠代码的命令(以下对应描述摘自官方文档,自译): 63 | 64 | `zc`:折叠光标所在的可折叠区域,如果前面加数字,则把该区域外的对应层数都折叠起来; 65 | `zC`:把光标所在的可折叠区域及其内部可折叠的内容递归地折叠起来; 66 | `za`:展开或折叠当前可折叠区域,折叠起区域时; 67 | `zA`:递归地展开或折叠当前可折叠区域; 68 | 69 | 这几个命令也是用于折叠或展开代码,而且它对 html 标签页同样起效,但按起来比较别扭,更重要的是折叠完后还是会遇到那个问题:我们光标一往下走进入被折叠起来的内容时,还是会把折叠起来的内容展开了。官方的建议是可以在 `setting.json` 中添加如下配置: 70 | 71 | ```json 72 | ... 73 | "vim.foldfix": true, 74 | ... 75 | ``` 76 | 77 | 但配置后会有一定副作用,比如笔者配置后出现使用 `shift` + `j` 和 `shift` + `k` 时光标出现延迟了(这两个组合键配置对应了 `5j` 和 `5k`),具体副作用可以参考官方 [issue](https://github.com/VSCodeVim/Vim/issues/2163)。 -------------------------------------------------------------------------------- /docs/vim/day-2.md: -------------------------------------------------------------------------------- 1 | # 小试牛刀:行相关命令 2 | 3 | 经过第一天的小试牛刀,这时候的你估计已经可以大概地操控光标了(可能还是不太习惯上下左右),但是不用担心,在接下来的每一天的训练里,你都会不断地重复巩固他们,直到它们变成你不假思索的动作。 4 | 5 | 今天,我们将更进一步,去学习更多更有用的操作;但在这之前,我想问你一个问题: 6 | 7 | - 昨天的训练中,你是否发现,`h` `j` `k` `l` 固然可以移动光标,但是在很多时候,他们移动的效率实在是太慢了...;想想,当光标是在一行中的末尾,你却要修改行首的字符时,这就要一顿好按才行。而今天,我们就来尝试解决这个问题 8 | 9 | ## 移动光标到行首 10 | 11 | 1. 移动到光标所在行的第一个字符:`0` 12 | 2. 移动到光标所在行的除 `blank` 字符外的第一个字符:`^` 13 | 14 | ## 移动光标到行尾 15 | 16 | 1. 移动到光标所在行的最后一个字符:`$` 17 | 2. 移动到光标所在行的除 `blank` 字符外的最后一个字符:`g _` 18 | 19 | ## 化繁为简 20 | 21 | 通过上面的四个操作,你就可以让你的光标快速去到行首行尾了;但是这时新的问题也随之而来,这四个操作,三个是需要击键两次,一个是需要那笨拙的右小拇指费劲按的键,光标的移动速度也一样是慢。这时我们就可以在 vscode 中对 vim 插件进行新键位映射,以简单化我们的使用;其中,`^` 和 `g _` 在开发中是很常用的,我们就对这两个操作进行重新映射。 22 | 23 | 在 `setting.json` 中添加设置: 24 | ```json 25 | "vim.normalModeKeyBindings": [ 26 | { 27 | "before": ["H"], 28 | "after": ["^"] 29 | }, 30 | { 31 | "before": ["L"], 32 | "after": ["g", "_"] 33 | } 34 | ], 35 | ``` 36 | 37 | 通过这样设置,我们就可以使用 `H` `L` 来达到和 `^` `g _` 一样的效果了;其中,这里的 `vim.normalModeKeyBindings` 是指在 vim Normal 模式即命令模式下的键映射,对于其他模式(如插入模式及后面会学到的可视化模式)是不起作用的。对于往后我们有其他的操作觉得比较复杂但是又常用的,也可以通过这种方式来添加自己的配置。 38 | 39 | ## 一简再简 40 | 41 | 通过键位的重新映射,总算是可以愉快地行首行尾快速输入了...吗? 42 | 43 | 并没有的。想想:光标跳到行首或行尾后,要输入字符的话,我们还是要再使用如 `i` `a` 这些操作指令,才能从命令模式进入输入模式;这时,我们就要请出新的操作命令了: 44 | 45 | 1. 在光标所在行行首插入(并进入输入模式):`I` 46 | 2. 在光标所在行行尾插入(并进入输入模式):`A` 47 | 3. 在光标所在行的上方插入空白行插入(并进入输入模式):`O` 48 | 4. 在光标所在行的下方插入空白行插入(并进入输入模式):`o` 49 | 50 | 通过这几个命令,我们就可以让光标快速跳到对应的位置并进入输入模式。 51 | 52 | ## three more thing 53 | 54 | 1. 复制光标所在行:`yy`;与系统的 `command + c` 不冲突,即如果先通过 `cmd + c` 复制一些内容,再通过 `yy` 复制一些内容,此时 `command + v` 快捷键粘贴出来的内容是 `command + c` 复制的内容而非 `yy` 复制的内容; 55 | 2. 粘贴:`p`;在 vim 中,有一个叫寄存器的概念,无论是 `y`(复制指令),还是 `d`(删除指令),`c`(删除并进入输入模式指令),被操作后的内容都会暂存在寄存器中,通过 `p` 指令则会把寄存器中的内容重新输出,从而达到粘贴的功能 56 | 3. 通过 `v` 可以选中内容,`h` `j` `k` `l` 调整选中区域,选中后通过 `y` 复制内容 57 | 58 | :::tip 提示 59 | 用完中文输入法后尽快切回英文模式 60 | ::: 61 | 62 | -------------------------------------------------------------------------------- /docs/vim/day-3.md: -------------------------------------------------------------------------------- 1 | # 更进一步:认识 vim 语法 2 | 经过前两天的练习,相信你对 vim 的感觉已经上来了;这时你就需要了解一下关于 vim 的语法知识,通过学习语法,你不仅仅可以把前面学习的内容进行复习和融会贯通,还能举一反三,更加明白 vim 的使用方法和功能。 3 | ## 语法 4 | vim 的语法主要指操作的组合,从而完成系列常用的操作。为 **操作 + 范围**。 5 | 6 | 1. 操作:如 `d`、`c`、`y` 7 | - `d`:删除 8 | - `c`:删除并进入 insert 模式 9 | - `y`:复制 10 | 2. 范围:如 `h`、`l`、`^`、`g _` 11 | 3. 搭配使用: 12 | - `d h`:删除当前光标前一个字符 13 | - `d j`:删除当前光标所在行和下一行 14 | - `d g _`:删除到行尾 15 | 16 | ## 基于单词的光标移动 17 | 18 | - `b`:光标跳到当前所在光标的单词开头,如果光标已在该单词的开头,则跳到下一个单词的开头 19 | - `e`:光标跳到当前所在光标的单词结尾,如果光标已在该单词的结尾,则跳到下一个单词的结尾 20 | - `w`:光标跳到下一个单词的开头 21 | - `g e`:光标跳到上一个单词的结尾 22 | 23 | ## 常用搭配 24 | 25 | - `d e`:删除到单词尾 26 | - `e a`:在当前单词后插入 27 | - `d w`:删除到下个单词前(`c w` 功能相同,但会保留下个单词前的空格) 28 | 29 | ## 拓展 30 | 31 | 1. `D` 删除到行尾(包括blank字符) 32 | 33 | :::warning 问题 34 | - `d ^`:删除到行首操作会有光标所在的字母没有删除到 35 | - `c w`:删除到下个单词前会保留下个单词前的空格,`d w` 则不会 36 | ::: 37 | 38 | ## 小训练 39 | 先敲出以下代码,然后修正以下代码中的错误单词、重复单词、错误格式、多余行,修改函数名为 typing 并为定时器添加 300 毫秒延迟 40 | ```js 41 | const bbb = () => { 42 | // this is is a description 43 | // 44 | // another descriptttion 45 | const timer = setTimeout(( ) => { 46 | console.log(that) alert('cool!') 47 | // awosome man ! 48 | }) 49 | } 50 | ``` -------------------------------------------------------------------------------- /docs/vim/day-4.md: -------------------------------------------------------------------------------- 1 | # 放慢脚步:删改重做,提升效率的新姿势 2 | 3 | 在日常使用中,我们有个功能是常常需要用到的,就是删除;前面我们学了 `d` `c` 这些指令,但是我们要进行删除一行中的某些字符时,要么得先用 `v` 选中内容然后 `d` 或 `c`,不然只能用键盘上的退格(删除)键。但是键盘的删除有几个问题: 4 | 5 | - 键盘的 Delete 按键太远,每次按都要移动手掌 6 | - 删除按键是单字符删除,删除效率低 7 | - 系统的删除与 vim 的配合不够契合 8 | 9 | 既然如此,我们来看看 vim 是如何解决这些问题的。 10 | 11 | ## 删除 12 | 13 | 对于删除,可以使用一下指令(命令模式中): 14 | 15 | - x:删除当前光标所在字符 16 | - X:删除当前光标所在字符的前一个字符 17 | - s:删除当前光标所在字符并进入 insert mode 18 | - S:删除当前光标所在行的除缩进外的所有内容并进入 insert mode 19 | 20 | ## 替换 21 | 22 | 对于有些情况下,我们可能要修改部分字符,比如修改某个函数的名称;虽然我们可以先删除,再重新键入,但是在 vim 中有更好的方法: 23 | 24 | - r + 字符:替换当前光标所在字符 25 | - R + 字符:替换当前光标开始的多个字符 26 | 27 | ## 撤销/重做 28 | 对于一些误操作,我们常常需要撤销或重做,大部分软件中都有这个操作,vim 也不例外: 29 | 30 | - `u`:撤销一次操作的内容 31 | :::info 提示 32 | normal mode => insert mode => normal mode 为一次操作,或在 insert mode 中进行了光标移动也会增加一次 33 | ::: 34 | - `ctrl + r`:重做 35 | 36 | ## 小训练 37 | 38 | ```js 39 | const bbb = () => { 40 | // this is is a description 41 | // 42 | // another descriptttion 43 | const timer = setTimeout(( ) => { 44 | console.log(that) alert('cool!') 45 | // awosome man ! 46 | }) 47 | } 48 | ``` -------------------------------------------------------------------------------- /docs/vim/day-5.md: -------------------------------------------------------------------------------- 1 | # 渐入佳境:认识可视化模式 2 | ## 可视化模式 3 | 4 | - 字符可视化模式(Characterwise visual mode):文本选择是以字符为单位,命令 `v` (命令模式下) 5 | - 行可视化模式(Linewise visual mode):文本选择是以行为单位,命令 `V` (命令模式下) 6 | - 块可视化模式(Blockwise visual mode):文本选择是以块为单位(非代码块,指一个矩形区域内的文本,多光标),命令 `Ctrl + v` (命令模式下) 7 | 8 | 通过以上三种方式进入可视化模式后,底部会显示 `-- visual --` 字样(vscode中);对于不同的可视化模式,可以直接输入另外两种可视化模式的命令直接切换模式,如 `v → V` 可以直接从字符可视化模式切换到行可视化模式,如此类推。 9 | 10 | **退出命令:** 11 | - `esc` / `Ctrl + [`:通用退出命令 12 | - `v` / `V` / `Ctrl + v`:使用某个命令进入了可视化模式则可以通过相同的命令退出,但是由于不同的可视化模式可以直接切换,所以如果切换多了自己可能也忘记是在哪个模式下了,所以推荐用通用退出命令 13 | 14 | ## 使用 15 | 16 | - `v` / `V` / `Ctrl + v` + 范围 / 位置:如 `v + e` 则是选中到单词结尾,诸如此类,可以搭配前面提到的 `w` `b` `h` `j` ... 等等的命令 17 | - 可视化模式下 `o`:切换光标位置,此时会在选中区域的头和尾之间切换 18 | 19 | ## 技巧 20 | 21 | - 多行修改:如果我们要统一修改多行的内容,可以用 `Ctrl + v` 选中多行后,通过 `I` 或 `A` 进行前插入或后插入 22 | - 通过可视化模式复制的内容,其实是暂存在了 vim 的寄存器中(`d` `c` 等操作其实也是,所以在 `d` 后,你也可以用 `p` 粘贴出来),而我们的 `command + c` 复制的内容则和 vim 无关,也就意味着,我们可以通过这两种不同的指令同时复制不同的内容而不会冲突,在某些场景下可以起到不错的辅助 23 | 24 | ## 拓展 25 | 26 | 还记得我们前面配置 `H` 和 `L` 来快速移动光标到行首行尾吗,在可视化模式中你会发现无法使用如 `vL` `vH` 这样的命令,这是因为我们 `H` `L` 的映射是在 normal mode 下的,我们需要在 vscode 的 `setting.json` 中添加如下配置: 27 | 28 | ```json 29 | "vim.visualModeKeyBindings": [ 30 | { 31 | 32 | "before": ["H"], 33 | "after": ["^"] 34 | }, 35 | { 36 | "before": ["L"], 37 | "after": ["g", "_"] 38 | }, 39 | { 40 | "before": ["J"], 41 | "after": ["5", "j"] 42 | }, 43 | { 44 | "before": ["K"], 45 | "after": ["5", "k"] 46 | } 47 | ], 48 | ``` 49 | ## 小练习 50 | 51 | ``` 52 | 1. 复制以下单词: 53 | 54 | javascript 55 | 56 | python 57 | 58 | java 59 | 60 | swift 61 | 62 | 2. 把以下所有句子的第一个单词改为 Just Vim It 63 | 64 | this is a simple easy vim tutorial 65 | this is a simple easy vim tutorial 66 | this is a simple easy vim tutorial 67 | this is a simple easy vim tutorial 68 | this is a simple easy vim tutorial 69 | this is a simple easy vim tutorial 70 | this is a simple easy vim tutorial 71 | this is a simple easy vim tutorial 72 | this is a simple easy vim tutorial 73 | 74 | ``` -------------------------------------------------------------------------------- /docs/vim/day-6.md: -------------------------------------------------------------------------------- 1 | # 继续深入:什么是文本对象? 2 | 3 | 在前面的训练中,我们学习了(比较)快速的删除 `X` `S`,以及选中文本 `v` 等指令,但在日常更多的使用中,我们常常是需要 4 | 5 | - 删除某些多余的变量 6 | - 复制某个单词 7 | - 删除被特定符号中包裹的某些内容,如 `()` `{}` `[]` 这些符号 8 | - 删除一段内容 9 | - ...等等等等 10 | 11 | 这时候之前的指令明显就不够用了。那就需要来认真认识一下 vim 的文本对象了。 12 | 13 | ## 文本对象 14 | 15 | 在 vim 中,文本是结构化的存在,即 **文本对象(text—object)**;而 vim 对于文本对象,专门有一部分语法,用于快速对文本对象进行编辑操作。 16 | 17 | ## 语法结构 18 | 19 | 文本对象的操作语法:**operater + 范围(内 / 外)+ 文本对象** 20 | 21 | - 内部:`i` ,意指 inner 22 | - 外部:`a` ,英文单词 a,一个的意思 23 | 24 | 可能看到这里,你会有点迷糊,没关系,我们下面会举例说明。 25 | 26 | ## 对象 27 | 28 | vim 中的文本对象主要有这一些: 29 | 30 | - `(` 或 `)` :一对 `()` 31 | - `b` :一对 `()` 32 | - `{` 或 `}` :一对 `{}` 33 | - `B` :一对 `{}` 34 | - `[` 或 `]` :一对 `[]` 35 | - `<` 或 `>` :一对 `<>` 36 | - `t` :tag (HTML 或 XML)标签 37 | - `'` 或 `'` :一对 `''` 38 | - `"` 或 `"` :一对 `""` 39 | - `` ` `` 或 `` ` `` :一对 ` `` ` 40 | - `w` :一个单词 41 | - `s` :一个句子;以 `.` `!` `?` 结尾即为一个句子 42 | - `p` :一个段落;以一个换行符间隔即为一个段落 43 | 44 | ## 组合举例 45 | 46 | 看了列举出来的文本对象后,可能你会更迷糊,那我们可以先来举个例子: 47 | 48 | - `viw`:`v` 是指选中, `i` 指内部, `w` 指一个单词,这个指令可以快速选中光标所在的单词,无论光标是在单词的前中后,都可以起效 49 | - `vi(`:`(` 指一个中括号,如果光标在一对括号里面,这个指令可以快速选中括号的内部内容(不包括括号本身),如 `('test')` 中的 `'test'`;同样的,`vi)` 或 `vib` 也是一样的效果 50 | - `va(`: 这个指令也可以选中括号内部的内容,并且会把括号本身也选中,如这 `('test')` 中使用这个指令,则会选中 `('test')`;这就是前面 `a` 被解释为外部的原因 51 | 52 | 相信看完这个例子,你应该大概能明白文本对象的使用方式了;对了,以上的 `v` 也可以换成 `d` `c`等操作符;这样下来,日常的使用中就更丝滑了! 53 | 54 | ## vim-textobj-arguments & vim-textobj-entire 55 | 56 | 在开始让你练习前,再提多一个内容:vim-textobj-arguments 与 vim-textobj-entire: 57 | 这是两个 vim 的插件,额外提供了两个文本对象 `a` 和 `e`,使用方式和上面提到的一样;`a` 具体的功能如下: 58 | 59 | ```js 60 | // Examples: 61 | // 删除一个参数 62 | function(arg1, ch) // 在第二个参数(即 “ ch”)中输入 daa 63 | function(arg1|) // 就会变成这样,| 代表这时光标所在位置;如果这时再输入 daa 64 | function(|) // 就会变成这样 65 | 66 | // 修改一个参数 67 | function(arg1, ch) // 在第二个参数(即 “ ch”)中输入 cia 68 | function(arg1, |) // 就会变成这样,| 代表这时光标所在位置 69 | ``` 70 | 71 | 以上可以看到在 文本对象 a 中,在他的前面接上表示范围的指令 a 和 i 时,它们的区别是是否包括前面的空格和符号(即当前参数外的内容)。所以规则如下: 72 | 73 | - `ia`:不包含分隔符 74 | - `aa`:包含分隔符 75 | 76 | `e` 在这里代表 entire ,即所有的意思;顾名思义,会针对当前文件所有内容左操作;规则如下: 77 | 78 | - `ae`:当前文本所有内容 79 | - `ie`:当前文本所有内容,但不包括前面和后面的 blank 字符 80 | 81 | 所以当我们要选中当前文件所有内容时,就可以直接用 `vie` ,其他删除复制也如此类推。 82 | 83 | ## 小练习 84 | 85 | 把以下被符号包裹的内容复制到符号外 86 | 87 | ``````js 88 | 'single quotation mark' 89 | "double quotation mark" 90 | [square bracket] 91 | {curly bracket} 92 | 93 | `backquote` 94 | ``` -------------------------------------------------------------------------------- /docs/vim/day-7.md: -------------------------------------------------------------------------------- 1 | # 快如闪电:让移动再次快起来 make move faster ~~again~~ 2 | 3 | 前面几天学到了光标一些的“快捷”移动方式,如 `hjkl` `b` `w` `e` 等等,但是在真实的使用中,他们的快捷确实是需要打上双引号,因为等我们打开动则上千行的 ~~屎山~~ 代码时,这些移动光标的方法就捉襟见肘了;这一节,我们就要祭出 vim 的一个大杀器,让我们的光标移动飞速起来! 4 | 5 | ## 给我滚! 6 | 7 | 先来看看让页面滚动起来的指令: 8 | 9 | - 向下滚动一屏:`ctrl + f` 10 | - 向上滚动一屏:`ctrl + b` 11 | - 向下滚动半屏:`ctrl + d` 12 | - 向上滚动半屏:`ctrl + u` 13 | - 向下滚动一行:`ctrl + e` , 光标不会移动,只是屏幕滚动 14 | - 向上滚动一行:`ctrl + y` , 光标不会移动,只是屏幕滚动 15 | 16 | 这时候,我们就可以愉快地在 ~~屎山~~ 代码中快速移动了。可是问题又来了,这几个指令动则半个屏幕移动,要不就一行行移,有没有在这些范围内的更适合平时使用的呢? 17 | 18 | 答案是:没有。 19 | 20 | 但不代表不可以,这时我们就要用老办法 -- 修改配置来达成需求了。 21 | 22 | 打开 vscode `setting.json`,在 `vim.visualModeKeyBindings` 和 `vim.normalModeKeyBindings` 中添加如下设置: 23 | 24 | ```json 25 | 26 | "vim.normalModeKeyBindings": [ 27 | ... 28 | { 29 | "before": ["J"], 30 | "after": ["5", "j"] 31 | }, 32 | { 33 | "before": ["K"], 34 | "after": ["5", "k"] 35 | } 36 | ... 37 | ], 38 | "vim.visualModeKeyBindings": [ 39 | ... 40 | { 41 | "before": ["J"], 42 | "after": ["5", "j"] 43 | }, 44 | { 45 | "before": ["K"], 46 | "after": ["5", "k"] 47 | } 48 | ... 49 | ], 50 | ``` 51 | 52 | 这里的配置是把 `J` `K` 映射成每次跳五行的效果,当然,如果你觉得不合适也可以根据自己的需求更改。配置完后,就可以在方便地跳转了。 53 | 54 | ## 光标位置 55 | 56 | 有时候在我们的光标移动到要编辑的行时,可能刚好这一行在屏幕的顶部或底部,或者需要跳转到文件的头或尾,这里有更快捷的指令: 57 | 58 | - 将当前行置于屏幕中央:`zz` 59 | - 将当前行置于屏幕顶部:`zt`,t 即 top 60 | - 将当前行置于屏幕底部:`zb`,b 即 bottom 61 | - 跳到文件首:`gg` 62 | - 跳到文件尾:`G` 63 | 64 | 如果是以上所有的命令都无法让你快速跳到要去的行,这时候就有一个终极方法: 65 | 66 | - 行数 + `gg` / `G`:跳到指定行;只要你知道行数,就可以准确无误地跳到那一行,在调试或查看报错位置时特别有用。比如跳到 1024 行,输入 `1024 gg`,这时候再搭配 `zz`,让当前行置于屏幕中间,然后就可以愉快 coding 了~ 67 | 68 | ## 小练习 69 | 70 | 这一天没有练习,去屎山里跳动吧!go and get it! 71 | -------------------------------------------------------------------------------- /docs/vim/day-8.md: -------------------------------------------------------------------------------- 1 | # 百发百中:掌握搜索命令 2 | 3 | 有一天,你终于厌倦了 `h` `j` `k` `l` 在字里行间移动,厌倦了 `w` `b` `e` 在 ~~屎山~~ 代码中半天跳不到头;你在想,有没有一种方法,可以像东风-41导弹一样指哪打哪,快速去到 ~~同事们写的垃圾~~ 代码中; 4 | 5 | 恭喜你,你找到了! 6 | 7 | 今天,我们就来学习搜索命令,打破你的困境。 8 | 9 | ## 行内搜索 10 | 11 | 通常我们在一行代码中时,有可能需要这里编辑一下那里编辑一下,虽然之前讲过的移动光标的命令也基本够用了,但可能在某些情况下,代码比较长之类的,可能用行内搜索命令是不错的方式。 12 | 13 | - `f` + 字符:自左往右移动光标到下一个匹配的字符中 14 | - `F` + 字符:自右往左移动光标到下一个匹配的字符中 15 | - `t` + 字符:自左往右移动光标到下一个匹配的字符的前一个字符中 16 | - `T` + 字符:自右往左移动光标到下一个匹配的字符的后一个字符中 17 | - `;`:重复执行上一个搜索命令 18 | - `,`: 与上一个命令方向相反地执行上一个搜索命令 19 | 20 | :::tip 使用技巧 21 | 普通移动光标的时候使用 `f` `F`,配合 `c` `d` `v` 这些操作时使用 `t` `T`,如: 22 | 23 | this is a simple easy vim tutorial. 24 | 25 | 如果我们光标在句首,需要跳到 easy 这个单词的字母 e,则直接 `fe;`即可(因为 `fe` 会跳到 simple 的 e,所以需要用 `;` 再执行一遍 `fe`); 26 | 27 | 而假如我们需要删除 easy 单词前的内容,则可以使用 `d2te` ,则句子就变成: 28 | 29 | easy vim tutorial. 30 | 31 | 这里的 `2te` 是指使用 `te` 这个指令时的第二个结果,因为上面那句话有两个字母 e,我们要匹配第二个,所以在这个指令前加上数字 2,指令 `f` 也同理。 32 | ::: 33 | 34 | ## 全局搜索 35 | 36 | 在日常开发中,我们用得最多的搜索其实是全局搜索,尤其是在查看一些变量、函数调用情况的时候,而 vim 也提供了方便的全局搜索: 37 | 38 | - 从光标位置向下查找:`/` + 字符 + enter 39 | - 从光标位置向上查找:`?` + 字符 + enter 40 | - 查看搜索历史:`/` + 上下方向键 41 | 42 | :::tip 使用技巧 43 | 使用 `/` `?` 查找时不需要输入要搜索的完整文本,就输入前面几个字符就可以了;而且这两个搜索命令是大写不敏感的,比如输入 `/ula,都可以匹配到 `ULA` 和 `ula`;这种特性下,如果我们搜索一个变量,如 `text`,会匹配到 `Text` `TEXT` 等单词,所以这两个命令是模糊搜索。 44 | ::: 45 | 46 | 在大多数情况下,其实我们更需要的是精确搜索,这时我们可以把光标移到我们需要搜索的单词上,然后按下以下命令: 47 | 48 | - 向上查找:`#` 49 | - 向下查找:`*` 50 | 51 | 这样就可以愉快地搜索了;我们还可以使用: 52 | 53 | - `n`:跳到下一个结果 54 | - `N`:跳到上一个结果 55 | 56 | 然后就可以快速查看搜索的结果了,完全不输 vscode 自带的搜索。 57 | -------------------------------------------------------------------------------- /docs/vim/day-9.md: -------------------------------------------------------------------------------- 1 | # 任意门:easymotion,让光标移动得随心所欲 2 | 3 | ## 插件:vim-easymotion 4 | 5 | vim-easymotion 的出现,是为了替代如要移动光标到下五行的 `5j`、后六个单词的 `5w` 这类的移动光标时要与数字混合的指令(因为数字键不好按),它通过一种更直观的方式去让我们更方便舒服地移动光标。 6 | 7 | ### 配置 8 | 9 | - 开启 vim-easymotion 插件 10 | - 改键:`` 改为 `space` 11 | :::tip 拓展 12 | 什么是 `` ? 13 | 14 | vim 中有很多快捷键,还有各种扩展插件,为了避免按键冲突以及丰富按键的组合,则推出了 `` 的概念,即前缀键或扩展组合键,通过配置 `` + 其他按键,来拓展出更多可用的组合键。 15 | ::: 16 | 17 | ### 指令 18 | 19 | - `` `` `w`:高亮光标后的所有单词的开头 20 | - `` `` `b`:高亮光标前的所有单词的开头 21 | - `` `` `e`:高亮光标后的所有单词的结尾 22 | - `` `` `ge`:高亮光标前的所有单词的结尾 23 | - `` `` `l`:高亮光标后的单词的开头和结尾、驼峰、`_` 或 `#` 之后的内容 24 | - `` `` `h`:高亮光标前的单词的开头和结尾、驼峰、`_` 或 `#` 之后的内容 25 | - `` `` `j`:高亮光标后的所有行的开头 26 | - `` `` `k`:高亮光标前的所有行的开头 27 | - `` `` `` `j`:高亮光标所有的单词的开头和结尾、驼峰、`_` 或 `#` 之后的内容 28 | 29 | ## 插件:vim-sneak 30 | 31 | vim 中的 `f` 命令后面只能跟一个字符,这样搜索的效率在实际场景中其实不高,而且它是行内搜索;为了弥补这些短板,就有了 vim-sneak。vim-sneak 使用 `s` `S` 操作符,后面可以接两个字符,并且是全局搜索,即当你搜索了一次之后,可以使用 `;` 不断的往下搜索相同的内容;为了使用更方便,我们可以直接把 `f` `F` 映射到 `s` `S`,这样在日常使用中就更方便了。 32 | 33 | ### 配置 34 | 35 | - 开启 vim.sneak 插件,在 vscode 的 `setting.json` 中添加: 36 | ```json 37 | "vim.sneak": "true" 38 | ``` 39 | 40 | - 添加改键映射: 41 | 42 | 首先配置 normal mode 下的 `f` `F` 映射为 vim-sneak 的 `s` `S`,这样映射后,为了让 `s` `S` 恢复为最原始的功能(删除光标所在字符并进入 insert mode;删除光标所在行从开头非 blank 字符到行尾的内容),需要把 `s` `S` 的原始功能用 `c` `C` 实现一下,而且由于在这个映射过程中,存在递归映射的情况(如 `f` → `s` → `c l`),所以要配置在 `vim.normalModeKeyBindingsNonRecursive` 中,遂在 vscode 的 `setting.json` 中添加: 43 | ```json 44 | "vim.normalModeKeyBindingsNonRecursive": [ 45 | ... 46 | { 47 | 48 | "after": ["s"] 49 | }, 50 | { 51 | "before": ["F"], 52 | "after": ["S"] 53 | }, 54 | { 55 | "before": ["s"], 56 | "after": ["c", "l"] 57 | }, 58 | { 59 | "before": ["S"], 60 | "after": ["^", "C"] 61 | }, 62 | ... 63 | ], 64 | 65 | ``` 66 | 67 | 配置完上面的设置后,我们就可以愉快地使用 `f` 或 `F` + 两个字符(或单字符 + 回车)在 normal mode 下进行搜索了,但是想在 visual mode 和 operater-pending 模式(即当输入了如 `d` `c` 等操作符后,vim 等待输入范围和文本对象时的状态,简而言之就是可以让 vim 支持如 `df` + 两个字符的这种操作,因为不配置的话在 operater-pending 模式中 vim-sneak 使用的是 `z` 操作符),则需要继续配置;并且在 visual mode 中,`F` 无法使用,遂只配置 `f`,配置如下: 68 | ```json 69 | "vim.visualModeKeyBindingsNonRecursive": [ 70 | { 71 | "before": ["f"], 72 | "after": ["s"] 73 | }, 74 | ], 75 | "vim.operatorPendingModeKeyBindingsNonRecursive": [ 76 | { 77 | "before": ["f"], 78 | "after": ["z"] 79 | }, 80 | { 81 | "before": ["F"], 82 | "after": ["Z"] 83 | }, 84 | ], 85 | ``` 86 | 87 | ## 小练习 88 | 89 | 建议在日常使用中直接练习,或者把本文复制到中 vscode 随便跳。 -------------------------------------------------------------------------------- /docs/vscode/day-19.md: -------------------------------------------------------------------------------- 1 | # 乘胜追击:文件与窗口基础操作 2 | 3 | vim 的部分已经结束,相信坚持到这里的朋友基本已经对 vim 有了基本(或更多)的了解,也已经可以在日常的开发中巴适地使用 vim 的操作命令来完成大部分的 coding 工作(如果你也是如我一般认真坚持了 18 天的话;我在到今天为止,在日常的 coding 中百分之 90 的时间双手是在键盘上的,而且随着对键位及快捷键的熟悉,coding 过程中的思维也愈加地集中,不容易被打断)。但是对于 vscode 来说,vim 是服务于或优势于编辑,而更多地对于 vscode 的使用操作,我们当然也是应该去学习、掌握,这样才可以让 vscode 之中 vim 之外的部分使用得更加丝滑。 4 | 5 | 既然如此,我们就乘胜追击,了解更多关于 vscode 本身的操作命令、快捷键。 6 | 7 | ## 窗口焦点切换 8 | 9 | 在[之前的课程](../vim/day-15.md)中,我们学习了 vim 的窗口管理的一些命令,当光标在编辑窗口时,我们通过 `shift` + `ctrl` + `h` / `l` 来使光标在左右窗口移动焦点,不过在使用的过程中这个快捷键还是比较不顺手,毕竟要按三个键,而且 vim 的命令只能在编辑窗使用,如果我们当前焦点在终端这类的时候,就无法使用 vim 的命令切换焦点了;而对于我们日常来说,需要聚焦到侧边的资源管理器的情况是很常有的,我们急需一个更方便好用的组合键达到这个目的;而 vscode 中,其实是有这个快捷键的,就是 `shift` + `command` + `e`,既然如此,在结合我们[前面](../vim/day-18.md)提到的方式,如此这般,就可以在 `keybindings.json` 中映射: 10 | 11 | ```json 12 | ... 13 | { 14 | "key": "ctrl+;", 15 | "command": "workbench.view.explorer", // `shift` + `command` + `e` 组合键对应的 命令ID(Command ID) 16 | } 17 | ... 18 | ``` 19 | 20 | 这样,我们就可以在任何时候都可以快速地聚焦到资源管理器了。与之相同的,聚焦编辑窗也是与聚焦资源管理器一样甚至更大的需求,同样 vscode 原本也有这个功能的组合键,就是 `command` + `1` (workbench.action.focusFirstEditorGroup),我们也可以把它重新映射一下: 21 | 22 | ```json 23 | { 24 | "key": "ctrl+'", 25 | "command": "workbench.action.focusFirstEditorGroup", 26 | } 27 | ``` 28 | 29 | 这样,我们就可以在任何时候快速聚焦到编辑窗中了。 30 | 31 | :::tip 我的做法 32 | 其实配置完 `ctrl` + `;` 后你会发现,当焦点在资源管理器时,如果使用这个快捷键,焦点会跳到编辑窗,这就意味着我们可以使用这个快捷键在这两个区域切换焦点;这时你可能会问,那终端与其他部分的焦点切换呢?我的做法是不用 vscode 的终端,直接打开自带的命令行工具或自己的其他命令行工具(比如我用 warp),一劳永逸,所有在跑的项目都在同一个地方查看,更方便管理。 33 | 34 | 去 TM 的终端! 35 | ::: 36 | 37 | ## 移动光标与查看 38 | 39 | 在我们习惯了 vim 的 `hjkl` 后,在资源管理器中上下切换文件焦点是很简单并且自然而然的事情。 40 | 41 | - `jk`:上下切换文件焦点 42 | - `h`:聚焦当前文件所在的文件夹并且折叠收起该文件夹 43 | - `l`:在编辑窗打开该文件 44 | 45 | ## 文件操作 46 | 47 | 在日常使用中,我们常常需要新建文件或者文件夹;而对于我们使用了 vim 的 vscode,又可以分成三个不同的情况: 48 | 49 | - 聚焦在资源管理器时:此时,我们可以配置个快捷键来新建文件或文件夹,在 `keybindings.json` 添加: 50 | 51 | ```json 52 | ... 53 | { 54 | "key": "a", // 新建文件 55 | "command": "explorer.newFile", 56 | "when": "filesExplorerFocus && !inputFocus" 57 | }, 58 | { 59 | "key": "shift+a", // 新建文件夹 60 | "command": "explorer.newFolder", 61 | "when": "filesExplorerFocus && !inputFocus" 62 | }, 63 | ... 64 | ``` 65 | 66 | 这里的 `when` 条件其实是指:当前的 vscode 焦点要在侧边栏的资源管理器中,且不是在输入框聚焦的情况下;后者是为了限制在编辑文件或文件夹名称时这两快捷键不可触发。 67 | 68 | - 聚焦在编辑窗时:此时我们可以在 `setting.json` 配置如下组合键来达到同样效果: 69 | 70 | ```json 71 | "vim.normalModeKeyBindingsNonRecursive": [ 72 | ... 73 | { 74 | "before": ["", "n", "d"], 75 | "commands": ["explorer.newFolder"] 76 | }, 77 | { 78 | "before": ["", "n", "f"], 79 | "commands": ["explorer.newFile"] 80 | }, 81 | ... 82 | ] 83 | ``` 84 | 85 | - 除了以上两种情况时:而除了使用前面两种方式,vscode 也提供一个全局新建文件的命令 `command` + `n`,这时会新建一个没有扩展名的空白文件,而且只能在保存时才能把文件保存到想要的路径下。 86 | 87 | 除了新建,删除和重命名也有对应的快捷键(聚焦资源管理器并选中): 88 | 89 | - `command` + `delete`:删除文件 90 | - `enter`:重命名文件 91 | 92 | 并且这两个文件都是 vscode 自带的,我们不需要配置新的映射。 -------------------------------------------------------------------------------- /docs/vscode/day-20.md: -------------------------------------------------------------------------------- 1 | # 似曾相识:vscode 多窗口操作 2 | 3 | 前面我们学习了不少关于“窗口”的操作,基本都是对于资源管理器、编辑窗之类的,今天我们来学习一下多个 vscode 窗口时的一些操作命令。 4 | 5 | ## 新建窗口 6 | 7 | 在开发中,我们可能要同时打开多个项目,这时候就需要创建一个新的 vscode 窗口,而对于 window 和 mac 系统,新建窗口的快捷键分别是: 8 | 9 | - MacOS:`shift` + `command` + `n`;(不要和新建文件 `command` + `n` 记混了) 10 | - Window:`shift` + `ctrl` + `n` 11 | 12 | ## 选择工作区 13 | 14 | 新建了窗口之后,是空白窗口;则需要为当前窗口选择一个工作区(即我们的项目),此时通过 `ctrl` + `r` 可以显示最近打开过的工作区(项目);选中一个工作区,即可打开。 15 | 16 | :::tip 切换工作区 17 | `ctrl` + `r` 是一个 vscode 的全局命令,即意味着我们在任何时候都可以通过它来切换当前窗口打开的工作区;但在你实践的时候你可能会发现,聚焦在编辑窗时是无法触发 `ctrl` + `r` 的,这是因为我们使用了 vim;这时只要你聚焦到资源管理器或其他地方,或把所有已打开的编辑窗关闭,即可使用该命令。 18 | ::: 19 | 20 | ## 多窗口切换 21 | 22 | 打开多个 vscode 窗口的时候,我们可以通过 `command` + `` ` `` 来切换不同的工作区窗口。这个快捷键在大部分软件中效果都是如此,如 Chrome 。 23 | 24 | ## 关闭窗口 25 | 26 | 和切换窗口一样,关闭窗口的快捷键 `shift` + `command` + `w` 在大部分软件中也是一样的效果 (`command` + `w` 则是关闭当前激活的编辑窗,即当前右边显示的编辑窗)。而 Window 系统则是使用 `shift` + `ctrl` + `w`。 27 | 28 | -------------------------------------------------------------------------------- /docs/vscode/day-21.md: -------------------------------------------------------------------------------- 1 | # 踏破铁鞋:vscode 的全局搜索命令 2 | 3 | 前面的训练中,我们学习了 [vim 的搜索命令](../vim/day-8.md) 以及 [vim-sneak](../vim/day-9.md#插件:vim-sneak);可以说掌握了这两个基本上在单个文件内进行搜索可以得心应手。 4 | 5 | 但在日常的开发中,我们常常也需要全局地去搜索内容,尤其在你的同事写的~~屎山~~代码中各种方法文件满天飞的时候;vim 无法提供一个这样全局搜索的命令,并且这样的命令也不应该在 vim 上进行,而应该在当前所使用的 IDE 中进行,所以今天我们就来了解一下 vscode 的全局搜索命令(我假设你用的是 vscode,因为我用的 vscode)。 6 | 7 | ## 全局搜索 8 | 9 | 通过 `shift` + `command` + `f` 可以激活全局搜索面板并聚焦到搜索框;如果此时在编辑窗里有选中文本,会直接触发全局搜索该文本。 10 | 11 | 在全局搜索面板移动光标时,略微会有点麻烦;全局搜索面板有多个输入框,输入框区域从上往下是关键词输入框、包含的文件输入框和排除的文件输入框;输入区域下方是结果列表。当我们聚焦搜索面板的时候,可以使用如下快捷键: 12 | 13 | - `command` + [方向键]:在输入框区域的输入框直接切换焦点 14 | - `shift` + `command` + `j`:展开 / 隐藏输入框区域,隐藏时只有关键词输入框,展开则显示所有输入框 15 | - `j` / `k` / `h` / `l`:功能和[资源管理器](./day-19.md#移动光标与查看)一致 16 | 17 | 当我们在搜索结果列表中按下 `l` 打开对应文件后,也可以通过 vim 的[窗口焦点切换命令](../vim/day-15.md#窗口切换)切换回结果列表。 18 | 19 | ## 快捷搜索符号 20 | 21 | 这里的符号是指如变量名、方法名之类的(下同)。开发中我们常常需要查看一些方法、变量在何处声明;虽然我们可以通过 vim 的搜索来进行当文件内搜索,也可以通过全局搜索进行整个工作区搜索;但是这样搜索出来的结果会比较混乱,不仅仅不会区分声明处还是调用处,而且可能一些同名的非变量的字符串也会被搜索出来,而且也不便于区分类型;所以 vscode 提供了一种更适合这种场景的快捷键。 22 | 23 | ### 工作区搜索符号 24 | 25 | 通过 `command` + `t`,可以在当前工作区中查找当前光标所在的变量的所有同名变量的声明位置(即如果在多个文件中有同名变量,也会显示出来。而且会有不同的图标区分变量还是方法,并可以直接进行文件跳转),也可以在输入框中输入字符进行搜索(此时输入框带 `#` 前缀)。 26 | ### 单文件搜索符号 27 | 28 | 键入 `shift` + `command` + `o` 会激活符号搜索(此时输入框带 `@` 前缀),此时可以在当前文件搜索所有与输入的关键词相关的符号;如果在 `@` 后输入 `:`,还会把搜索到的结果分门别类,区分变量、方法、类型等等;聚焦列表不同项还会直接跳到对应位置。 29 | 30 | ## 文件查找与切换 31 | 32 | 有时我们想要打开一个文件,我们知道它的文件名,有不想在侧边栏海量的文件中查找,则可以直接通过 `command` + `p` 调出输入框,输入文件名即可查找和跳转。而切换最近打开的两个文件则是由 mac 通用的快捷键 `ctrl` + `tab` 可以达到;这个快捷键在 chrome 、warp 等可打开多窗的软件也是同样的效果。 33 | 34 | ## 查找命令 35 | 36 | 在日常中,尤其最近学习 vim,我们常常要配快捷键或查找快捷键,用鼠标点点点肯定不符合键盘侠的调性;我们可以通过 `command` + `shift` + `p` 打开命令搜索框(此时输入框带 `>` 前缀),就可以查找 vscode 的命令了;比如我们要找关于 git 的命令,则可以输入 git 查看相关命令(关于 git 的命令确实可以提前去了解一下,因为过两天的训练就有关它)。 37 | 38 | :::tip command + p 妙用 39 | 输入 `command` + `p` 后会在最上方弹出输入框,分别输入 `@` 、`#`、`>` 等符号,即可达到上面提到的功能;本质上是一样的。 40 | ::: -------------------------------------------------------------------------------- /docs/vscode/day-22.md: -------------------------------------------------------------------------------- 1 | # 先利其器:vscode 开发常用小技巧 2 | 3 | 论语有曰:“工欲善其事,必先利其器”。而对于我们开发用的 “器” ———— vscode (或其他 whatever),我们要会了解怎么使用它,才能把它变成一个利器。 4 | 5 | 故而我们今天来了解一下 vscode 在开发中的一些使用小技巧,虽然它们很 “小”,但却与我们的日常开发息息相关。 6 | 7 | ## 代码提示命令 8 | 9 | ### 显示代码操作 10 | 11 | 我们在前面的训练中了解到了如何通过 vim 的命令模仿鼠标划过激活悬浮提示,但还有一种情况我们没有说:当我们输入一些有问题的代码语法比如未引入的模块函数,该行的行首会有个小灯泡移入会有 “显示代码操作” 字样(英文为 `show code action`),点击会有待选框弹出让我们可以快速导入(如果检测到项目中的其他模块有同名的模块),这就是我们常常会看到和用到的 [代码操作] 选项框(在鼠标划过的悬浮提示框底部带有可点击的 "快速修复 quick fix" 字样也同样会激活 [代码操作]); 12 | 13 | 但是对于键盘侠的我们,怎么能忍得了用鼠标点点点呢?可能你已经注意到,无论是在小灯泡提示的 “显示代码操作” 的旁边,还是 “快速修复” 的旁边,其实已经标明了这里要讲的快捷键:`command` + `.`;这时候只要我们按下该组合键,可以激活 [代码操作] 待选框。 14 | 15 | 而在后面的关于[重构]的章节中,我们会更加详细地学习和拓展这个[快速修复]这个功能。 16 | 17 | :::tip 代码操作 Code action 18 | vscode 文档中提到: 19 | Code Actions = Quick Fixes and refactorings 20 | 即:代码操作是快速修复功能和重构功能;快速修复功能涵盖了许多内容,如导入模块、添加行内 eslint 跳过检查注释等。 21 | ::: 22 | 23 | ### 触发参数提示 24 | 25 | 在我们使用一个已声明的函数或类时,vscode 会提示对应的入参、参数类型等(在输入时);但如果我们不小心移动了光标或点击了其他地方再回到传参的位置时,提示就没有了,这时我们可以通过 `shift` + `command` + `space` 触发参数提示(trigger parameter hints)。 26 | 27 | ### 触发建议 28 | 29 | 众所周知,vscode 有代码提示的功能,比如我们输入个 `con`,会提示 `console.log`,但是一旦想上面那样光标移动之类的情况发生,提示框也是会消失;当然,你可以把已经输入的字符删除一下再重新输入,提示框就会重新出现(我之前就是这么做的...),但这确实挺~~傻逼~~费劲的;这时我们只要用上触发建议(trigger suggestion)的快捷键 `command` + `i`,提示框就出现了;是不是白费劲了这么久才知道这个方式? 30 | 31 | :::tip 区分好 action 与 hints 与 suggestion 32 | action 会针对代码进行一定的修改等操作,比如提取为函数,命名为新变量,导入模块等; 33 | hints 是针对已有的代码内容做一个提示,仅显示而无操作; 34 | suggestiton 则会根据当前的代码中可以输入的内容及当前已输入的内容分析出一系列可供参考及选中快速输入的待选列表。 35 | ::: 36 | 37 | ## 行操作命令 38 | 39 | 有没有遇到这两个问题: 40 | 41 | 在之前的 vim 训练中,我们如果要移动一行代码可能会使用 `dd` 和 `p`,本质上是删除对应行再粘贴,来达到移动的效果,看起来还行但是总是缺点优雅的感觉,也比较反常识;以及我们在要在当前行上 / 下方新建空白行时使用的 `O` / `o`,新建空行后就进入了 insert mode;虽说一般新建行后是进行输入,但是比如我们要粘贴点 vim 寄存器中的内容时,又要重新退出 insert mode,确实有点多此一举。 42 | 43 | 而其实 vscode 中,对于这样的行操作默认就有对应的操作组合键: 44 | 45 | - `option` + [上 / 下方向键]:上 / 下移动所在行,或选中区域 46 | - `command` + `enter` / `shift` + `command` + `enter`:在当前行上 / 下方新建空白行 47 | 48 | :::tip mac 中的 `shift` 49 | 在 MacOS 中,`shift` 在组合键中常常起到类似“取反”的作用;比如 `chrome` 中:`shift` + `tab` 是切换到下一个标签页,而 `shift` + `tab` + `shift` (左右 `shift` 都用上),则是切换到上一个标签页;再如 `command` + `tab` 是切换到下一个应用,而 `command` + `shift` + `tab` 则是切换到上一个应用。这样的例子还有很多,平时可以多留意。 50 | ::: 51 | 52 | ## 删除前面的单词 53 | 54 | 在 vim 中提到删除单词,我们肯定是无脑 `diw` 或 `ciw` 的,当然这也是涵盖了所有的场景的删除单词;不过可能有时候有些人会想着,如果可以快速删除光标前的单词,那我岂不是不用移动光标了?虽然 vim 给不了你这样的功能,但是 VScode 可以。 55 | 56 | - `option` + `delete`:删除光标前的单词(一个文本块为一个单词,如 `vimUser` 这里为一个单词) 57 | - `option` + `control` + `delete`:删除光标前的单词(以驼峰为单词的区分,如 `vimUser` 这里为两个单词) 58 | 59 | ## 跳转错误处 60 | 61 | 通过 `f8` 可以跳转到代码报错飘红的位置,而且范围是整个工作区而不仅仅是当前文件;存在多个报错处的时 `f8` 可以跳往下一处,`shift` + `f8` 可以跳往上一处。 62 | 63 | ## 选中所有相同单词 64 | 65 | 虽然 vim 中的 `gb` 可以选中相同的单词,在选中某几个的时候还比较好用,如果相同单词过多并且数量比较多的情况下,就需要键入很多次,而通过 `command` + `f2` 则可以快速选中所有相同单词。 66 | 67 | -------------------------------------------------------------------------------- /docs/vscode/day-23.md: -------------------------------------------------------------------------------- 1 | # 举一反三:vscode 挖掘快捷键场景 2 | 3 | ## 切换侧边栏 4 | 5 | ## live server 6 | 7 | ## 预览 markdown 8 | 9 | ## 显示插件窗口 10 | 11 | ## 文件操作 -------------------------------------------------------------------------------- /docs/vscode/day-24.md: -------------------------------------------------------------------------------- 1 | # 雁过留痕:vscode git 常用操作 2 | 3 | ## 显示源代码面板 4 | 5 | 源代码面板(source control panel) 6 | 7 | ## 暂存更改 stage change 8 | 9 | ## 提交 commit 10 | 11 | ## 比较 diff 12 | 13 | ## 撤销暂存 unstage change 14 | 15 | ## 撤销更改 discard change 16 | 17 | ## 插件 18 | 19 | - edamgit 20 | - gitmoji 21 | - lazygit -------------------------------------------------------------------------------- /docs/vscode/day-25.md: -------------------------------------------------------------------------------- 1 | # 以一打十:Snippet 代码片段 2 | 3 | 你是否厌倦了每次新建个 vue 文件、react 文件是每次重复输入的 `template`、`script`、`style`,是否厌倦了每次命名个函数来来去去地敲 `function shitInput() {}` ;诸如此类的这种重复输入一天的~~屎山~~ coding 下来,重复写的内容占据了相当一部分的时间;都 21 世纪了,我们能不能把这种重复的劳动浪费的时间节省下来摸鱼呢?那,就要看今天的主角 ———— Snippet 了! 4 | 5 | ## Snippet 6 | 7 | Snippet 即代码片段;在 vscode 中我们可以利用代码片段通过代码提示快速地输入固定的一些代码模版,方便我们输入一些重复、常用的代码片段。 8 | 9 | ## vscode Snippet 插件 10 | 11 | vscode 中常用的前端开发 snippet 插件有: 12 | 13 | - [JavaScript (ES6) code snippets](https://marketplace.visualstudio.com/items?itemName=xabikos.JavaScriptSnippets) 14 | - [Vue 3 Snippets](https://marketplace.visualstudio.com/items?itemName=hollowtree.vue-snippets) 15 | - [Vue VSCode Snippets](https://marketplace.visualstudio.com/items?itemName=sdras.vue-vscode-snippets) 16 | 17 | 当然,你也可以根据自己的需求安装其他如 `html`、`css`、`markdown`、`python` 等语言的 snippet 插件。 18 | 19 | ## 常用 Snippet 指令 20 | 21 | 由于 vscode 会识别我们输入的字符进行代码提示,当我们安装了 snippet 插件后,一些代码块则会在我们输入到对应简写文本时在代码提示中出现以供选择;当我们安装了上面提到的几个插件后,会有如下一些简写提示代码指令: 22 | 23 | - `imp`:对应 `import second from 'first'` 24 | - `imd`:对应 `import { second } from 'first'` 25 | - `fn`:对应创建一个函数 26 | - `log`:对应 `console.log()` 27 | - `vue`:对应创建 `vue` 文件模版 28 | - `anfn`:`对应创建一个箭头函数` 29 | - `rp`:对应 `return new Promise()` 30 | 31 | 比如使用 `imp` 时,在选择了代码提示的代码块后,会输出 `import second from 'first|'`,`|` 代表当前光标所在位置,且此时 `first` 处于选中状态,我们可以直接键入要引入的内容所在的包名或路径;输入后(或不输入也没有关系)我们按下 `tab`,则光标会跳到 `second|`,且此时它也是处于选中状态,我们就可以输入导入的名称;其他简写也是如此。 32 | 33 | :::技巧 34 | 如上面提到,`tab` 可以在代码块的占位光标中切换;另外一种情况是:有时候我们输入文本时,比如 `imp`,输入后可能不小心移动了光标或者切换了窗口,导致代码提示没有了,此时我们可以通过 `command` + `.`(用 `ctrl` + `space` 也可以,不过这个是 MacOS 默认输入法切换组合键,所以一般不用这个)重新使代码提示框显示。 35 | ::: 36 | 37 | ## 配置自己的 Snippet 38 | 39 | 既然插件可以配置一些供我们选择的代码块,那就意味着我们也可以自己配置专属自己的代码块;因为自己永远是最了解自己的。比如我在日常调试中常常需要输出一些变量、描述等内容来辨别一些逻辑是否正确。可是在公司的~~屎山~~项目中输出的除了我自己写的,还有很多其他人的输出,我常常无法找到我添加的输出。为此我在使用 `console.log()` 时会通过设置颜色代码来让我自己的输出更显眼。但是每次都手敲颜色设置,就非常麻烦;既然如此,我就为自己配置了一个专属的 color log snippet; 40 | 41 | 首先我们[打开命令查找框](./day-21.md#查找命令),输入 `user snippet`,即查找当前用户自定义的 snippet,会有配置用户代码片段(configure user snippet)选项;选择它,会有如下选项: 42 | 43 | - 新建全局代码片段文件 44 | - 新建当前工作区的代码片段文件 45 | - 为特定特定语言配置代码块;如 `javascript`、`c#` 等等 46 | 47 | 如果你已经配置过自定义的代码块,也会显示对应的配置文件名;此时我们选择第一个;输入要生成的文件名后,就进入了配置文件中。vscode 官方 snippet 配置规则文档在[这里](https://code.visualstudio.com/docs/editor/userdefinedsnippets)。于是乎,我根据上面的自己的需求,配置了一个自己的 snippet: 48 | 49 | ```json 50 | { 51 | "color log": { 52 | "scope": "javascript,typescript", 53 | "prefix": "ccl", 54 | "body": [ 55 | "console.log('%c $1', 'color: ${2|red,blue,green|}')", 56 | "$3" 57 | ] 58 | } 59 | } 60 | ``` 61 | 62 | 其中,`$` + [数字] 是指按下 `tab` 时光标跳转的顺序;而 `${[数字]|[文本],[文本],[文本]|}` 是指光标跳到该位置时除了输入也可以直接选择提供的 [文本] 选项;所以这个 snippet 的效果如下: 63 | 64 | ![color log](https://pic.imgdb.cn/item/62bf024d1d64b070667113c4.gif) 65 | 66 | 置于其他的一些灵活配置,大家可以直接看文档,都有详细说明。 -------------------------------------------------------------------------------- /docs/vscode/day-26.md: -------------------------------------------------------------------------------- 1 | # 改头换面:代码重构工具 -------------------------------------------------------------------------------- /docs/vscode/day-27.md: -------------------------------------------------------------------------------- 1 | # 包罗万键:VSpaceCode 插件 2 | 3 | 训练进行到这里,大部分日常的使用场景和功能我们基本都配置了对应的一些快捷键,或者知道如何不通过鼠标去达到目的;而今天我们来了解学习 VSpaceCode 插件,通过它,可以让我们的组合键覆盖得更广阔全面。至于怎么个覆盖,装完插件再慢慢道来。 4 | 5 | :::tip VSpaceCode 与 Whichkey 6 | 二者是同一家出品,而且功能上基本一致;VSpaceCode 插件主要面向 Vim 使用者;而 Whichkey 更适用于普通用户; 7 | 而且他们的[文档](https://vspacecode.github.io/docs/)也已经合并在一起。 8 | ::: 9 | 10 | ## 安装及初始配置 11 | [点击直达下载](https://marketplace.visualstudio.com/items?itemName=VSpaceCode.vspacecode)或在 vscode 的拓展中搜索 `VSpaceCode` 安装; 12 | 13 | 安装完后,查看[文档](https://vspacecode.github.io/docs/#manual-configuration-optional),可以发现文档中提到了两个配置文件 [`setting.jsonc`](https://github.com/VSpaceCode/VSpaceCode/blob/master/src/configuration/settings.jsonc) 与 [`keybindings.jsonc`](https://github.com/VSpaceCode/VSpaceCode/blob/master/src/configuration/keybindings.jsonc);分别对应了 vim 中绑定 VSpaceCode 的激活命令以及在 vscode 中编辑窗之外的其他窗口 VSpaceCode 的激活命令;当然除了激活命令之外,我们还可以看到文档的这两个文件里面都配置了很多命令,其实都是一些扩展了其他功能的命令,我们暂时不需要,所以可以先不配置;而可以看到,两个文件中默认的激活命令是: 14 | 15 | ```jsonc 16 | // keybinds.jsonc 17 | { 18 | "key": "space", 19 | "command": "vspacecode.space", 20 | "when": "activeEditorGroupEmpty && focusedView == '' && !whichkeyActive && !inputFocus" 21 | }, 22 | ``` 23 | 24 | ```jsonc 25 | // setting.jsonc 26 | "vim.normalModeKeyBindingsNonRecursive": [ 27 | { 28 | "before": [""], 29 | "commands": ["vspacecode.space"] 30 | }, 31 | ], 32 | "vim.visualModeKeyBindingsNonRecursive": [ 33 | { 34 | "before": [""], 35 | "commands": ["vspacecode.space"] 36 | }, 37 | ] 38 | ``` 39 | 40 | 可以看到,默认的配置是使用空格激活;但是我们配置的 vim 的 `` 也是 `space` 键(如果你和我一样的配置,如果不是则无需接下来的改键),这时候我们就要重新配置激活按键,而我改成了 `space` + `;`,这样的按起来也比较顺手。如下: 41 | 42 | ```jsonc 43 | // keybinds.jsonc 44 | { 45 | "key": "space+;", 46 | "command": "vspacecode.space", 47 | "when": "activeEditorGroupEmpty && focusedView == '' && !whichkeyActive && !inputFocus" 48 | }, 49 | // Trigger vspacecode when sidebar is in focus 50 | { 51 | "key": "space+;", 52 | "command": "vspacecode.space", 53 | "when": "sideBarFocus && !inputFocus && !whichkeyActive" 54 | }, 55 | ``` 56 | 57 | ```jsonc 58 | // setting.jsonc 59 | "vim.normalModeKeyBindingsNonRecursive": [ 60 | { 61 | "before": ["", ";"], 62 | "commands": ["vspacecode.space"] 63 | }, 64 | ], 65 | "vim.visualModeKeyBindingsNonRecursive": [ 66 | { 67 | "before": ["", ";"], 68 | "commands": ["vspacecode.space"] 69 | }, 70 | ] 71 | ``` 72 | 73 | 这样我们就可以愉快地使用 VSpaceCode 了。 74 | 75 | 现在我们激活它,会在 vscode 上面弹出输入框,并且在待选列表中有很多功能,每条记录都有一个符号前缀,在键盘上输入该前缀,就可进入该功能;比如激活插件后我们输入 `g`,则进入了 `git` 的功能模块中,则会列出可执行的操作,继续点击对应操作的前缀,则可以执行该操作;这就是 VSpaceCode 的使用逻辑。简单来说就是我们可以通过所见即所点的模式进行纯键盘的操作(和 chrome 的 vim 插件 vimium-c 一样的思想)。 76 | 77 | ## 修改原有配置 78 | 79 | 虽然 VSpaceCode 提供一整套的规则,但每个人都有自己的一些个人习惯和喜好,而 VSpaceCode 当然也提供了重写和新增命令的方式。 80 | 81 | ### 重写已有命令 82 | 83 | VSpaceCode 提供了个配置项 `vspacecode.bindingOverrides`,通过这个配置可以重写已有的一些命令;比如我们我们触发 VSpaceCode,可以看到 `g` 选项为 Git 的操作,`g` 里面的 `s` 选项为 `status`,即 Git 查看状态命令;而如果我们要把这个命令改为跳转到某行(go to line)的功能,我们可以在 VSCode 的 `setting.json` 中如此配置: 84 | 85 | ```json 86 | "vspacecode.bindingOverrides": [ 87 | ... 88 | { 89 | "keys": "g.s", // 指 g 选项中的 s 命令 90 | "name": "Go To Line", // 在弹出的 VSpaceCode 的 g 中的 s 选项中显示的名称 91 | "type": "command", 92 | "command": "workbench.action.gotoline", // VScode 跳转行的命令 id 93 | } 94 | ... 95 | ] 96 | ``` 97 | 98 | 这样,原来的 `g` 中的 `s` 对应的功能就被重写了。 99 | 100 | 而如果我们要重写整个 `g` 的模块也是类似: 101 | 102 | ```json 103 | "vspacecode.bindingOverrides": [ 104 | ... 105 | { 106 | "keys": "g", // 指要重新 g 选项 107 | "name": "Go...", // 在弹出的 VSpaceCode 的 g 选项中显示的名称 108 | "type": "bindings", // 对应下面的 bindings,即 g 命令下的子级命令 109 | "bindings": [ 110 | { 111 | "key": "g", // 指 g 选项的子级有一个 g 命令 112 | "name": "Go To", // 在弹出的 VSpaceCode 的 g 中的 g 选项中显示的名称 113 | "type": "command", 114 | "command": "workbench.action.gotoline", // VScode 跳转行的命令 id 115 | } 116 | ] 117 | } 118 | ... 119 | ] 120 | ``` 121 | 122 | 这样配完后,我们激活 VSpaceCode 时,它的 `g` 对应就是我们的新功能 `Go...`,进入该选项里面只有一个子命令 `g`,对应 `Go To`。 123 | 124 | ### 增加命令 125 | 126 | 增加命令也是和重写类似,VSpaceCode 提供的配置字段为 `vspacecode.bindings`,而且我们如果增加的命令是和已有的命令的绑定是相同的,会直接覆盖,所以上面重新 `g` 模块也可以这样: 127 | 128 | ```json 129 | "vspacecode.bindings": [ 130 | ... 131 | { 132 | "key": "g", // 指要重新 g 选项;注意!这里的字段是 key 而非 bindingOverrides 配置的 keys 133 | "name": "Go...", // 在弹出的 VSpaceCode 的 g 选项中显示的名称 134 | "type": "bindings", // 对应下面的 bindings,即 g 命令下的子级命令 135 | "bindings": [ 136 | { 137 | "key": "g", // 指 g 选项的子级有一个 g 命令 138 | "name": "Go To", // 在弹出的 VSpaceCode 的 g 中的 g 选项中显示的名称 139 | "type": "command", 140 | "command": "workbench.action.gotoline", // VScode 跳转行的命令 id 141 | } 142 | ] 143 | } 144 | ... 145 | ] 146 | ``` 147 | 148 | 这样的效果也是和上面一样。 149 | 150 | :::tip 避免 VSpaceCode 的弹窗 151 | 有的人可能觉得 VSpaceCode 弹窗不好,其实可以用 vim 实现对应的功能,它的原理和 vim 的 `` 键是一样的。至于配置的喜好因人而异,大家也可以参考 [VSpaceCode 官方推荐的配置](https://github.com/VSpaceCode/VSpaceCode/blob/vscode-vim/settings.json)。 152 | ::: -------------------------------------------------------------------------------- /docs/vscode/day-28.md: -------------------------------------------------------------------------------- 1 | # 止言又欲:Git 神器 lazygit 2 | 3 | 先来看看官方的一段描述(意译 & 自译,不喜勿喷): 4 | 5 | :::tip lazygit 6 | 你以前肯定听说过:Git is 抛瓦否!但如果它的一切都很几把难用的时候,再抛瓦否又有什么用呢? 7 | 交互式重新建立基地需要你在你的编辑器中编辑一个沙雕的 TODO 文件?你他妈在开玩笑吗? 8 | 要暂存一个文件的部分更改,还要在命令行里面手动处理每个代码块? 9 | 如果一个块不能被进一步拆分,但又包含不想暂存的代码,你必须手动编辑一个莫名奇妙的补丁文件?这去你妈的是在玩我吧?! 10 | 有时切换分支的时候,突然叫我暂存更改,但在切换完并取消暂存后,根本没有任何代码冲突!直接签出分支就是了! 11 | 你 他 妈 的 一 定 是 在 玩 老 子 ! 12 | 13 | 如果你像我一样只是个普通人,而且你厌倦了听着 Git 有多牛逼实际在你用它时是像吃屎一样恶心时,lazygit 可能非常适合你。 14 | 15 | ::: 16 | 17 | 可以看出,[lazygit](https://github.com/jesseduffield/lazygit) 是为了可以让我们“懒惰”地使用 Git 的一个工具;它是基于命令行 UI 的,支持全键盘操和鼠标操作,无论是全键盘党还是普通使用者,都适合。它帮我们免掉了许多输入繁琐命令的麻烦,给我们提供了一个清爽、简洁以及极客风格的方案。 18 | 19 | ## 安装及配置 20 | 21 | Mac 下推荐使用 brew 进行安装;参考[官方安装方法](https://github.com/jesseduffield/lazygit#Homebrew)。 22 | 23 | :::warning brew install 报错 24 | 如果 brew 使用的是国内的源,有可能会导致安装时出错,比如依赖的包没有装上(我就是这样的情况),建议切回官方的源。 25 | ::: 26 | 27 | ## 基本操作 28 | - `lazygit`:安装 lazygit 后在 git 的仓库目录下命令行键入 `lazygit` 即可打开 lazygit,也可以在 `~/bash_profile` 中添加别名 `lg`,即添加新一行 `alias lg='lazygit'`; 29 | 30 | :::warning 注意! 31 | 修改 bash_profile 文件前最好先备份该文件!尤其不知道这是什么东西的朋友! 32 | ::: 33 | 34 | - `q`:退出 lazygit; 35 | - `h` / `l`:在左侧由上至下五个功能区焦点切换,也可以通过数字键 1 ~ 5 来切换对应功能区; 36 | - `j` / `k`:功能区内单条记录焦点切换;如 commit 记录焦点切换,分支焦点切换等; 37 | - `[` / `]`:功能区内有多个标签页的,可以通过这两个命令左右切换;如分支区的 `Local Branches` / `Remotes` / `Tags` 这几个标签页的切换; 38 | - `?`:如同 Vimium-c 一样,键入 `?` 会弹出当前功能区的所有可用命令以及其功能描述(相同的一个命令,如 `a`,在不同的功能区其对应的功能也不一样); 39 | 40 | ## Git 常用操作 41 | 42 | - add:左栏切换到第二栏 Files 栏中,如果是对单个文件进行暂存可以聚焦到对应文件后按下 `space` 键即可;而如果是要对所有文暂存则可以按 `a`;而如果当前文件或者所有文件都已暂存,这时使用 `space` / `a` 会变回为未添加到暂存的状态; 43 | - commit:左栏切换到第二栏 files 栏中,按 `c` 会弹出输入框要求填入提交信息,输入后 `enter` 即可提交已经暂存的更改;如果是需要添加详细可以使用 `C`; 44 | - reset:左栏切换到第四栏 Commits 栏中,切换聚焦需要回退到的那个提交上,键入 `g`,会有弹框可选择 `reset` 的 `--soft` / `--mixed` / `--hard` 参数,`enter` 即可选择; 45 | - pull:在任意位置都可通过 `p` 进行代码拉取,会拉取左栏第三栏中的 Local Branches 的分支列表中的带星号的分支的远程分支代码; 46 | - push:在任意位置都可通过 `P` 进行代码推送,会推送代码到左栏第三栏中的 Local Branches 的分支列表中的带星号的分支的远程分支中; 47 | - discard:需要撤销更改时,左栏切换到第二栏 Files 栏中,聚焦要撤销的文件,键入 `d` 即会弹出提示框提示是否撤销该文件所有更改;如果是要把当前项目中的所有文件的更改一并撤销,则可以键入 `D` 后选择需要撤销的类型; 48 | - branch:在左栏切换到第三栏 Local Branches 栏中,键入 `n` 即可基于当前分支创建新分支,键入 `d` 即可删除聚焦的分支; 49 | 50 | 以上是一些大家常用的 Git 操作对应的 lazygit 命令;当然,它的功能非常强大,还可以完成许多复杂的功能,具体可以参考官方文档。 51 | 52 | :::tip Command Log 面板 53 | 对于刚刚开始使用 lazygit 的人来说,可能很多时候并不知道自己按下按键后到底发生了什么或者到底有没有执行到,其实在左边的 Command Log 面板会把每一次我们的操作所对应的命令显示出来,所以通过观察这个区域的输出,可以时刻知道到底发生了什么。 54 | ::: 55 | 56 | 记得一定要多尝试使用 lazygit,掌握新知识的方式,就是不断使用它,vim 如是,lazygit 也如是。 57 | 58 | :::tip Git 知识 59 | 可能有一些朋友对于 Git 也只是停留在拉拉代码推推代码的程度,甚至可能连 reset 或 rebase 都没有用过的,可以在这个小训练中学习一下:[learnGitBranching](https://learngitbranching.js.org/?locale=zh_CN)。 60 | ::: -------------------------------------------------------------------------------- /docs/vscode/day-29.md: -------------------------------------------------------------------------------- 1 | # 返璞归真:终端的基本操作 2 | 3 | 众所周知,最初的程序员都是在命令行用 vim 写代码的。而即使到了今时今日,命令行也仍然在我们的开发中占据重要地位,譬如我们的每一次 ~~`润射`~~ `run serve`;为了让我们在润的时候更舒爽,也为了更贴近一个真正的程序员,终端命令行的基本操作还是要掌握的。 4 | 5 | ## 常用操作 6 | 7 | - `command` + `j` / `ctrl` + `` ` `` :这两个命令都可以打开终端;区别是前者打开的是终端所在的底部面板,但因为该面板还有不同的 tab 如输出窗、调试窗等,如果在此之前你切换到了其他 tab,通过 `command` + `j` 打开面板时还是会停留在之前的 tab;而 `ctrl` + `` ` `` 则是打开底部面板并切换到终端 tab;所以后者更好用;但由于 `` ` `` 比较难按,我们可以给配置为 `ctrl` + `,`;对应命令 `workbench.action.terminal.toggleTerminal` 8 | - `command` + `k`:当终端内容过多时可以该命令清屏 9 | - `command` + `\`:对当前终端分屏,适合同时要运行不同的命令的情况 10 | - `option` + `command` + `↑` / `←`:分屏后多屏状态下切换到上一屏,对应命令 `workbench.action.terminal.focusPreviousPane` 11 | - `option` + `command` + `↓` / `→` 分屏后多屏状态下切换到下一屏,对应命令 `workbench.action.terminal.focusNextPane` 12 | 13 | 可以发现,vscode 切换分屏的组合键是比较复杂的,再因为我们方向键是映射过的,这样一来我们要同时按四个按键;所以,改键势在必行,我们可以把 `command` + `[` / `]` 组合键添加为上面的切换屏的功能,这样一来就方便了。 14 | 15 | - `shift` + `option` + `q`:关闭终端,这个命令需要自己配置;对应命令 `workbench.action.terminal.kill` 16 | - `ctrl` + `shift` + `` ` ``:新建终端,但同样按地难受;我们可以添加个组合键 `shift` + `option` + `n` 来达到这个功能;对应命令 `workbench.action.terminal.new` 17 | - `shift` + `command` + `[` / `]`:对于新建了多个终端(非拆分的)时切换不同终端 18 | 19 | :::tip 拆分终端和新建终端 20 | 感觉区别不大,都是可以让我们对一个项目同时进行多个命令,比如一个用来跑服务,一个用来做其他命令; 21 | 唯一感觉有实质区别的就是新建可以建不同的终端,如一个是 `bash` 终端,一个是 `zsh` 终端; 22 | 也许在多工作区的情况下有不同(not sure); 23 | 如果有朋友了解的请告知我,十分感谢! 24 | ::: 25 | 26 | ## 如何打开外部终端 27 | 28 | 当然,肯定有和我一样感想的人: 29 | 30 | 这破电脑的显示屏已经够小了,还要把 vscode 的命令行面板调出来占用宝贵的位置;况且 vscode 的终端确实食之无味;社区上的命令行工具比他~~不知道高到哪里去了~~。正如我已经彻底放弃了 vscode 的命令行,转投到 [Warp](https://www.warp.dev/) 的怀抱中。既然如此,如果可以在 vscode 中打开系统默认的终端就好了。 31 | 32 | 33 | 在 vscode 中,可以设置默认打开的外部命令行工具, 34 | 在 vscode 中,通过 `command` + `k` + `command` + `s`,打开键盘快捷方式面板,搜索 `open terminal` 可以找到打开新的外部终端的快捷键为 `shift` + `command` + `c`;如果你是使用 MacOS 自带终端工具的则到这里就 ok 了。但如果你是和我一样使用 Warp 或 iTerm2 之类的命令行工具的,则需要继续阅读。 35 | 36 | 通过查看 vscode 命令行相关的设置(设置面板,不是在 `setting.json` 找),在 `用户 - 功能 - 终端` 中可以找到三个设置: 37 | 38 | - 自定义要在 Linux 上运行的终端 39 | - 自定义要在 MacOS 上运行的终端 40 | - 自定义要在 Window 上运行的终端 41 | 42 | 我们可以根据自己的系统直接在对应的输入框输入命令行工具名称,比如 Warp 则输入 `Warp.app`,如果是 iTerm 则为 `iTerm.app`;当然我们也可以点击输入框前面的小齿轮,选择 [复制设置id],其值为 `terminal.external.osxExec`,然后在 `setting.json` 中设置该值为前面说的如 `Warp.app` 即可。 43 | 44 | 当你通过该快捷键激活外部命令行时,你还会惊奇发现:vscode 会在当前工作区路径打开的外部命令行! 45 | 46 | 这多是一件美事啊! 47 | 48 | 还不快点摆脱 vscode 的命令行? -------------------------------------------------------------------------------- /docs/vscode/day-30.md: -------------------------------------------------------------------------------- 1 | # 去其糟粕:Debug the Bug 2 | 3 | 有人统计过,一个程序员 50% 以上的工作时间都没有编程,而他们有一半的编程时间都花在 debug 上。而这 50% 的时间里面,可能有 20% 的时间,我们是在移动鼠标的路上;今天我们进来了解一下如何通过键盘快捷键来打一场漂亮的~~翻身仗~~断点。 4 | 5 | ## 基础操作 6 | 7 | - `f5`:开始 Debug 或 跳出当前断点;比如在一个 JavaScript 脚本文件中键入 `f5`,即可进入 Debug 模式;而如果是已经在 Debug 过程中了,则是 **step out**; 8 | - `shift` + `f5`:停止 Debug; 9 | - `shift` + `command` + `f5`:重新开始 Debug,比如正在 Debug 时不小心跳过了某个应该停止的断点,则可以使用该组合键快速重新 Debug;由于 `f5` 比较远,可以在 VScode 快捷键面板中改成 `shift` + `command` + `0`;其对应 VScode 命令为 `workbench.action.debug.restart`; 10 | - `f9`:为当前光标所在行添加断点 / 取消当前光标所在行的断点;和上面同理可以改键为 `shift` + `command` + `9`;其对应 VScode 命令为 `workbench.action.debug.toggleBreakpoint` 11 | - `f10`:**step over**;同理我们可以改为 `command` + `'`;其对应 VScode 命令为 `workbench.action.debug.stepOver` 12 | - `f11`:**step into**;同理我们可以改为 `shift` + `command` + `'`;其对应 VScode 命令为 `workbench.action.debug.stepInto` 13 | 14 | :::tip step into / step over / step out 15 | step into:单步执行,遇到子函数就进入并且继续单步执行(简而言之,进入子函数); 16 | 17 | step over:在单步执行时,在函数内遇到子函数时不会进入子函数内单步执行,而是将子函数整个执行完再停止,也就是把子函数整个作为一步。不存在子函数的情况下是和 step into 效果一样的(简而言之,越过子函数,但子函数会执行); 18 | 19 | step out:当单步执行到子函数内时,用step out就可以执行完子函数余下部分,并返回到上一层函数。 20 | ::: 21 | 22 | :::tip 使用 VSpacecode 插件进行 debug 23 | 如果有安装了 VSpacecode 插件的朋友,可以在激活该插件时看到其 `d` 命令就是对应了 Debug 的一系列操作。所以不想记忆上面提到的快捷键的朋友可以直接使用 VSpacecode 达到对应的操作。 24 | ::: 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "just-vim-it", 3 | "version": "1.0.0", 4 | "description": "这是一个纯小白入门 vim 的训练,这里有两个关键点 1. 使用于纯小白的(或者已经接触过vim但想构建一套基础,使用日常工作的vim方案的朋友),如果你不属于这样的人群,那可能这个训练并不适合你,因为可能在本训练中的一些快捷键设置、使用习惯和你已养成的并不相符 2. 这是一个入门训练,本训练只能保证在你认真使用、学习后,可以在日常、工作的代码工作中使用vim完成日常会用到的操作,更深一层的技巧则是在于你本人的探索", 5 | "main": "index.js", 6 | "scripts": { 7 | "docs:dev": "vitepress dev docs", 8 | "docs:build": "vitepress build docs", 9 | "docs:serve": "vitepress serve docs" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/Nauxscript/Just-Vim-It.git" 14 | }, 15 | "author": "", 16 | "license": "ISC", 17 | "bugs": { 18 | "url": "https://github.com/Nauxscript/Just-Vim-It/issues" 19 | }, 20 | "homepage": "https://github.com/Nauxscript/Just-Vim-It#readme", 21 | "devDependencies": { 22 | "vitepress": "^1.0.0-alpha.1" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '6.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | devDependencies: 8 | vitepress: 9 | specifier: ^1.0.0-alpha.1 10 | version: 1.0.0-alpha.1(@types/react@18.2.21)(react-dom@18.2.0)(react@18.2.0) 11 | 12 | packages: 13 | 14 | /@algolia/autocomplete-core@1.6.3: 15 | resolution: {integrity: sha512-dqQqRt01fX3YuVFrkceHsoCnzX0bLhrrg8itJI1NM68KjrPYQPYsE+kY8EZTCM4y8VDnhqJErR73xe/ZsV+qAA==} 16 | dependencies: 17 | '@algolia/autocomplete-shared': 1.6.3 18 | dev: true 19 | 20 | /@algolia/autocomplete-shared@1.6.3: 21 | resolution: {integrity: sha512-UV46bnkTztyADFaETfzFC5ryIdGVb2zpAoYgu0tfcuYWjhg1KbLXveFffZIrGVoboqmAk1b+jMrl6iCja1i3lg==} 22 | dev: true 23 | 24 | /@algolia/cache-browser-local-storage@4.13.1: 25 | resolution: {integrity: sha512-UAUVG2PEfwd/FfudsZtYnidJ9eSCpS+LW9cQiesePQLz41NAcddKxBak6eP2GErqyFagSlnVXe/w2E9h2m2ttg==} 26 | dependencies: 27 | '@algolia/cache-common': 4.13.1 28 | dev: true 29 | 30 | /@algolia/cache-common@4.13.1: 31 | resolution: {integrity: sha512-7Vaf6IM4L0Jkl3sYXbwK+2beQOgVJ0mKFbz/4qSxKd1iy2Sp77uTAazcX+Dlexekg1fqGUOSO7HS4Sx47ZJmjA==} 32 | dev: true 33 | 34 | /@algolia/cache-in-memory@4.13.1: 35 | resolution: {integrity: sha512-pZzybCDGApfA/nutsFK1P0Sbsq6fYJU3DwIvyKg4pURerlJM4qZbB9bfLRef0FkzfQu7W11E4cVLCIOWmyZeuQ==} 36 | dependencies: 37 | '@algolia/cache-common': 4.13.1 38 | dev: true 39 | 40 | /@algolia/client-account@4.13.1: 41 | resolution: {integrity: sha512-TFLiZ1KqMiir3FNHU+h3b0MArmyaHG+eT8Iojio6TdpeFcAQ1Aiy+2gb3SZk3+pgRJa/BxGmDkRUwE5E/lv3QQ==} 42 | dependencies: 43 | '@algolia/client-common': 4.13.1 44 | '@algolia/client-search': 4.13.1 45 | '@algolia/transporter': 4.13.1 46 | dev: true 47 | 48 | /@algolia/client-analytics@4.13.1: 49 | resolution: {integrity: sha512-iOS1JBqh7xaL5x00M5zyluZ9+9Uy9GqtYHv/2SMuzNW1qP7/0doz1lbcsP3S7KBbZANJTFHUOfuqyRLPk91iFA==} 50 | dependencies: 51 | '@algolia/client-common': 4.13.1 52 | '@algolia/client-search': 4.13.1 53 | '@algolia/requester-common': 4.13.1 54 | '@algolia/transporter': 4.13.1 55 | dev: true 56 | 57 | /@algolia/client-common@4.13.1: 58 | resolution: {integrity: sha512-LcDoUE0Zz3YwfXJL6lJ2OMY2soClbjrrAKB6auYVMNJcoKZZ2cbhQoFR24AYoxnGUYBER/8B+9sTBj5bj/Gqbg==} 59 | dependencies: 60 | '@algolia/requester-common': 4.13.1 61 | '@algolia/transporter': 4.13.1 62 | dev: true 63 | 64 | /@algolia/client-personalization@4.13.1: 65 | resolution: {integrity: sha512-1CqrOW1ypVrB4Lssh02hP//YxluoIYXAQCpg03L+/RiXJlCs+uIqlzC0ctpQPmxSlTK6h07kr50JQoYH/TIM9w==} 66 | dependencies: 67 | '@algolia/client-common': 4.13.1 68 | '@algolia/requester-common': 4.13.1 69 | '@algolia/transporter': 4.13.1 70 | dev: true 71 | 72 | /@algolia/client-search@4.13.1: 73 | resolution: {integrity: sha512-YQKYA83MNRz3FgTNM+4eRYbSmHi0WWpo019s5SeYcL3HUan/i5R09VO9dk3evELDFJYciiydSjbsmhBzbpPP2A==} 74 | dependencies: 75 | '@algolia/client-common': 4.13.1 76 | '@algolia/requester-common': 4.13.1 77 | '@algolia/transporter': 4.13.1 78 | dev: true 79 | 80 | /@algolia/logger-common@4.13.1: 81 | resolution: {integrity: sha512-L6slbL/OyZaAXNtS/1A8SAbOJeEXD5JcZeDCPYDqSTYScfHu+2ePRTDMgUTY4gQ7HsYZ39N1LujOd8WBTmM2Aw==} 82 | dev: true 83 | 84 | /@algolia/logger-console@4.13.1: 85 | resolution: {integrity: sha512-7jQOTftfeeLlnb3YqF8bNgA2GZht7rdKkJ31OCeSH2/61haO0tWPoNRjZq9XLlgMQZH276pPo0NdiArcYPHjCA==} 86 | dependencies: 87 | '@algolia/logger-common': 4.13.1 88 | dev: true 89 | 90 | /@algolia/requester-browser-xhr@4.13.1: 91 | resolution: {integrity: sha512-oa0CKr1iH6Nc7CmU6RE7TnXMjHnlyp7S80pP/LvZVABeJHX3p/BcSCKovNYWWltgTxUg0U1o+2uuy8BpMKljwA==} 92 | dependencies: 93 | '@algolia/requester-common': 4.13.1 94 | dev: true 95 | 96 | /@algolia/requester-common@4.13.1: 97 | resolution: {integrity: sha512-eGVf0ID84apfFEuXsaoSgIxbU3oFsIbz4XiotU3VS8qGCJAaLVUC5BUJEkiFENZIhon7hIB4d0RI13HY4RSA+w==} 98 | dev: true 99 | 100 | /@algolia/requester-node-http@4.13.1: 101 | resolution: {integrity: sha512-7C0skwtLdCz5heKTVe/vjvrqgL/eJxmiEjHqXdtypcE5GCQCYI15cb+wC4ytYioZDMiuDGeVYmCYImPoEgUGPw==} 102 | dependencies: 103 | '@algolia/requester-common': 4.13.1 104 | dev: true 105 | 106 | /@algolia/transporter@4.13.1: 107 | resolution: {integrity: sha512-pICnNQN7TtrcYJqqPEXByV8rJ8ZRU2hCiIKLTLRyNpghtQG3VAFk6fVtdzlNfdUGZcehSKGarPIZEHlQXnKjgw==} 108 | dependencies: 109 | '@algolia/cache-common': 4.13.1 110 | '@algolia/logger-common': 4.13.1 111 | '@algolia/requester-common': 4.13.1 112 | dev: true 113 | 114 | /@babel/helper-validator-identifier@7.16.7: 115 | resolution: {integrity: sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==} 116 | engines: {node: '>=6.9.0'} 117 | dev: true 118 | 119 | /@babel/parser@7.18.4: 120 | resolution: {integrity: sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==} 121 | engines: {node: '>=6.0.0'} 122 | hasBin: true 123 | dependencies: 124 | '@babel/types': 7.18.4 125 | dev: true 126 | 127 | /@babel/types@7.18.4: 128 | resolution: {integrity: sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==} 129 | engines: {node: '>=6.9.0'} 130 | dependencies: 131 | '@babel/helper-validator-identifier': 7.16.7 132 | to-fast-properties: 2.0.0 133 | dev: true 134 | 135 | /@docsearch/css@3.1.0: 136 | resolution: {integrity: sha512-bh5IskwkkodbvC0FzSg1AxMykfDl95hebEKwxNoq4e5QaGzOXSBgW8+jnMFZ7JU4sTBiB04vZWoUSzNrPboLZA==} 137 | dev: true 138 | 139 | /@docsearch/js@3.1.0(@types/react@18.2.21)(react-dom@18.2.0)(react@18.2.0): 140 | resolution: {integrity: sha512-5XSK+xbP0hcTIp54MECqxkWLs6kf7Ug4nWdxWNtx8cUpLiFNFnKXDxCb35wnyNpjukmrx7Q9DkO5tFFsmNVxng==} 141 | dependencies: 142 | '@docsearch/react': 3.1.0(@types/react@18.2.21)(react-dom@18.2.0)(react@18.2.0) 143 | preact: 10.7.3 144 | transitivePeerDependencies: 145 | - '@types/react' 146 | - react 147 | - react-dom 148 | dev: true 149 | 150 | /@docsearch/react@3.1.0(@types/react@18.2.21)(react-dom@18.2.0)(react@18.2.0): 151 | resolution: {integrity: sha512-bjB6ExnZzf++5B7Tfoi6UXgNwoUnNOfZ1NyvnvPhWgCMy5V/biAtLL4o7owmZSYdAKeFSvZ5Lxm0is4su/dBWg==} 152 | peerDependencies: 153 | '@types/react': '>= 16.8.0 < 19.0.0' 154 | react: '>= 16.8.0 < 19.0.0' 155 | react-dom: '>= 16.8.0 < 19.0.0' 156 | dependencies: 157 | '@algolia/autocomplete-core': 1.6.3 158 | '@docsearch/css': 3.1.0 159 | '@types/react': 18.2.21 160 | algoliasearch: 4.13.1 161 | react: 18.2.0 162 | react-dom: 18.2.0(react@18.2.0) 163 | dev: true 164 | 165 | /@types/prop-types@15.7.5: 166 | resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} 167 | dev: true 168 | 169 | /@types/react@18.2.21: 170 | resolution: {integrity: sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA==} 171 | dependencies: 172 | '@types/prop-types': 15.7.5 173 | '@types/scheduler': 0.16.3 174 | csstype: 3.1.2 175 | dev: true 176 | 177 | /@types/scheduler@0.16.3: 178 | resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==} 179 | dev: true 180 | 181 | /@vitejs/plugin-vue@2.3.3(vite@2.9.18)(vue@3.2.37): 182 | resolution: {integrity: sha512-SmQLDyhz+6lGJhPELsBdzXGc+AcaT8stgkbiTFGpXPe8Tl1tJaBw1A6pxDqDuRsVkD8uscrkx3hA7QDOoKYtyw==} 183 | engines: {node: '>=12.0.0'} 184 | peerDependencies: 185 | vite: ^2.5.10 186 | vue: ^3.2.25 187 | dependencies: 188 | vite: 2.9.18 189 | vue: 3.2.37 190 | dev: true 191 | 192 | /@vue/compiler-core@3.2.37: 193 | resolution: {integrity: sha512-81KhEjo7YAOh0vQJoSmAD68wLfYqJvoiD4ulyedzF+OEk/bk6/hx3fTNVfuzugIIaTrOx4PGx6pAiBRe5e9Zmg==} 194 | dependencies: 195 | '@babel/parser': 7.18.4 196 | '@vue/shared': 3.2.37 197 | estree-walker: 2.0.2 198 | source-map: 0.6.1 199 | dev: true 200 | 201 | /@vue/compiler-dom@3.2.37: 202 | resolution: {integrity: sha512-yxJLH167fucHKxaqXpYk7x8z7mMEnXOw3G2q62FTkmsvNxu4FQSu5+3UMb+L7fjKa26DEzhrmCxAgFLLIzVfqQ==} 203 | dependencies: 204 | '@vue/compiler-core': 3.2.37 205 | '@vue/shared': 3.2.37 206 | dev: true 207 | 208 | /@vue/compiler-sfc@3.2.37: 209 | resolution: {integrity: sha512-+7i/2+9LYlpqDv+KTtWhOZH+pa8/HnX/905MdVmAcI/mPQOBwkHHIzrsEsucyOIZQYMkXUiTkmZq5am/NyXKkg==} 210 | dependencies: 211 | '@babel/parser': 7.18.4 212 | '@vue/compiler-core': 3.2.37 213 | '@vue/compiler-dom': 3.2.37 214 | '@vue/compiler-ssr': 3.2.37 215 | '@vue/reactivity-transform': 3.2.37 216 | '@vue/shared': 3.2.37 217 | estree-walker: 2.0.2 218 | magic-string: 0.25.9 219 | postcss: 8.4.31 220 | source-map: 0.6.1 221 | dev: true 222 | 223 | /@vue/compiler-ssr@3.2.37: 224 | resolution: {integrity: sha512-7mQJD7HdXxQjktmsWp/J67lThEIcxLemz1Vb5I6rYJHR5vI+lON3nPGOH3ubmbvYGt8xEUaAr1j7/tIFWiEOqw==} 225 | dependencies: 226 | '@vue/compiler-dom': 3.2.37 227 | '@vue/shared': 3.2.37 228 | dev: true 229 | 230 | /@vue/reactivity-transform@3.2.37: 231 | resolution: {integrity: sha512-IWopkKEb+8qpu/1eMKVeXrK0NLw9HicGviJzhJDEyfxTR9e1WtpnnbYkJWurX6WwoFP0sz10xQg8yL8lgskAZg==} 232 | dependencies: 233 | '@babel/parser': 7.18.4 234 | '@vue/compiler-core': 3.2.37 235 | '@vue/shared': 3.2.37 236 | estree-walker: 2.0.2 237 | magic-string: 0.25.9 238 | dev: true 239 | 240 | /@vue/reactivity@3.2.37: 241 | resolution: {integrity: sha512-/7WRafBOshOc6m3F7plwzPeCu/RCVv9uMpOwa/5PiY1Zz+WLVRWiy0MYKwmg19KBdGtFWsmZ4cD+LOdVPcs52A==} 242 | dependencies: 243 | '@vue/shared': 3.2.37 244 | dev: true 245 | 246 | /@vue/runtime-core@3.2.37: 247 | resolution: {integrity: sha512-JPcd9kFyEdXLl/i0ClS7lwgcs0QpUAWj+SKX2ZC3ANKi1U4DOtiEr6cRqFXsPwY5u1L9fAjkinIdB8Rz3FoYNQ==} 248 | dependencies: 249 | '@vue/reactivity': 3.2.37 250 | '@vue/shared': 3.2.37 251 | dev: true 252 | 253 | /@vue/runtime-dom@3.2.37: 254 | resolution: {integrity: sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw==} 255 | dependencies: 256 | '@vue/runtime-core': 3.2.37 257 | '@vue/shared': 3.2.37 258 | csstype: 2.6.20 259 | dev: true 260 | 261 | /@vue/server-renderer@3.2.37(vue@3.2.37): 262 | resolution: {integrity: sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA==} 263 | peerDependencies: 264 | vue: 3.2.37 265 | dependencies: 266 | '@vue/compiler-ssr': 3.2.37 267 | '@vue/shared': 3.2.37 268 | vue: 3.2.37 269 | dev: true 270 | 271 | /@vue/shared@3.2.37: 272 | resolution: {integrity: sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==} 273 | dev: true 274 | 275 | /@vueuse/core@8.6.0(vue@3.2.37): 276 | resolution: {integrity: sha512-VirzExCm/N+QdrEWT7J4uSrvJ5hquKIAU9alQ37kUvIJk9XxCLxmfRnmekYc1kz2+6BnoyuKYXVmrMV351CB4w==} 277 | peerDependencies: 278 | '@vue/composition-api': ^1.1.0 279 | vue: ^2.6.0 || ^3.2.0 280 | peerDependenciesMeta: 281 | '@vue/composition-api': 282 | optional: true 283 | vue: 284 | optional: true 285 | dependencies: 286 | '@vueuse/metadata': 8.6.0 287 | '@vueuse/shared': 8.6.0(vue@3.2.37) 288 | vue: 3.2.37 289 | vue-demi: 0.13.1(vue@3.2.37) 290 | dev: true 291 | 292 | /@vueuse/metadata@8.6.0: 293 | resolution: {integrity: sha512-F+CKPvaExsm7QgRr8y+ZNJFwXasn89rs5wth/HeX9lJ1q8XEt+HJ16Q5Sxh4rfG5YSKXrStveVge8TKvPjMjFA==} 294 | dev: true 295 | 296 | /@vueuse/shared@8.6.0(vue@3.2.37): 297 | resolution: {integrity: sha512-Y/IVywZo7IfEoSSEtCYpkVEmPV7pU35mEIxV7PbD/D3ly18B3mEsBaPbtDkNM/QP3zAZ5mn4nEkOfddX4uwuIA==} 298 | peerDependencies: 299 | '@vue/composition-api': ^1.1.0 300 | vue: ^2.6.0 || ^3.2.0 301 | peerDependenciesMeta: 302 | '@vue/composition-api': 303 | optional: true 304 | vue: 305 | optional: true 306 | dependencies: 307 | vue: 3.2.37 308 | vue-demi: 0.13.1(vue@3.2.37) 309 | dev: true 310 | 311 | /algoliasearch@4.13.1: 312 | resolution: {integrity: sha512-dtHUSE0caWTCE7liE1xaL+19AFf6kWEcyn76uhcitWpntqvicFHXKFoZe5JJcv9whQOTRM6+B8qJz6sFj+rDJA==} 313 | dependencies: 314 | '@algolia/cache-browser-local-storage': 4.13.1 315 | '@algolia/cache-common': 4.13.1 316 | '@algolia/cache-in-memory': 4.13.1 317 | '@algolia/client-account': 4.13.1 318 | '@algolia/client-analytics': 4.13.1 319 | '@algolia/client-common': 4.13.1 320 | '@algolia/client-personalization': 4.13.1 321 | '@algolia/client-search': 4.13.1 322 | '@algolia/logger-common': 4.13.1 323 | '@algolia/logger-console': 4.13.1 324 | '@algolia/requester-browser-xhr': 4.13.1 325 | '@algolia/requester-common': 4.13.1 326 | '@algolia/requester-node-http': 4.13.1 327 | '@algolia/transporter': 4.13.1 328 | dev: true 329 | 330 | /body-scroll-lock@4.0.0-beta.0: 331 | resolution: {integrity: sha512-a7tP5+0Mw3YlUJcGAKUqIBkYYGlYxk2fnCasq/FUph1hadxlTRjF+gAcZksxANnaMnALjxEddmSi/H3OR8ugcQ==} 332 | dev: true 333 | 334 | /csstype@2.6.20: 335 | resolution: {integrity: sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==} 336 | dev: true 337 | 338 | /csstype@3.1.2: 339 | resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} 340 | dev: true 341 | 342 | /esbuild-android-64@0.14.42: 343 | resolution: {integrity: sha512-P4Y36VUtRhK/zivqGVMqhptSrFILAGlYp0Z8r9UQqHJ3iWztRCNWnlBzD9HRx0DbueXikzOiwyOri+ojAFfW6A==} 344 | engines: {node: '>=12'} 345 | cpu: [x64] 346 | os: [android] 347 | requiresBuild: true 348 | dev: true 349 | optional: true 350 | 351 | /esbuild-android-arm64@0.14.42: 352 | resolution: {integrity: sha512-0cOqCubq+RWScPqvtQdjXG3Czb3AWI2CaKw3HeXry2eoA2rrPr85HF7IpdU26UWdBXgPYtlTN1LUiuXbboROhg==} 353 | engines: {node: '>=12'} 354 | cpu: [arm64] 355 | os: [android] 356 | requiresBuild: true 357 | dev: true 358 | optional: true 359 | 360 | /esbuild-darwin-64@0.14.42: 361 | resolution: {integrity: sha512-ipiBdCA3ZjYgRfRLdQwP82rTiv/YVMtW36hTvAN5ZKAIfxBOyPXY7Cejp3bMXWgzKD8B6O+zoMzh01GZsCuEIA==} 362 | engines: {node: '>=12'} 363 | cpu: [x64] 364 | os: [darwin] 365 | requiresBuild: true 366 | dev: true 367 | optional: true 368 | 369 | /esbuild-darwin-arm64@0.14.42: 370 | resolution: {integrity: sha512-bU2tHRqTPOaoH/4m0zYHbFWpiYDmaA0gt90/3BMEFaM0PqVK/a6MA2V/ypV5PO0v8QxN6gH5hBPY4YJ2lopXgA==} 371 | engines: {node: '>=12'} 372 | cpu: [arm64] 373 | os: [darwin] 374 | requiresBuild: true 375 | dev: true 376 | optional: true 377 | 378 | /esbuild-freebsd-64@0.14.42: 379 | resolution: {integrity: sha512-75h1+22Ivy07+QvxHyhVqOdekupiTZVLN1PMwCDonAqyXd8TVNJfIRFrdL8QmSJrOJJ5h8H1I9ETyl2L8LQDaw==} 380 | engines: {node: '>=12'} 381 | cpu: [x64] 382 | os: [freebsd] 383 | requiresBuild: true 384 | dev: true 385 | optional: true 386 | 387 | /esbuild-freebsd-arm64@0.14.42: 388 | resolution: {integrity: sha512-W6Jebeu5TTDQMJUJVarEzRU9LlKpNkPBbjqSu+GUPTHDCly5zZEQq9uHkmHHl7OKm+mQ2zFySN83nmfCeZCyNA==} 389 | engines: {node: '>=12'} 390 | cpu: [arm64] 391 | os: [freebsd] 392 | requiresBuild: true 393 | dev: true 394 | optional: true 395 | 396 | /esbuild-linux-32@0.14.42: 397 | resolution: {integrity: sha512-Ooy/Bj+mJ1z4jlWcK5Dl6SlPlCgQB9zg1UrTCeY8XagvuWZ4qGPyYEWGkT94HUsRi2hKsXvcs6ThTOjBaJSMfg==} 398 | engines: {node: '>=12'} 399 | cpu: [ia32] 400 | os: [linux] 401 | requiresBuild: true 402 | dev: true 403 | optional: true 404 | 405 | /esbuild-linux-64@0.14.42: 406 | resolution: {integrity: sha512-2L0HbzQfbTuemUWfVqNIjOfaTRt9zsvjnme6lnr7/MO9toz/MJ5tZhjqrG6uDWDxhsaHI2/nsDgrv8uEEN2eoA==} 407 | engines: {node: '>=12'} 408 | cpu: [x64] 409 | os: [linux] 410 | requiresBuild: true 411 | dev: true 412 | optional: true 413 | 414 | /esbuild-linux-arm64@0.14.42: 415 | resolution: {integrity: sha512-c3Ug3e9JpVr8jAcfbhirtpBauLxzYPpycjWulD71CF6ZSY26tvzmXMJYooQ2YKqDY4e/fPu5K8bm7MiXMnyxuA==} 416 | engines: {node: '>=12'} 417 | cpu: [arm64] 418 | os: [linux] 419 | requiresBuild: true 420 | dev: true 421 | optional: true 422 | 423 | /esbuild-linux-arm@0.14.42: 424 | resolution: {integrity: sha512-STq69yzCMhdRaWnh29UYrLSr/qaWMm/KqwaRF1pMEK7kDiagaXhSL1zQGXbYv94GuGY/zAwzK98+6idCMUOOCg==} 425 | engines: {node: '>=12'} 426 | cpu: [arm] 427 | os: [linux] 428 | requiresBuild: true 429 | dev: true 430 | optional: true 431 | 432 | /esbuild-linux-mips64le@0.14.42: 433 | resolution: {integrity: sha512-QuvpHGbYlkyXWf2cGm51LBCHx6eUakjaSrRpUqhPwjh/uvNUYvLmz2LgPTTPwCqaKt0iwL+OGVL0tXA5aDbAbg==} 434 | engines: {node: '>=12'} 435 | cpu: [mips64el] 436 | os: [linux] 437 | requiresBuild: true 438 | dev: true 439 | optional: true 440 | 441 | /esbuild-linux-ppc64le@0.14.42: 442 | resolution: {integrity: sha512-8ohIVIWDbDT+i7lCx44YCyIRrOW1MYlks9fxTo0ME2LS/fxxdoJBwHWzaDYhjvf8kNpA+MInZvyOEAGoVDrMHg==} 443 | engines: {node: '>=12'} 444 | cpu: [ppc64] 445 | os: [linux] 446 | requiresBuild: true 447 | dev: true 448 | optional: true 449 | 450 | /esbuild-linux-riscv64@0.14.42: 451 | resolution: {integrity: sha512-DzDqK3TuoXktPyG1Lwx7vhaF49Onv3eR61KwQyxYo4y5UKTpL3NmuarHSIaSVlTFDDpcIajCDwz5/uwKLLgKiQ==} 452 | engines: {node: '>=12'} 453 | cpu: [riscv64] 454 | os: [linux] 455 | requiresBuild: true 456 | dev: true 457 | optional: true 458 | 459 | /esbuild-linux-s390x@0.14.42: 460 | resolution: {integrity: sha512-YFRhPCxl8nb//Wn6SiS5pmtplBi4z9yC2gLrYoYI/tvwuB1jldir9r7JwAGy1Ck4D7sE7wBN9GFtUUX/DLdcEQ==} 461 | engines: {node: '>=12'} 462 | cpu: [s390x] 463 | os: [linux] 464 | requiresBuild: true 465 | dev: true 466 | optional: true 467 | 468 | /esbuild-netbsd-64@0.14.42: 469 | resolution: {integrity: sha512-QYSD2k+oT9dqB/4eEM9c+7KyNYsIPgzYOSrmfNGDIyJrbT1d+CFVKvnKahDKNJLfOYj8N4MgyFaU9/Ytc6w5Vw==} 470 | engines: {node: '>=12'} 471 | cpu: [x64] 472 | os: [netbsd] 473 | requiresBuild: true 474 | dev: true 475 | optional: true 476 | 477 | /esbuild-openbsd-64@0.14.42: 478 | resolution: {integrity: sha512-M2meNVIKWsm2HMY7+TU9AxM7ZVwI9havdsw6m/6EzdXysyCFFSoaTQ/Jg03izjCsK17FsVRHqRe26Llj6x0MNA==} 479 | engines: {node: '>=12'} 480 | cpu: [x64] 481 | os: [openbsd] 482 | requiresBuild: true 483 | dev: true 484 | optional: true 485 | 486 | /esbuild-sunos-64@0.14.42: 487 | resolution: {integrity: sha512-uXV8TAZEw36DkgW8Ak3MpSJs1ofBb3Smkc/6pZ29sCAN1KzCAQzsje4sUwugf+FVicrHvlamCOlFZIXgct+iqQ==} 488 | engines: {node: '>=12'} 489 | cpu: [x64] 490 | os: [sunos] 491 | requiresBuild: true 492 | dev: true 493 | optional: true 494 | 495 | /esbuild-windows-32@0.14.42: 496 | resolution: {integrity: sha512-4iw/8qWmRICWi9ZOnJJf9sYt6wmtp3hsN4TdI5NqgjfOkBVMxNdM9Vt3626G1Rda9ya2Q0hjQRD9W1o+m6Lz6g==} 497 | engines: {node: '>=12'} 498 | cpu: [ia32] 499 | os: [win32] 500 | requiresBuild: true 501 | dev: true 502 | optional: true 503 | 504 | /esbuild-windows-64@0.14.42: 505 | resolution: {integrity: sha512-j3cdK+Y3+a5H0wHKmLGTJcq0+/2mMBHPWkItR3vytp/aUGD/ua/t2BLdfBIzbNN9nLCRL9sywCRpOpFMx3CxzA==} 506 | engines: {node: '>=12'} 507 | cpu: [x64] 508 | os: [win32] 509 | requiresBuild: true 510 | dev: true 511 | optional: true 512 | 513 | /esbuild-windows-arm64@0.14.42: 514 | resolution: {integrity: sha512-+lRAARnF+hf8J0mN27ujO+VbhPbDqJ8rCcJKye4y7YZLV6C4n3pTRThAb388k/zqF5uM0lS5O201u0OqoWSicw==} 515 | engines: {node: '>=12'} 516 | cpu: [arm64] 517 | os: [win32] 518 | requiresBuild: true 519 | dev: true 520 | optional: true 521 | 522 | /esbuild@0.14.42: 523 | resolution: {integrity: sha512-V0uPZotCEHokJdNqyozH6qsaQXqmZEOiZWrXnds/zaH/0SyrIayRXWRB98CENO73MIZ9T3HBIOsmds5twWtmgw==} 524 | engines: {node: '>=12'} 525 | hasBin: true 526 | requiresBuild: true 527 | optionalDependencies: 528 | esbuild-android-64: 0.14.42 529 | esbuild-android-arm64: 0.14.42 530 | esbuild-darwin-64: 0.14.42 531 | esbuild-darwin-arm64: 0.14.42 532 | esbuild-freebsd-64: 0.14.42 533 | esbuild-freebsd-arm64: 0.14.42 534 | esbuild-linux-32: 0.14.42 535 | esbuild-linux-64: 0.14.42 536 | esbuild-linux-arm: 0.14.42 537 | esbuild-linux-arm64: 0.14.42 538 | esbuild-linux-mips64le: 0.14.42 539 | esbuild-linux-ppc64le: 0.14.42 540 | esbuild-linux-riscv64: 0.14.42 541 | esbuild-linux-s390x: 0.14.42 542 | esbuild-netbsd-64: 0.14.42 543 | esbuild-openbsd-64: 0.14.42 544 | esbuild-sunos-64: 0.14.42 545 | esbuild-windows-32: 0.14.42 546 | esbuild-windows-64: 0.14.42 547 | esbuild-windows-arm64: 0.14.42 548 | dev: true 549 | 550 | /estree-walker@2.0.2: 551 | resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} 552 | dev: true 553 | 554 | /fsevents@2.3.2: 555 | resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} 556 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 557 | os: [darwin] 558 | requiresBuild: true 559 | dev: true 560 | optional: true 561 | 562 | /function-bind@1.1.1: 563 | resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} 564 | dev: true 565 | 566 | /has@1.0.3: 567 | resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} 568 | engines: {node: '>= 0.4.0'} 569 | dependencies: 570 | function-bind: 1.1.1 571 | dev: true 572 | 573 | /is-core-module@2.9.0: 574 | resolution: {integrity: sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==} 575 | dependencies: 576 | has: 1.0.3 577 | dev: true 578 | 579 | /js-tokens@4.0.0: 580 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 581 | dev: true 582 | 583 | /jsonc-parser@3.0.0: 584 | resolution: {integrity: sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==} 585 | dev: true 586 | 587 | /loose-envify@1.4.0: 588 | resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} 589 | hasBin: true 590 | dependencies: 591 | js-tokens: 4.0.0 592 | dev: true 593 | 594 | /magic-string@0.25.9: 595 | resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} 596 | dependencies: 597 | sourcemap-codec: 1.4.8 598 | dev: true 599 | 600 | /nanoid@3.3.6: 601 | resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} 602 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 603 | hasBin: true 604 | dev: true 605 | 606 | /path-parse@1.0.7: 607 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 608 | dev: true 609 | 610 | /picocolors@1.0.0: 611 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} 612 | dev: true 613 | 614 | /postcss@8.4.31: 615 | resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} 616 | engines: {node: ^10 || ^12 || >=14} 617 | dependencies: 618 | nanoid: 3.3.6 619 | picocolors: 1.0.0 620 | source-map-js: 1.0.2 621 | dev: true 622 | 623 | /preact@10.7.3: 624 | resolution: {integrity: sha512-giqJXP8VbtA1tyGa3f1n9wiN7PrHtONrDyE3T+ifjr/tTkg+2N4d/6sjC9WyJKv8wM7rOYDveqy5ZoFmYlwo4w==} 625 | dev: true 626 | 627 | /react-dom@18.2.0(react@18.2.0): 628 | resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} 629 | peerDependencies: 630 | react: ^18.2.0 631 | dependencies: 632 | loose-envify: 1.4.0 633 | react: 18.2.0 634 | scheduler: 0.23.0 635 | dev: true 636 | 637 | /react@18.2.0: 638 | resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} 639 | engines: {node: '>=0.10.0'} 640 | dependencies: 641 | loose-envify: 1.4.0 642 | dev: true 643 | 644 | /resolve@1.22.0: 645 | resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==} 646 | hasBin: true 647 | dependencies: 648 | is-core-module: 2.9.0 649 | path-parse: 1.0.7 650 | supports-preserve-symlinks-flag: 1.0.0 651 | dev: true 652 | 653 | /rollup@2.75.5: 654 | resolution: {integrity: sha512-JzNlJZDison3o2mOxVmb44Oz7t74EfSd1SQrplQk0wSaXV7uLQXtVdHbxlcT3w+8tZ1TL4r/eLfc7nAbz38BBA==} 655 | engines: {node: '>=10.0.0'} 656 | hasBin: true 657 | optionalDependencies: 658 | fsevents: 2.3.2 659 | dev: true 660 | 661 | /scheduler@0.23.0: 662 | resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} 663 | dependencies: 664 | loose-envify: 1.4.0 665 | dev: true 666 | 667 | /shiki@0.10.1: 668 | resolution: {integrity: sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==} 669 | dependencies: 670 | jsonc-parser: 3.0.0 671 | vscode-oniguruma: 1.6.2 672 | vscode-textmate: 5.2.0 673 | dev: true 674 | 675 | /source-map-js@1.0.2: 676 | resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} 677 | engines: {node: '>=0.10.0'} 678 | dev: true 679 | 680 | /source-map@0.6.1: 681 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} 682 | engines: {node: '>=0.10.0'} 683 | dev: true 684 | 685 | /sourcemap-codec@1.4.8: 686 | resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} 687 | dev: true 688 | 689 | /supports-preserve-symlinks-flag@1.0.0: 690 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 691 | engines: {node: '>= 0.4'} 692 | dev: true 693 | 694 | /to-fast-properties@2.0.0: 695 | resolution: {integrity: sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=} 696 | engines: {node: '>=4'} 697 | dev: true 698 | 699 | /vite@2.9.18: 700 | resolution: {integrity: sha512-sAOqI5wNM9QvSEE70W3UGMdT8cyEn0+PmJMTFvTB8wB0YbYUWw3gUbY62AOyrXosGieF2htmeLATvNxpv/zNyQ==} 701 | engines: {node: '>=12.2.0'} 702 | hasBin: true 703 | peerDependencies: 704 | less: '*' 705 | sass: '*' 706 | stylus: '*' 707 | peerDependenciesMeta: 708 | less: 709 | optional: true 710 | sass: 711 | optional: true 712 | stylus: 713 | optional: true 714 | dependencies: 715 | esbuild: 0.14.42 716 | postcss: 8.4.31 717 | resolve: 1.22.0 718 | rollup: 2.75.5 719 | optionalDependencies: 720 | fsevents: 2.3.2 721 | dev: true 722 | 723 | /vitepress@1.0.0-alpha.1(@types/react@18.2.21)(react-dom@18.2.0)(react@18.2.0): 724 | resolution: {integrity: sha512-yA0QIl+mB3fQ2j+keQVa0DTT0waP2AeWM/p9VYfUAT9vOkQEGass4/oYmMGPCQrBwCaO3cpOxJL3ZFVooyvybQ==} 725 | engines: {node: '>=14.6.0'} 726 | hasBin: true 727 | dependencies: 728 | '@docsearch/css': 3.1.0 729 | '@docsearch/js': 3.1.0(@types/react@18.2.21)(react-dom@18.2.0)(react@18.2.0) 730 | '@vitejs/plugin-vue': 2.3.3(vite@2.9.18)(vue@3.2.37) 731 | '@vueuse/core': 8.6.0(vue@3.2.37) 732 | body-scroll-lock: 4.0.0-beta.0 733 | shiki: 0.10.1 734 | vite: 2.9.18 735 | vue: 3.2.37 736 | transitivePeerDependencies: 737 | - '@types/react' 738 | - '@vue/composition-api' 739 | - less 740 | - react 741 | - react-dom 742 | - sass 743 | - stylus 744 | dev: true 745 | 746 | /vscode-oniguruma@1.6.2: 747 | resolution: {integrity: sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==} 748 | dev: true 749 | 750 | /vscode-textmate@5.2.0: 751 | resolution: {integrity: sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==} 752 | dev: true 753 | 754 | /vue-demi@0.13.1(vue@3.2.37): 755 | resolution: {integrity: sha512-xmkJ56koG3ptpLnpgmIzk9/4nFf4CqduSJbUM0OdPoU87NwRuZ6x49OLhjSa/fC15fV+5CbEnrxU4oyE022svg==} 756 | engines: {node: '>=12'} 757 | hasBin: true 758 | requiresBuild: true 759 | peerDependencies: 760 | '@vue/composition-api': ^1.0.0-rc.1 761 | vue: ^3.0.0-0 || ^2.6.0 762 | peerDependenciesMeta: 763 | '@vue/composition-api': 764 | optional: true 765 | dependencies: 766 | vue: 3.2.37 767 | dev: true 768 | 769 | /vue@3.2.37: 770 | resolution: {integrity: sha512-bOKEZxrm8Eh+fveCqS1/NkG/n6aMidsI6hahas7pa0w/l7jkbssJVsRhVDs07IdDq7h9KHswZOgItnwJAgtVtQ==} 771 | dependencies: 772 | '@vue/compiler-dom': 3.2.37 773 | '@vue/compiler-sfc': 3.2.37 774 | '@vue/runtime-dom': 3.2.37 775 | '@vue/server-renderer': 3.2.37(vue@3.2.37) 776 | '@vue/shared': 3.2.37 777 | dev: true 778 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Just Vim It 2 | 这是一个纯小白入门 vim 的训练,这里有两个关键点 3 | 1. 使用于纯小白的(或者已经接触过vim但想构建一套基础,使用日常工作的vim方案的朋友),如果你不属于这样的人群,那可能这个训练并不适合你,因为可能在本训练中的一些快捷键设置、使用习惯和你已养成的并不相符 4 | 2. 这是一个入门训练,本训练只能保证在你认真使用、学习后,可以在日常、工作的代码工作中使用vim完成日常会用到的操作,更深一层的技巧则是在于你本人的探索 5 | 6 | ## 写在前面 7 | 8 | 由于我的主要使用场景是在 vscode 中使用 vim,以及在命令行中简单使用,所以大部分时候是围绕着 vscode 中的 vim 使用场景展开,但只要跟着全程训练坚持下来,再加上你聪明的小脑袋瓜子,将会很容易地知道并掌握如何在其他软件(如 webstorm、sublime、chrome、obsidian)中使用 vim 来脱离对鼠标的以来,甚至不仅仅 vim,你会想要找到更多更全面的方式,如 MacOS 下的 Alfred (假设你没有使用过它),所以对于 vim 的掌握程度或熟练程度,它只取决于你有多想摆脱频繁移动手去使用鼠标以及你使用 vim 的次数。 9 | 10 | ## 环境准备 11 | * **一台电脑**(mac 或 linux 为佳,window 的话我随后再试试有何不同,在 issue 区会有一些常见问题,也可自行查找) 12 | - [ Mac 环境 ](./docs/for-mac.md) 13 | - [ Window 环境 ](./docs/for-window.md) 14 | * **一个键盘** 15 | * **鼠标 / 触控板**(本训练无法也不会教你完全不使用鼠标 / 键盘操作 16 | * **坚持的心** 17 | 18 | :::tip 提示 19 | 在 issue 区会有一些常见问题,也可自行查找 20 | ::: 21 | 22 | :::tip 提示 23 | 24 | - 建示示练习 vim 之余,也练习一下电脑盲打,尤其是对于符号键位及功能键位,日常的使用时大部分人并没有非常规范地进行输入,常常是通过**一指禅**或是**移动整个手掌**来输入,这样的话输入效率也会降低,而正确(有些人喜欢杠正确这个词,或者说适宜大部分人、大部分场景)的键盘输入指法可以大大提高输入效率。大家不妨一试。 25 | 26 | - 我通过每天练习半个小时(早上10分钟,下午10分钟,晚上10分钟,大概两周),基本习惯了新的指法,且基本恢复原有的输入速度(甚至比原来更快了一些,因为击键的准确度上升了),并且对于百分之95的字符都可以盲打,所有我觉得大家都可以练习一下,是百利无一害的。 27 | 28 | ::: 29 | 30 | ## 问题 / 反馈 31 | 在 issue 中会对一些大家可能或常见的问题进行补充和说明,遇到问题可以查阅 issue 或自己 google,也欢迎提 issue;如果文章中有错误等也麻烦大家指出,十分感谢! 32 | 33 | ## 最重要的一点 34 | 该训练是根据本人在 [@崔效瑞](https://github.com/cuixiaorui) 的 [键盘侠养成训练营](https://appewiejl9g3764.h5.xiaoeknow.com/p/course/ecourse/course_28y3lTEa0pnA2HVLtZiz1vQ2kH4) 中的笔记,本着共同进步、开源的精神整理而成,希望大家饮水不忘挖井人,多多支持他,再次感谢! --------------------------------------------------------------------------------