本文旨在介绍 vim 的操作技巧,以便最大程度的提高编码效率。
Ubuntu 终端快捷键
这里我们会给出 Ubuntu 终端常用的快捷键。通常,我们会在终端下使用 vim,掌握这些终端快捷键可以节省多余操作,间接提高 vim 编程效率。
打开终端
- 用户根目录下打开新的终端:
Ctrl+Alt+T
- 打开新的终端 tab 页:
Ctrl+Shift+T
终端 tab 管理
- 跳转到指定编号的 tab(1-9)页:
Alt + 1
、Alt + 2
等 - 前一个/后一个 tab 页:
ctrl + pageUp
或ctrl + pageDown
- 关闭 tab 页:
Ctrl+Shift+w
- 全屏:
F11
- 独立屏幕之间切换:
Alt+Tab
- 左移右移标签页:
Shift+Ctrl+PgUp/PgDn
- 清除屏幕文字:
Ctrl+L
- 搜索:~Ctrl+Shift+F`
- 屏幕向上/下滚动:
Shift+PgUp/PgDn
- 暂停屏幕输出:
Ctrl+S
- 继续屏幕输出:
Ctrl+Q
编辑
- 复制:
Shift+Ctrl+C
- 粘贴:
Shift+Ctrl+V
- 移动到行首:
CTRL + A
- 移动到行末:
CTRL + E
- 在输入历史中搜索:
CTRL + R + 文本
- 向上显示缓存命令:
Ctrl+p
- 终止当前任务:
Ctrl+C
- 把当前任务放到后台运行(相当于运行命令时后面加&):
Ctrl+Z
- 显示后台运行的任务:
fg
- 向下显示缓存命令:
Ctrl+n
- 删除此处至末尾的所有内容:
Ctrl+k
- 删除此处至开始的所有内容:
Ctrl+u
- 删除此处到左边的单词:
Ctrl+w
- 删除当前字符:
Ctrl+d
- 删除当前字符前一个字符:
Ctrl+h
- 向回移动光标:
Ctrl+b
- 向前移动光标:
Ctrl+f
- 恢复删除的内容:
Ctrl+&
vim 快速配置
接下来用 macOS 作为例子,在新机器上,使用 vim 打造高效开发环境。
安装终端常用工具
使用 vim 打造开发环境,往往还需要借助终端组件或插件来实现。在安装过程中,需要根据提示设置环境变量等,以便能够找到相应的命令。
- 安装包管理工具brew:/bin/bash -c “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)”
- 逐个安装以下工具软件,并根据提示设置环境变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# 安装git
brew install git
cargo install git-delta
brew install lazygit
# 把~/.ssh中的私钥公钥文件拷贝过来或者重新生成(注意文件权限要正确)
# 执行命令 git config --global --edit
# 把原有的 git config 配置拷贝进去,适当调整,不要有重复
# 配置全局或仓库的user和email
# 拉代码,并 git fetch —all 验证
# 可能需要 git ls-remote -q origin in 路径,来产生fingerprint(会自动写入~/.ssh/known_hosts文件)
# 配置可参考
# https://github.com/dandavison/delta
# https://code-winder.github.io/2022/04/git-jump.html
# 安装rust
brew install rustup
brew install ruby-build
rustup component add rust-src
rustup component add rust-analyzer
# 安装 tmux
brew install tmux
# 配置 tmux
https://github.com/gpakosz/.tmux
# 安装neovim
brew install neovim
brew install vim
# 安装node.js
brew install nodes
# 安装docker
brew install --cask docker
# 安装截图工具
brew install --cask snipaste
# 安装搜索工具
# ag
brew install the_silver_searcher
# ack
brew install ack
brew install ripgrep
# 安装hosts管理工具
# 从原来的switchhosts导出hosts再在新电脑中导入
brew install --cask switchhosts
# 安装sougo输入法
brew install --cask sogouinput
配置vim
安装以下组件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 安装 SpaceVim
# 参考以下网址
https://spacevim.org/cn/quick-start-guide/
# 安装 vim-import-js
# 参考以下网址
https://github.com/Galooshi/vim-import-js
# 配置开发工具
brew install plantuml
brew install ctags
# 用于编译 go 程序,特别是有linux依赖的
docker pull golang
# 配置jekyll
gem install jekyll
gen install bundler
# 先clone博客项目
# 在jekyll博客项目中执行
bundler install
jekyll s
# 安装ycm依赖
brew install cmake
brew install llvm
brew install mono
brew install go@1.19
brew install golangci-lint
brew install gometalinter
# 配置go env,把之前的配置在新机器上配置一遍,特别是
# go mod tidy 验证git 和 host 配置(可以ping 域名)
brew install openjdk
# 打开vim后会自动安装所需插件
# 有问题时可参考 https://github.com/ycm-core/YouCompleteMe#installation
# 如果nvim无法使用ycm,可以在nvim最下方的命令行执行 :CheckHealth 得到帮助修复
# 如果编译ycm出错,可以根据提示解决或修改 third_pard/ycmd/build.py
# 设置python3命令的路径,用which python3查看
# let g:python3_host_prog='/opt/homebrew/bin/python3'
配置 SpaceVim 工具。vi ~/.SpaceVim.d/init.toml 之后添加如下配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
#=============================================================================
# dark_powered.toml --- dark powered configuration example for SpaceVim
# Copyright (c) 2016-2020 Wang Shidong & Contributors
# Author: Wang Shidong < wsdjeg at 163.com >
# URL: https://spacevim.org
# License: GPLv3
#=============================================================================
# All SpaceVim option below [option] section
[options]
# set spacevim theme. by default colorscheme layer is not loaded,
# if you want to use more colorscheme, please load the colorscheme
# layer
# colorscheme = "solarized8"
colorscheme = "solarized8"
colorscheme_bg = "dark"
# Disable guicolors in basic mode, many terminal do not support 24bit
# true colors
enable_guicolors = true
# Disable statusline separator, if you want to use other value, please
# install nerd fonts
statusline_separator = "arrow"
statusline_iseparator = "arrow"
buffer_index_type = 4
enable_tabline_filetype_icon = true
enable_statusline_mode = false
bootstrap_before = "myspacevim#before"
bootstrap_after = "myspacevim#after"
autocomplete_method = "ycm"
enable_ycm = true
snippet_engine = "ultisnips"
autocomplete_parens = true
filemanager = " " #为了禁用报错的插件 nerdtree
default_indent = 2
expand_tab = true # 注意:python 不能这么搞
# disabled_plugins = ["preservim/nerdtree"]
# [[custom_plugins]]
# name = 'Xuyuanp/nerdtree-git-plugin'
[[layers]]
name = "checkers"
[[layers]]
name = "colorscheme"
# solarize 主题
[[custom_plugins]]
repo = "lifepillar/vim-solarized8"
merged = 0
[[custom_plugins]]
repo = "flazz/vim-colorschemes"
merged = 0
# Enable autocomplete layer
[[layers]]
name = 'autocomplete'
auto_completion_return_key_behavior = "complete"
auto_completion_tab_key_behavior = "smart"
# cpp ycm 配置文件产生器,终端中makefile同级目录下 config_gen.py .
# vim 中 :YcmRes 重启 ycm 服务
[[custom_plugins]]
name = "rdnetto/YCM-Generator"
# [[layers]]
# name = 'shell'
# default_position = 'top'
# default_height = 30
[[layers]]
name = 'lang#c'
[[layers]]
name = 'lang#go'
[[custom_plugins]]
name = "fatih/vim-go"
[[layers]]
name = 'lang#html'
[[layers]]
name = 'lang#javascript'
# 如果 fzf 相关命令提示不存在,可以更新一下:SPUpdate fzf
[[layers]]
name = "fzf"
# FFiles [PATH]
# Ag [PATTERN]
# Rg [PATTERN]]
# History 历史buffer
# History: 历史命令
# Marks
# Commits 搜索该仓库的提交记录
# BCommits 与当前buffer相关的提交记录
# Commands 可以使用的vim命令列表
# Maps 快捷键列表
[[custom_plugins]]
name = "junegunn/fzf.vim"
[[layers]]
name = "lang#toml"
[[layers]]
name = "lang#plantuml"
[[layers]]
name = "lang#xml"
# git 浏览插件
# Git 为前缀,其他同 git
# Gdiff 左右分栏比较当前文件改动很直观
# Git log 很美观
# 其他用 shell git 命令就行
[[layers]]
name = "git"
git_plugin = 'fugitive'
# 有多个 gitLab 地址的很难适配
# Gbrowse 跳转到对应仓库网页
[[custom_plugins]]
name = "shumphrey/fugitive-gitlab.vim"
# :Flog -all 查看各个分支之间的演化关系
[[custom_plugins]]
name = "rbong/vim-flog"
[[layers]]
name = "tmux"
# Ack! 列出结果集且不消失
[[custom_plugins]]
name = "mileszs/ack.vim"
# 异步浮动终端,
# :fn yourCommand 执行命令
# :fk 关闭浮动窗口
# <C-c> 或者 :q 等也可以关闭
[[custom_plugins]]
name = "voldikss/vim-floaterm"
#[[custom_plugins]]
#name = "tenfyzhong/CompleteParameter.vim"
# vim 中显示 cpp 帮助文档
[[custom_plugins]]
name = "gauteh/vim-cppman"
# 用下划线标注当前 word
[[custom_plugins]]
name = "dominikduda/vim_current_word"
# 高亮单个文件感兴趣的word,结合 * 可以实现跨文件
# 主要用到 \k 和 \K
[[custom_plugins]]
name = "lfv89/vim-interestingwords"
# 注释代码
# gcc: 注释一行或所选多行
[[custom_plugins]]
name = "tpope/vim-commentary"
# Ranger 打开当前文件所在目录树状图
[[custom_plugins]]
name = "francoiscabrol/ranger.vim"
# bd 关闭一个buffer
[[custom_plugins]]
name = "rbgrouleff/bclose.vim"
# Deol 打开shell
# exit 退出shell
# :q 退出shell窗口
[[custom_plugins]]
name = "Shougo/deol.nvim"
# git 结果美化工具
[[custom_plugins]]
name = "dandavison/delta"
# 使用 \\ 前缀与 vim 常用的移动键,如 w、b、f、s、h、l 等
# 例如定位一个字符 c,则可以 \\s 再根据提示输入c,再看提示
# [[custom_plugins]]
# name = "easymotion/vim-easymotion"
[[custom_plugins]]
name = "ShengChangJian/a.vim"
[[custom_plugins]]
name = "ShengChangJian/vim-jekyll"
# 书签管理 https://github.com/MattesGroeger/vim-bookmarks
# mm 对该行打mark或清除
# mc 清除当前buffer的mark
# mx 清除所有buffer的mark
[[custom_plugins]]
name = "MattesGroeger/vim-bookmarks"
# undo 管理,命令前缀为 Mundo
[[custom_plugins]]
name = "simnalamburt/vim-mundo"
[[custom_plugins]]
name = "gelguy/wilder.nvim"
# vim 中完成 LeetCode 刷题,命令前缀: LeetCode
#[[custom_plugins]]
#name = "ianding1/leetcode.vim"
# 支持v模式,先选再对齐
# gaip*= 对齐所有=
# gaip2= 对齐第2个=
# vipga=
[[custom_plugins]]
name = "junegunn/vim-easy-align"
[[custom_plugins]]
name = "tmux-plugins/vim-tmux-focus-events"
# tmux 和 vim 窗口来回切换
# <C-h>
# <C-j>
# <C-k>
# <C-l>
# <C-p>
[[custom_plugins]]
name = "christoomey/vim-tmux-navigator"
# [[custom_plugins]]
# name = "907th/vim-auto-save"
配置自定义函数,vi ~/.SpaceVim.d/autoload/myspacevim.vim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
func! myspacevim#before() abort
if has("termguicolors")
set t_8f=^[[38;2;%lu;%lu;%lum
set t_8b=^[[48;2;%lu;%lu;%lum
set termguicolors
endif
" 设置python3命令的路径,用which python3查看
" 供 ycm 使用
let g:python3_host_prog='/opt/homebrew/bin/python3'
set cmdheight=2
" Set cursor shape and color
if &term =~ "xterm"
" INSERT mode
let &t_SI = "\<Esc>[6 q" . "\<Esc>]12;blue\x7"
" REPLACE mode
let &t_SR = "\<Esc>[3 q" . "\<Esc>]12;black\x7"
" NORMAL mode
let &t_EI = "\<Esc>[2 q" . "\<Esc>]12;green\x7"
endif
" 1 -> blinking block 闪烁的方块
" 2 -> solid block 不闪烁的方块
" 3 -> blinking underscore 闪烁的下划线
" 4 -> solid underscore 不闪烁的下划线
" 5 -> blinking vertical bar 闪烁的竖线
" 6 -> solid vertical bar 不闪烁的竖线
set cursorline cursorcolumn
" set wildmode=list:longest,full
" set wildmenu
" set wildmode=full
" set guifont=DroidSansMonoForPowerlinePlusNerdFileTypesMono:h14
set guifont=DejaVu\ Sans\ Mono\ for\ Powerline:h14
"let g:spacevim_guifont = 'DejaVu\ Sans\ Mono\ for\ Powerline\ 16'
set guioptions-=r
set tabstop = 2
filetype plugin indent on
set rtp+=~/.fzf
endf
func! myspacevim#after() abort
" a.vim 插件参数
let g:selfConfigPartPath= 'export:h:src'
"let g:alternateSearchPath= 'export,sfr:h,sfr:src,sfr'
" ianding1/leetcode.vim
let g:leetcode_browser = 'firefox'
let g:leetcode_china = 1
let g:leetcode_solution_filetype = 'golang'
" voldikss/vim-floaterm
:cabbrev fn FloatermNew
:cabbrev fk FloatermKill
" dominikduda/vim_current_word
let g:vim_current_word#highlight_only_in_focused_window = 0
" Twins of word under cursor:
let g:vim_current_word#highlight_twins = 1
" The word under cursor:
let g:vim_current_word#highlight_current_word = 1
"Ycm
"let g:ycm_confirm_extra_conf=0
let g:spacevim_enable_ycm = 1
let g:ycm_error_symbol = 'x'
inoremap <silent><expr> ( complete_parameter#pre_complete("()")
smap <a-j> <Plug>(complete_parameter#goto_next_parameter)
imap <a-j> <Plug>(complete_parameter#goto_next_parameter)
smap <a-k> <Plug>(complete_parameter#goto_previous_parameter)
imap <a-k> <Plug>(complete_parameter#goto_previous_parameter)
"let g:ycm_collect_identifiers_from_comments_and_strings = 0
"let g:ycm_add_preview_to_completeopt = 1
"let g:ycm_autoclose_preview_window_after_completion = 1
"let g:ycm_autoclose_preview_window_after_insertion = 1
nnoremap gt :YcmCompleter GoTo<CR>
nnoremap gr :YcmCompleter GoToReferences<CR>
nnoremap gv :YcmCompleter GetType<CR>
nnoremap gc :YcmCompleter GetDoc<CR>
" 分词设置
set iskeyword=A-Z,97-122,48-57,95
"set iskeyword-=*,&,!,[,],<,>,=,(,),:
set iskeyword-=33-47,58-64
set iskeyword-=:
au FileType cpp set iskeyword-=33-47,58-64
au FileType cpp set iskeyword-=:
au FileType cpp set iskeyword-=<
au FileType cpp set iskeyword-=>
au FileType cpp set iskeyword-=!
au FileType cpp set iskeyword-=*
au FileType cpp set iskeyword-=-
au FileType cpp set iskeyword-=+
au FileType cpp set iskeyword-=/
au FileType go set iskeyword-=33-47,58-64
au FileType go set iskeyword-=:
" junegunn/vim-easy-align
" Start interactive EasyAlign in visual mode (e.g. vipga)
xmap ga <Plug>(EasyAlign)
" " Start interactive EasyAlign for a motion/text object (e.g. gaip)
nmap ga <Plug>(EasyAlign)
" junegunn/fzf.vim
:cabbrev Ag Ag <C-R>=expand("<cword>")<CR><CR>
:cabbrev Rg Rg <C-R>=expand("<cword>")<CR><CR>
" Enable persistent undo so that undo history persists across vim sessions
set undofile
set undodir=~/.vim/undo
command Todo Ack! '// TODO|// FIXME|// NOTE'
" lfv89/vim-interestingwords
" let g:interestingWordsRandomiseColors = 1
let g:interestingWordsTermColors = ['154', '121', '211', '137', '214', '222']
" francoiscabrol/ranger.vim
let g:ranger_replace_netrw = 1 " open ranger when vim open a directory
let g:ranger_command_override = 'ranger --cmd "set show_hidden=true"'
" ianding1/leetcode.vim
let g:fugitive_gitlab_domains = ['https://git.bybit.com/']
" ShengChangJian/vim-jekyll
let g:jekyll_post_template = [
\ '---',
\ 'layout: post',
\ 'title: "JEKYLL_TITLE"',
\ 'date: "JEKYLL_DATE"',
\ 'categories: "JEKYLL_CATEGORIES"',
\ 'tags: "JEKYLL_TAGS"',
\ '---',
\ '']
" brew install ctags
" tagbar
" <C-F2> 打开tagbar窗口
let g:tagbar_type_go = {
\ 'ctagstype' : 'go',
\ 'kinds' : [
\ 'p:package',
\ 'i:imports:1',
\ 'c:constants',
\ 'v:variables',
\ 't:types',
\ 'n:interfaces',
\ 'w:fields',
\ 'e:embedded',
\ 'm:methods',
\ 'r:constructor',
\ 'f:functions'
\ ],
\ 'sro' : '.',
\ 'kind2scope' : {
\ 't' : 'ctype',
\ 'n' : 'ntype'
\ },
\ 'scope2kind' : {
\ 'ctype' : 't',
\ 'ntype' : 'n'
\ },
\ 'ctagsbin' : 'gotags',
\ 'ctagsargs' : '-sort -silent'
\ }
au FileType plantuml let g:plantuml_previewer#plantuml_jar_path = get(
\ matchlist(system('cat `which plantuml` | grep plantuml.jar'), '\v.*\s[''"]?(\S+plantuml\.jar).*'),
\ 1,
\ 0
\)
" Start NERDTree. If a file is specified, move the cursor to its window.
"将F3设置为开关NERDTree的快捷键
" map <F3> :NERDTreeToggle<CR>
"窗口位置
" let g:NERDTreeWinPos='right'
"打开vim时自动打开NERDTree
" autocmd vimenter * NERDTree
"不显示隐藏文件
" let g:NERDTreeHidden=0
"打开vim时如果没有文件自动打开NERDTree
" autocmd vimenter * if !argc()|NERDTree|endif
"当NERDTree为剩下的唯一窗口时自动关闭
" autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
" christoomey/vim-tmux-navigator
let g:tmux_navigator_no_mappings = 1
noremap <silent> <C-h> :<C-U>TmuxNavigateLeft<cr>
noremap <silent> <C-j> :<C-U>TmuxNavigateDown<cr>
noremap <silent> <C-k> :<C-U>TmuxNavigateUp<cr>
noremap <silent> <C-l> :<C-U>TmuxNavigateRight<cr>
noremap <silent> <C-p> :<C-U>TmuxNavigatePrevious<cr>
" gelguy/wilder.nvim
autocmd CmdlineEnter * ++once call s:wilder_init() | call wilder#main#start()
function! s:wilder_init() abort
call wilder#setup({
\ 'modes': [':', '/', '?'],
\ 'enable_cmdline_enter': 0,
\ 'next_key': '<C-n>',
\ 'previous_key': '<C-p>',
\ 'accept_key': '<C-l>',
\ 'reject_key': '<C-h>',
\ })
call wilder#set_option('renderer', wilder#popupmenu_renderer(wilder#popupmenu_palette_theme({
\ 'border': 'rounded',
\ 'max_height': '75%',
\ 'min_height': 0,
\ 'prompt_position': 'top',
\ 'reverse': 0,
\ })))
call wilder#set_option('pipeline', [
\ wilder#branch(
\ wilder#python_file_finder_pipeline({
\ 'file_command': ['find', '.', '-type', 'f', '-printf', '%P\n'],
\ 'dir_command': ['find', '.', '-type', 'd', '-printf', '%P\n'],
\ 'filters': ['fuzzy_filter', 'difflib_sorter'],
\ }),
\ wilder#cmdline_pipeline(),
\ wilder#python_search_pipeline(),
\ ),
\ ])
" Default keys
call wilder#set_option('pipeline', [
\ wilder#branch(
\ wilder#cmdline_pipeline({
\ 'fuzzy': 1,
\ 'set_pcre2_pattern': 1,
\ }),
\ wilder#python_search_pipeline({
\ 'pattern': 'fuzzy',
\ }),
\ ),
\ ])
call wilder#set_option('renderer', wilder#popupmenu_renderer({
\ 'highlighter': wilder#basic_highlighter(),
\ 'highlights': {
\ 'accent': wilder#make_hl('WilderAccent', 'Pmenu', [{}, {}, {'foreground': '#f4468f'}]),
\ },
\ }))
endfunction
endf
美化终端
- brew install ranger
- brew install highlight
- brew install tree
- brew install htop
- 配置zsh,参考https://github.com/ohmyzsh/ohmyzsh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 在 ~/.zshrc 文件中末尾添加
# 只允许开一个 tmux
if [[ -z "$TMUX" ]] ;then
ID="`tmux ls | grep -vm1 attached | cut -d: -f1`" # get the id of a deattached session
if [[ -z "$ID" ]] ;then # if not available create a new one
tmux new-session
else
tmux attach-session -t "$ID" # if available attach to it
fi
fi
export PATH="$HOME/go/bin:$PATH"
# 美化终端命令历史 ctrl-r
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
# 配置flog命令,使其与 vim 中的 flog -all 命令趋同
alias flog='git log --graph --oneline --all --decorate'
alias ll='ls -lha'
)
tmux 与 vim 窗格间相互跳转,需在 ~/.tmux.conf 文件中配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Smart pane switching with awareness of Vim splits.
# See: GitHub - christoomey/vim-tmux-navigator: Seamless navigation between tmux panes and vim splits
is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
| grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"
bind-key -n 'C-h' if-shell "$is_vim" 'send-keys C-h' 'select-pane -L'
bind-key -n 'C-j' if-shell "$is_vim" 'send-keys C-j' 'select-pane -D'
bind-key -n 'C-k' if-shell "$is_vim" 'send-keys C-k' 'select-pane -U'
bind-key -n 'C-l' if-shell "$is_vim" 'send-keys C-l' 'select-pane -R'
tmux_version='$(tmux -V | sed -En "s/^tmux ([0-9]+(.[0-9]+)?).*/\1/p")'
if-shell -b '[ "$(echo "$tmux_version < 3.0" | bc)" = 1 ]' \
"bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\' 'select-pane -l'"
if-shell -b '[ "$(echo "$tmux_version >= 3.0" | bc)" = 1 ]' \
"bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\\\' 'select-pane -l'"
bind-key -T copy-mode-vi 'C-h' select-pane -L
bind-key -T copy-mode-vi 'C-j' select-pane -D
bind-key -T copy-mode-vi 'C-k' select-pane -U
bind-key -T copy-mode-vi 'C-l' select-pane -R
bind-key -T copy-mode-vi 'C-\' select-pane -l
set -g focus-events on
插件便利功能
在“vim快速配置”一节中引入了有用的插件,本章节将列举一些高效的操作。
通用
BLines
和Lines
:列出包含所查内容的所有行,可跳转Todo
:列出含有 TODO 的文件和行Marks
:列出所有被标注的行Commands
:所有支持的vim命令Ranger
:打开文件管理器Ack
或Rg
或Ag
:搜索当前单词或函数名Tagbar
:打开tagbarFiles
:查找文件Buff
:查找buffCtrl+]
:函数跳转到定义或声明处gr
:函数被引用的所有地方Ctrl+o
和Ctrl+t
:光标回退history
: 历史命令History
: 历史bufferCommits
: 搜索该仓库的提交记录BCommits
: 与当前buffer相关的提交记录Gdiff
: 左右分栏比较当前文件改动很直观Git log
和GcLog
和Git log -p %
: 很美观GitGutterLineHighlightsToggle
:高亮或取消高亮有改动的行GitGutterFold
:把未改动的行折叠Flog -all
: 查看各个分支之间的演化关系fn yourCommand
: 执行命令fk
: 关闭浮动窗口\k
和\K
:高亮单个文件感兴趣的word,结合 * 可以实现跨文件gcc
: 注释一行或所选多行bd
: 关闭一个bufferDeol
: 打开shellmm
:对该行打mark或清除mc
:清除当前buffer的markmx
:清除所有buffer的mark- undo 管理,命令前缀为 Mundo
- gaip*= 对齐所有=
- gaip2= 对齐第2个=
- vipga= 可视模式下对齐=
go 语言
命令基本上以 Go 开头(输入:Go 之后按 ctrl+n 启用命令行情模糊筛选)
GoFillStruct
: 在输入struct名称{}后,输入该命令回车,可以默认值自动填充结构体GoAddTags json
和GoRemoveTags
:在struct内部输入该命令,可自动加或删 json tagGoIfErr
:自动生成 err 的模板代码GoTests
:自动生成所在行对应函数的测试函数GoTestFunc
、GoTest
、GoTestFile
:单元测试GoAlternate
:在源文件和测试文件之间来回跳转GoCallers
和GoCallees
:显示函数调用关系GoDebug
前缀: go debug 命令
go 编程效率工具
- jmoiron/sqlx:通过配置文件自动生成mysql的go操作代码
- orlangure/gnomock:各种中间件的mock,单元测试或集成测试时不再需要自己写mock了
- Redis
- Memcached
- MySQL
- MariaDB
- PostgreSQL
- MongoDB
- RabbitMQ
- Kafka
- Elasticsearch
- alicebob/miniredis:纯go的用于单测的redis服务端代码
- cjsaylor/sqlfixture:纯go的用于单测的mysql服务端代码
- tokopedia/gripmock:通过proto文件来mock任意的grpc服务
- k1LoW/grpcstub:grpc测试打桩
- smallnest/rpcx:rpc工具
vim 高效率操作
掌握常用的 vim 技巧可以大大减少鼠标的使用,从而使十指保持在主键盘上,减少切换的频率,最终提升编码效率,同时减少精力损耗。
模式
普通模式
修改
i
: 在光标前插入;一个小技巧:按 8,再按 i,进入插入模式,输入 =, 按 esc 进入命令模式,就会出现8个=。 这在插入分割线时非常有用,如30i+就插入了36个+组成的分割线。I
: 在当前行第一个非空字符前插入;gI
: 在当前行第一列插入;a
: 在光标后插入;A
: 在当前行最后插入;o
: 在下面新建一行插入;O
: 在上面新建一行插入;c[n]w
: 改写光标后1(n)个词。c[n]l
: 改写光标后n个字母。c[n]h
: 改写光标前n个字母。[n]cc
: 修改当前[n]行。[n]s
: 以输入的文本替代光标之后1(n)个字符,相当于c[n]l。[n]S
: 删除指定数目的行,并以所输入文本代替之。r
: 替换光标处的字符,同样支持汉字。R
: 进入替换模式,按esc回到正常模式。~
: 反转光标所在字符的大小写
注意,类似 cnw,dnw,ynw 的形式同样可以写为 ncw,ndw,nyw
删除
[n]x
: 剪切光标右边n个字符,相当于 d[n]l。[n]X
: 剪切光标左边n个字符,相当于 d[n]h。d
: 删除(剪切)在可视模式下选中的文本。d$ or D
: 删除(剪切)当前位置到行尾的内容。d[n]w
: 删除(剪切)1(n)个单词(注意,大写W规定以空格分割的词,而小写可以为其他)d[n]l
: 删除(剪切)光标右边1(n)个字符。d[n]h
: 删除(剪切)光标左边1(n)个字符。d0
: 删除(剪切)当前位置到行首的内容[n] dd
: 删除(剪切)1(n)行。:m,nd
剪切m行到n行的内容。d1G
或dgg
: 剪切光标以上的所有行。dG
: 剪切光标以下的所有行。daw
和das
:剪切一个词和剪切一个句子,即使光标不在词首和句首也没关系。d/f<cr>
:这是一个比较高级的组合命令,它将删除当前位置 到下一个 f 之间的内容。dt+定位符
:一直删除到该行的定位符处Ctrl+r
:撤销- 有时候可以把诸如空格替换成制表符,借助 Excel 删除不需要的列
选择
shift+v
:行选模式:i{
:选中光标所在中括号之间所有内容,不包括中括号i
: 选中分词符(一般为空格,除非特别指明)内的所有内容a
: 选中包括分词符(一般为空格,除非特别指明)在内的所有内容a{
:选中光标所在中括号之间所有内容,包括中括号ib / i(
:选中光标所在小括号之间所有内容,不包括小括号ab / a(
:选中光标所在小括号之间所有内容,包括小括号
以上可以和 y、c、d 等结合实现快速复制、修改、删除功能
复制
y
: 复制在可视模式下选中的文本。yy
orY
: 复制整行文本。y[n]w
: 复制一(n)个词。y[n]l: 复制光标右边 1(n) 个字符。y[n]h: 复制光标左边1(n)个字符。y$
: 从光标当前位置复制到行尾。y0
: 从光标当前位置复制到行首。:m,ny<cr>
复制m行到n行的内容。ygg
: 复制光标以上的所有行。yG
: 复制光标以下的所有行。yaw
和yas
:复制一个词和复制一个句子,即使光标不在词首和句首也没关系。
粘贴
p
: 在光标之后粘贴。P
: 在光标之前粘贴。"+y
: 复制到系统剪切板"+p
: 从系统剪切板中粘贴,- 命令行或插入模式下
Ctrl+r+寄存器符号
可粘贴相应寄存器中的内容:如可以使用yiw
复制内容,然后在命令行中使用Ctrl+r+0
粘贴
移动
ctrl+f
: 下翻一屏。ctrl+b
: 上翻一屏。ctrl+d
: 下翻半屏。ctrl+u
: 上翻半屏。M
: 移动到屏幕的中间行H
: 移动到屏幕首行L
: 移动到屏幕的末行nH
: 移动到屏幕首行下面的第n行nL
: 移动到屏幕末上上面的第n行0nl
: 表示先用命令 0 将光标移动到行首,nl 表示执行 n 次向右移动光标操作n|
: 表示使用 | 命令跳转到当前行的第 n 列ta/fa
: 移动到光标所之后第一个字符a处Ta/Fa
: 移动到光标所之前最后一个字符a处zz
: 将当前行移动到屏幕中央。zt
: 将当前行移动到屏幕顶端。zb
: 将当前行移动到屏幕底端。gg
: 移动到文件首行G
: 移动到文末$
: 从光标当前位置到行尾。0
: 从光标当前位置到行首。w
和W
: 从光标当前位置到词尾gg
: 从光标当前位置到页首G
: 从光标当前位置到页尾H
: 移动到起始点—-屏幕首行M
: 移动到屏幕的中间行L
: 移动到屏幕的末行nH
: 移动到屏幕首行下面的第n行nL
: 移动到屏幕末上上面的第n行m{a-z}
: 标记光标所在位置,局部标记,只用于当前文件。m{A-Z}
: 标记光标所在位置,全局标记。标记之后,退出 Vim, 重新启动,标记仍然有效。'{a-z}
: 移动到标记位置。'{A-Z}
: 移动到标记位置。
以上可以通过插件简单管理实现。
''
: 移动到上次修改或编辑的地方'.
: 移动到最后修改的地方Ctrl+i
或Ctrl+o
或Ctrl+t
:快进或快退ta
: 移动到所在行之后第一个字符a前一字符fa
: 移动到所在行之后第一个字符a处Ta
: 移动到所在行之前最后一个字符a的后一个字符Fa
: 移动到所在行之前最后一个字符a处0nl
或n|
: 跳转到当前行的第 n 列Ctrl+o
和Ctrl+i
: 很像浏览器上的 后退 和 前进gd
: 跳转到局部变量的定义处;gD
: 跳转到全局变量的定义处,从当前文件开头开始搜索;g;
: 上一个修改过的地方;g,
: 下一个修改过的地方;[[
: 跳转到上一个函数块开始,需要有单独一行的{。]]
: 跳转到下一个函数块开始,需要有单独一行的{。[]
: 跳转到上一个函数块结束,需要有单独一行的}。][
: 跳转到下一个函数块结束,需要有单独一行的}。[{
: 跳转到当前块开始处;]}
: 跳转到当前块结束处;[/
: 跳转到当前注释块开始处;]/
: 跳转到当前注释块结束处;%
: 不仅能移动到匹配的 (), {} 或 [] 上,而且能在 #if,#else, #endif 之间跳跃。
查找
/something
: 在后面的文本中查找something。?something
: 在前面的文本中查找something。/pattern/+number
: 将光标停在包含pattern的行后面第number行上。/pattern/-number
: 将光标停在包含pattern的行前面第number行上。f(或者F,t,T)
: 后面跟需要查找的字符。%
可以搜索与之匹配的对应的()[]{}。这个功能对于书写程序特别有用。n
: 向后查找下一个。N
: 向前查找下一个。\*
:buffer 内查找当前词- 在搜索命令中, .*[]^%/?~$这10个字符有着特殊意义,所以在使用这些字符的时候要在前面加上一个反斜杠/。而/e表示<esc>;/t表示<tab>;/r表示<cr>;/b表示<bs>
折叠
zf
– 创建折叠的命令,可以在一个可视区域上使用该命令;zf ap
– 折叠光标所在的段;zf %
– 折叠光标配对括号的部分,例如光标在{处,则折叠{}间的部分,对折叠函数很有用;zd
– 删除当前行的折叠;zD
– 删除当前行的折叠;zo
– 打开折叠的文本;zc
– 收起折叠;za
– 打开/关闭当前折叠;zr
– 打开嵌套的折行;zm
– 收起嵌套的折行;zR (zO)
– 打开所有折行;zM (zC)
– 收起所有折行;zj
– 跳到下一个折叠处;zk
– 跳到上一个折叠处;[z
到当前打开的折叠的开始处。]z
到当前打开的折叠的末尾处。zi
– enable/disable fold;
缩进
<<
向左缩进一个 shiftwidth>>
向右缩进一个 shiftwidthCTRL-T
插入模式下向右缩进CTRL-D
插入模式下向左缩进J
拼接当前行和下一行gJ
同J
,不过合并后不留空格
撤销或重做
[n]u
: 取消一(n)个改动。:undolist
– 你的撤销历史。ctrl + r
: 重做最后的改动。g+
: 转到较新的文本状态U
: 取消当前行中所有的改动。
v 模式(块模式 Ctrl+v 或 字符模式 v)
i{
、(
、<
、[
:选中括号中的所有内容iw
:选中一个单词is
:选中一个句子ip
:选中一个段落o
光标移动到选中文本的另一结尾O
光标移动到选中文本的另一角落U
或u
:把选中的文本变为大写或小写。gu(U)
接范围(如$,或G),可以把从光标当前位置到指定位置之间字母全部 转换成小写或大写。
命令模式(Esc+:)
:r filename
在当前位置插入另一个文件的内容。:[n]r filename
在第n行插入另一个文件的内容。:r !date
在光标处插入当前日期与时间。同理,:r !command可以将其它shell命令的输出插入当前文档。- 在普通模式下使用 yiw 复制,然后在命令模式下 Ctrl+r 然后输入 0 即可复制文本到 vim 命令行中
Ctrl-w
: 向前删除一个单词。Ctrl-h
: 向前删除一个字符,等同于Backspace。Ctrl-u
: 从当前位置移动到命令行开头。Ctrl-b
: 移动到命令行开头。Ctrl-e
: 移动到命令行末尾。Shift-Left
: 左移一个单词。Shift-Right
: 右移一个单词。@
: 重复上一次的冒号命令。:m,ny<cr>
复制m行到n行的内容。:s/old/new
- 用new(如果没有/new,则视为删除)替换当前行第一个old。:s/old/new/g
- 用new替换当前行所有的old。:n1,n2s/old/new/g
- 用new替换文件n1行到n2行所有的old。:%s/old/new/g
- 用new替换文件中所有的old。:%s/^/xxx/g
- 在每一行的行首插入xxx,^表示行首。:%s/$/xxx/g
- 在每一行的行尾插入xxx,$表示行尾。- 所有替换命令末尾加上c,每个替换都将需要用户确认。
- 加上i则忽略大小写
[range]g/pattern/command
:例如 :%g/^ xyz/normal dd:pwd
显示vim的工作目录。:cd path
改变vim的工作目录。
插入模式(Esc+i)
Ctrl-h
,Ctrl+w
,Ctrl-u
具有删除功能Ctrl-R {0-9a-z"%#\*+:.~=}
插入寄存器内容
补全菜单
Ctrl-p
向前切换成员;Ctrl-n
向后切换成员;Ctrl-e
退出下拉菜单,并退回到原来录入的文字;Ctrl-y
退出下拉菜单,并接受当前选项。
行选模式(shift+v)
i{
:选中光标所在中括号之间所有内容,不包括中括号a{
:选中光标所在中括号之间所有内容,包括中括号ib
/i(
:选中光标所在小括号之间所有内容,不包括小括号ab
/a(
:选中光标所在小括号之间所有内容,包括小括号
多文件或缓冲区
多缓冲区
:buffers
或:ls
或:files
– 显示缓冲区列表。ctrl+6
:在最近两个缓冲区间切换。:bn
– 下一个缓冲区。:bp
– 上一个缓冲区。:bl
– 最后一个缓冲区。:b[n]
或:[n]b
– 切换到第n个缓冲区。:nbw(ipeout)
– 彻底删除第n个缓冲区。:nbd(elete)
– 删除第n个缓冲区,并未真正删除,还在unlisted列表中。:ba[ll]
– 把所有的缓冲区在当前页中打开,每个缓冲区占一个窗口。:ls
– //列出打开的文件,带编号
多标签页
- 终端中
vim -p files
: 打开多个文件,每个文件占用一个标签页。 :tabe, tabnew
– 如果加文件名,就在新的标签中打开这个文件, 否则打开一个空缓冲区。^w gf
– 在新的标签页里打开光标下路径指定的文件。:tabn
– 切换到下一个标签。Control + PageDown,也可以。:tabp
– 切换到上一个标签。Control + PageUp,也可以。[n] gt
– 切换到下一个标签。如果前面加了 n , 就切换到第n个标签。第一个标签的序号就是1。:tab split
– 将当前缓冲区的内容在新页签中打开。:tabc[lose]
– 关闭当前的标签页。:tabo[nly]
– 关闭其它的标签页。:tabs
– 列出所有的标签页和它们包含的窗口。:tabm[ove] [N]
– 移动标签页,移动到第N个标签页之后。 如 tabm 0 当前标签页,就会变成第一个标签页。:q
、:close
(暂时关闭窗口,其内容还存在缓存中)- 标准模式下:
gt
(可能被其他插件或映射占用) ,gT
可以直接在 tab 之间切换。更多可以查看帮助 :help table , help -p
窗格分割
:split(:sp
) – 把当前窗水平分割成两个窗口(两个窗口内容一致)。(CTRL-W s 或 CTRL-W CTRL-S) —注意如果在终端下,CTRL-S可能会冻结终端,请按CTRL-Q继续。:split filename
– 水平分割窗口,并在新窗口中显示另一个文件。ctrl+w f
–水平分割出一个窗口,并在新窗口打开名称为光标所在词的文件 。C-w C-^
– 水平分割一个窗口,打开刚才编辑的文件。:vsplit(:vsp)
– 把当前窗口分割成水平分布的两个窗口。 (CTRL-W v或CTRL CTRL-V)ctrl+w o
– 只保留当前窗口
窗格关闭
:qall
– 关闭所有窗口,退出vim。:wall
– 保存所有修改过的窗口。:only
– 只保留当前窗口,关闭其它窗口。(CTRL-W o):close
– 关闭当前窗口,CTRL-W c/q 能实现同样的功能。 (象 :q :x同样工作 )
调整窗口大小
ctrl+w +
–当前窗口增高一行。也可以用n增高n行。ctrl+w -
–当前窗口减小一行。也可以用n减小n行。ctrl+w \_
–当前窗口扩展到尽可能的大。也可以用n设定行数。:resize n
– 当前窗口n行高。ctrl+w =
– 所有窗口同样高度。n ctrl+w \_
– 当前窗口的高度设定为n行。ctrl+w <
–当前窗口减少一列。也可以用n减少n列。ctrl+w >
–当前窗口增宽一列。也可以用n增宽n列。ctrl+w |
–当前窗口尽可能的宽。也可以用n设定列数。
切换和移动窗口
ctrl+w ctrl+w
: 切换到下一个窗口。或者是ctrl+w w。ctrl+w p
: 切换到前一个窗口。ctrl+w h(l,j,k)
:切换到左(右,下,上)的窗口。ctrl+w t(b)
:切换到最上(下)面的窗口。ctrl+w H(L,K,J)
: 将当前窗口移动到最左(右、上、下)面。ctrl+w r
:顺时针旋转窗口的位置。ctrl+w R
:逆时针旋转窗口的位置。ctrl+w x
:交换同列或同行的窗口的位置ctrl+w T
: 将当前的窗口移动到新的标签页上。
简便操作
重复操作(.)
We saw how the . command can be used to repeat the lasi changed. But the dot command won’t replay changes made from Vim’s command line. Instead, we can repeat the last Ex command by pressing @:
数字的增减
在编程中常常会为变量进行编号,通常很多行代码只是变量的编号不一样,而且这些编号一般是递增或递减或有相同间距等,那么我们 就可以使用yyp类似的命令进行复制,然后单独修改数字编号即可。对于修改编号有快速方法:定位到该编号,然后使用”数字+
命令配合数字使用
vim 大部分命令都可以配合数字使用,但是为了充分利用.和u命令提高效率,建议:Don’t Count if you can repeat! (因为数字表示重复命令多少次,这数字是多少呢,会增加思考点数时间,同时不易使用u命令),所以更好的选择是使用 一次命令然后用.重复该命令,这样选择余地更大,使用u命令恢复更有选择性(比如你只需要恢复一个词语,但是你使用 了 d2w 命令删除了 2 个,那么你使用u命令则恢复了2个词语,那么你还得删除一个词语)。