aboutsummaryrefslogtreecommitdiffhomepage
path: root/vim/init/keymaps.vim
diff options
context:
space:
mode:
Diffstat (limited to 'vim/init/keymaps.vim')
-rw-r--r--vim/init/keymaps.vim448
1 files changed, 448 insertions, 0 deletions
diff --git a/vim/init/keymaps.vim b/vim/init/keymaps.vim
new file mode 100644
index 0000000..5e472d2
--- /dev/null
+++ b/vim/init/keymaps.vim
@@ -0,0 +1,448 @@
1"======================================================================
2"
3" Only for key mapping
4"
5" - COMMON_MAPPING
6" - LINKS
7" - MOVING_WITH_READLINE
8" - JUMP_TO_TABS_WITH_ALT
9" - MANAGE_TABS
10" - MANAGE_BUFFERS
11" - SURROURD_WITH_CHAR
12" - REDIRECTION_WITH_BUFFER
13" - 终端支持
14" - 编译运行
15" - 符号搜索
16"
17"======================================================================
18" vim: set ts=4 sw=4 tw=78 noet :
19
20"----------------------------------------------------------------------
21" COMMON_MAPPING
22"----------------------------------------------------------------------
23
24" Space for searching
25map <space> /
26
27" j/k will move virtual lines (lines that wrap)
28noremap <silent> <expr> j (v:count == 0 ? 'gj' : 'j')
29noremap <silent> <expr> k (v:count == 0 ? 'gk' : 'k')
30
31" Search for selected test
32vnoremap * y/\V<C-R>=escape(@",'/\')<CR><CR>
33
34" Disable highlight when <leader><cr> is pressed
35map <silent> <leader><cr> :nohlsearch<cr>
36
37" Quick move in a line
38noremap <C-h> 30h
39noremap <C-l> 30l
40
41" Paste register 0
42nnoremap <C-p> "0p
43
44" Fast saving
45nmap <leader>w :w!<cr>
46
47" Fast quit with error
48nmap <leader>cq :cc<cr>
49
50" Switch wrap
51nmap <leader>W :set wrap!<cr>
52
53" :W sudo saves the file
54" (useful for handling the permission-denied error)
55command! W execute 'w !sudo -S tee %' <bar> edit!
56
57" New tab like browser
58nmap <C-t>n :tabnew<CR>
59nmap <C-t>c :tabclose<CR>
60nmap <C-t>m :tabmove
61nmap <C-t>o :tabonly
62
63" Enter to open file
64nnoremap <CR> gf
65nnoremap gF :e <cfile><CR>
66augroup vimrc_CRfix
67 au!
68 " Quickfix, Location list, &c. remap <CR> to work as expected
69 autocmd BufReadPost quickfix nnoremap <buffer> <CR> <CR>
70 autocmd CmdwinEnter * nnoremap <buffer> <CR> <CR>
71 autocmd CmdwinEnter * nnoremap <buffer> <C-c> <C-c>
72augroup END
73
74" Open terminal
75nnoremap <leader>, :.terminal ++noclose<CR>
76vnoremap <leader>, :terminal<CR>
77
78" Toggle paste mode on and off
79map <leader>pp :setlocal paste!<cr>
80
81" Switch CWD to the directory of the open buffer
82map <leader>cd :cd %:p:h<cr>:pwd<cr>
83
84" Move one line up and down
85nnoremap <C-j> ddp
86nnoremap <C-k> ddkP
87
88" In case ALT key is not working
89" execute "set <M-1>=\e1"
90" execute "set <M-2>=\e2"
91" execute "set <M-3>=\e3"
92" execute "set <M-4>=\e4"
93" execute "set <M-5>=\e5"
94" execute "set <M-6>=\e6"
95" execute "set <M-7>=\e7"
96" execute "set <M-8>=\e8"
97" execute "set <M-9>=\e9"
98" execute "set <M-0>=\e0"
99" execute "set <M-f>=\ef"
100" execute "set <M-b>=\eb"
101" execute "set <M-d>=\ed"
102" execute "set <M-l>=\el"
103" execute "set <M-h>=\eh"
104
105" Copy from system clipboard
106nnoremap <leader>P :r !xsel -ob<CR>
107vnoremap Y :w !xsel -ib<CR>
108
109" Spell
110nnoremap <leader>ts :set spell!<CR>
111nnoremap <leader>ss ]s
112nnoremap <leader>S [s
113
114" Show full path by default
115nnoremap <C-g> 1<C-g>
116
117" Translate by Google API
118vnoremap Tz :!trans -t zh-TW -b<CR>
119vnoremap Te :!trans -t en-US -b<CR>
120
121" source .vimrc
122nnoremap <leader>so V:so<CR>
123nnoremap <leader><leader>so :source ~/.vimrc<CR>
124vnoremap so :source<CR>
125
126
127"----------------------------------------------------------------------
128" => Fast editing and reloading of vimrc configs
129"----------------------------------------------------------------------
130nnoremap <leader>e :edit $MYVIMRC<CR>
131autocmd! bufwritepost $MYVIMRC source $MYVIMRC
132
133
134"----------------------------------------------------------------------
135" MOVING_WITH_READLINE
136"----------------------------------------------------------------------
137inoremap <C-f> <Right>
138inoremap <C-b> <Left>
139inoremap <C-a> <C-o>0
140inoremap <C-e> <C-o>$
141inoremap <M-f> <S-Right>
142inoremap <M-b> <S-Left>
143inoremap <C-d> <del>
144inoremap <C-h> <BackSpace>
145inoremap <C-j> <Down>
146inoremap <C-k> <Up>
147
148set cedit=<C-x>
149cnoremap <C-f> <Right>
150cnoremap <C-b> <Left>
151cnoremap <C-a> <Home>
152cnoremap <C-e> <End>
153cnoremap <M-f> <S-Right>
154cnoremap <M-b> <S-Left>
155cnoremap <C-d> <Del>
156cnoremap <C-r> <C-d>
157cnoremap <C-h> <BackSpace>
158cnoremap <C-n> <Down>
159cnoremap <C-p> <Up>
160cnoremap <C-k> <C-x>d$<C-c>
161cnoremap <M-d> <C-x>de<C-c>
162
163" Moving with wrap
164noremap <m-j> gj
165noremap <m-k> gk
166inoremap <m-j> <c-\><c-o>gj
167inoremap <m-k> <c-\><c-o>gk
168
169
170"----------------------------------------------------------------------
171" JUMP_TO_TABS_WITH_ALT
172"----------------------------------------------------------------------
173noremap <silent><A-1> :tabn 1<CR>
174noremap <silent><A-2> :tabn 2<CR>
175noremap <silent><M-3> :tabn 3<CR>
176noremap <silent><M-4> :tabn 4<CR>
177noremap <silent><M-5> :tabn 5<CR>
178noremap <silent><M-6> :tabn 6<CR>
179noremap <silent><M-7> :tabn 7<CR>
180noremap <silent><M-8> :tabn 8<CR>
181noremap <silent><M-9> :tablast<CR>
182inoremap <silent><A-1> <Esc>:tabn 1<CR>
183inoremap <silent><A-2> <Esc>:tabn 2<CR>
184inoremap <silent><M-3> <Esc>:tabn 3<CR>
185inoremap <silent><M-4> <Esc>:tabn 4<CR>
186inoremap <silent><M-5> <Esc>:tabn 5<CR>
187inoremap <silent><M-6> <Esc>:tabn 6<CR>
188inoremap <silent><M-7> <Esc>:tabn 7<CR>
189inoremap <silent><M-8> <Esc>:tabn 8<CR>
190inoremap <silent><M-9> <Esc>:tablast<CR>
191
192
193"----------------------------------------------------------------------
194" MANAGE_TABS
195"----------------------------------------------------------------------
196
197" Useful mappings for managing tabs
198map <leader>tn :tabnew<CR>
199map <leader>to :tabonly<CR>
200map <leader>tc :tabclose<CR>
201map <leader>tm :tabmove<SPACE>
202noremap <silent><m-h> :call Tab_MoveLeft()<cr>
203noremap <silent><m-l> :call Tab_MoveRight()<cr>
204
205" Let <leader>tl toggle between this and the last accessed tab
206let g:lasttab = 1
207nmap <Leader>tl :exe "tabn ".g:lasttab<CR>
208autocmd TabLeave * let g:lasttab = tabpagenr()
209
210" Opens a new tab with the current buffer's path
211" Super useful when editing files in the same directory
212map <leader>te :tabedit <C-r>=expand("%:p:h")<cr>/
213
214" Tab move functions
215function! Tab_MoveLeft()
216 let l:tabnr = tabpagenr() - 2
217 if l:tabnr >= 0
218 exec 'tabmove '.l:tabnr
219 endif
220endfunc
221function! Tab_MoveRight()
222 let l:tabnr = tabpagenr() + 1
223 if l:tabnr <= tabpagenr('$')
224 exec 'tabmove '.l:tabnr
225 endif
226endfunc
227
228
229"----------------------------------------------------------------------
230" MANAGE_BUFFERS
231"----------------------------------------------------------------------
232
233" Open a new buffer
234nmap <leader>O :e /tmp/buffer<CR>
235
236" Next buffer
237noremap <leader>l :bn<CR>
238
239" Let <leader>l toggle between this and the last accessed buffer
240let g:lastbuffer = 1
241noremap <Tab> :exe "buffer ".g:lastbuffer<CR>
242au BufLeave * let g:lastbuffer = bufnr()
243
244"----------------------------------------------------------------------
245" SURROURD_WITH_CHAR
246"----------------------------------------------------------------------
247vnoremap S sa
248vnoremap ' <ESC>`<i'<ESC>`>la'<ESC>
249vnoremap q <ESC>`<i"<ESC>`>la"<ESC>
250vnoremap ( <ESC>`<i(<ESC>`>la)<ESC>
251vnoremap [ <ESC>`<i[<ESC>`>la]<ESC>
252vnoremap { <ESC>`<i{<ESC>`>la}<ESC>
253vnoremap ` <ESC>`<i`<ESC>`>la`<ESC>
254vnoremap <space> <ESC>`<i<space><ESC>`>la<space><ESC>
255vnoremap z <ESC>`<i「<ESC>`>la」<ESC>
256
257
258"----------------------------------------------------------------------
259" REDIRECTION_WITH_BUFFER
260"----------------------------------------------------------------------
261" Usage:
262" :Redir hi ............. show the full output of command ':hi' in a scratch window
263" :Redir !ls -al ........ show the full output of command ':!ls -al' in a scratch window
264"
265function! Redir(cmd)
266 for win in range(1, winnr('$'))
267 if getwinvar(win, 'scratch')
268 execute win . 'windo close'
269 endif
270 endfor
271 if a:cmd =~ '^!'
272 let output = system(matchstr(a:cmd, '^!\zs.*'))
273 else
274 redir => output
275 execute a:cmd
276 redir END
277 endif
278 vnew
279 let w:scratch = 1
280 setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile
281 call setline(1, split(output, "\n"))
282endfunction
283
284command! -nargs=1 -complete=command Redir silent call Redir(<q-args>)
285nnoremap <leader>rr :Redir
286
287"----------------------------------------------------------------------
288" Markdown items (temproray solution)
289"----------------------------------------------------------------------
290
291" Toggle list item in markdown: "- [ ] XXX" -> "XXX" -> "- XXX" -> "- [ ] XXX"
292autocmd FileType markdown nnoremap <buffer> <leader>i V:!sed -E '/^ *- \[.\]/ { s/^( *)- \[.\] */\1/; q; }; /^ *[^[:space:]-]/ { s/^( *)/\1- /; q; }; /^ *- / { s/^( *)- /\1- [ ] /; q; }'<CR><CR>
293autocmd FileType markdown nnoremap <buffer> <leader>I V:!sed -E 's/^( *)/\1- [ ] /'<CR><CR>
294
295" Toggle task status: "- [ ] " -> "- [x]" -> "- [.] " -> "- [ ] "
296nnoremap <leader>x V:!sed -E '/^ *- \[ \]/ { s/^( *)- \[ \]/\1- [x]/; q; }; /^ *- \[\x\]/ { s/^( *)- \[\x\]/\1- [.]/; q; }; /^ *- \[\.\]/ { s/^( *)- \[\.\]/\1- [ ]/; q; }'<CR><CR>
297
298
299"----------------------------------------------------------------------
300" Common command
301"----------------------------------------------------------------------
302" Show date selector
303nnoremap <leader>dd :r !sh -c 'LANG=en zenity --calendar --date-format="\%Y.\%m.\%d" 2>/dev/null'<CR><CR>
304nnoremap <leader>dD :r !sh -c 'LANG=en zenity --calendar --date-format="\%a \%b \%d" 2>/dev/null'<CR><CR>
305nnoremap <leader>dt :r !date +\%H:\%m<CR>A
306
307
308"----------------------------------------------------------------------
309" 窗口切换:ALT+SHIFT+hjkl
310" 传统的 CTRL+hjkl 移动窗口不适用于 vim 8.1 的终端模式,CTRL+hjkl 在
311" bash/zsh 及带文本界面的程序中都是重要键位需要保留,不能 tnoremap 的
312"----------------------------------------------------------------------
313noremap <m-H> <c-w>h
314noremap <m-L> <c-w>l
315noremap <m-J> <c-w>j
316noremap <m-K> <c-w>k
317inoremap <m-H> <esc><c-w>h
318inoremap <m-L> <esc><c-w>l
319inoremap <m-J> <esc><c-w>j
320inoremap <m-K> <esc><c-w>k
321
322if has('terminal') && exists(':terminal') == 2 && has('patch-8.1.1')
323 " vim 8.1 支持 termwinkey ,不需要把 terminal 切换成 normal 模式
324 " 设置 termwinkey 为 CTRL 加减号(GVIM),有些终端下是 CTRL+?
325 " 后面四个键位是搭配 termwinkey 的,如果 termwinkey 更改,也要改
326 set termwinkey=<c-_>
327 tnoremap <m-H> <c-_>h
328 tnoremap <m-L> <c-_>l
329 tnoremap <m-J> <c-_>j
330 tnoremap <m-K> <c-_>k
331 tnoremap <m-q> <c-\><c-n>
332elseif has('nvim')
333 " neovim 没有 termwinkey 支持,必须把 terminal 切换回 normal 模式
334 tnoremap <m-H> <c-\><c-n><c-w>h
335 tnoremap <m-L> <c-\><c-n><c-w>l
336 tnoremap <m-J> <c-\><c-n><c-w>j
337 tnoremap <m-K> <c-\><c-n><c-w>k
338 tnoremap <m-q> <c-\><c-n>
339endif
340
341
342
343"----------------------------------------------------------------------
344" 编译运行 C/C++ 项目
345" 详细见:http://www.skywind.me/blog/archives/2084
346"----------------------------------------------------------------------
347
348" 自动打开 quickfix window ,高度为 6
349let g:asyncrun_open = 6
350
351" 任务结束时候响铃提醒
352let g:asyncrun_bell = 1
353
354" 设置 F10 打开/关闭 Quickfix 窗口
355nnoremap <F10> :call asyncrun#quickfix_toggle(6)<cr>
356
357" F9 编译 C/C++ 文件
358nnoremap <silent> <F9> :AsyncRun gcc -Wall -O2 "$(VIM_FILEPATH)" -o "$(VIM_FILEDIR)/$(VIM_FILENOEXT)" <cr>
359
360" F5 运行文件
361nnoremap <silent> <F5> :call ExecuteFile()<cr>
362
363" F7 编译项目
364nnoremap <silent> <F7> :AsyncRun -cwd=<root> make <cr>
365
366" F8 运行项目
367nnoremap <silent> <F8> :AsyncRun -cwd=<root> -raw make run <cr>
368
369" F6 测试项目
370nnoremap <silent> <F6> :AsyncRun -cwd=<root> -raw make test <cr>
371
372" 更新 cmake
373nnoremap <silent> <F4> :AsyncRun -cwd=<root> cmake . <cr>
374
375" Windows 下支持直接打开新 cmd 窗口运行
376if has('win32') || has('win64')
377 nnoremap <silent> <F8> :AsyncRun -cwd=<root> -mode=4 make run <cr>
378endif
379
380
381"----------------------------------------------------------------------
382" F5 运行当前文件:根据文件类型判断方法,并且输出到 quickfix 窗口
383"----------------------------------------------------------------------
384function! ExecuteFile()
385 let cmd = ''
386 if index(['c', 'cpp', 'rs', 'go'], &ft) >= 0
387 " native 语言,把当前文件名去掉扩展名后作为可执行运行
388 " 写全路径名是因为后面 -cwd=? 会改变运行时的当前路径,所以写全路径
389 " 加双引号是为了避免路径中包含空格
390 let cmd = '"$(VIM_FILEDIR)/$(VIM_FILENOEXT)"'
391 elseif &ft == 'python'
392 let $PYTHONUNBUFFERED=1 " 关闭 python 缓存,实时看到输出
393 let cmd = 'python "$(VIM_FILEPATH)"'
394 elseif &ft == 'javascript'
395 let cmd = 'node "$(VIM_FILEPATH)"'
396 elseif &ft == 'perl'
397 let cmd = 'perl "$(VIM_FILEPATH)"'
398 elseif &ft == 'ruby'
399 let cmd = 'ruby "$(VIM_FILEPATH)"'
400 elseif &ft == 'php'
401 let cmd = 'php "$(VIM_FILEPATH)"'
402 elseif &ft == 'lua'
403 let cmd = 'lua "$(VIM_FILEPATH)"'
404 elseif &ft == 'zsh'
405 let cmd = 'zsh "$(VIM_FILEPATH)"'
406 elseif &ft == 'ps1'
407 let cmd = 'powershell -file "$(VIM_FILEPATH)"'
408 elseif &ft == 'vbs'
409 let cmd = 'cscript -nologo "$(VIM_FILEPATH)"'
410 elseif &ft == 'sh'
411 let cmd = 'bash "$(VIM_FILEPATH)"'
412 else
413 return
414 endif
415 " Windows 下打开新的窗口 (-mode=4) 运行程序,其他系统在 quickfix 运行
416 " -raw: 输出内容直接显示到 quickfix window 不匹配 errorformat
417 " -save=2: 保存所有改动过的文件
418 " -cwd=$(VIM_FILEDIR): 运行初始化目录为文件所在目录
419 if has('win32') || has('win64')
420 exec 'AsyncRun -cwd=$(VIM_FILEDIR) -raw -save=2 -mode=4 '. cmd
421 else
422 exec 'AsyncRun -cwd=$(VIM_FILEDIR) -raw -save=2 -mode=0 '. cmd
423 endif
424endfunc
425
426
427
428"----------------------------------------------------------------------
429" F2 在项目目录下 Grep 光标下单词,默认 C/C++/Py/Js ,扩展名自己扩充
430" 支持 rg/grep/findstr ,其他类型可以自己扩充
431" 不是在当前目录 grep,而是会去到当前文件所属的项目目录 project root
432" 下面进行 grep,这样能方便的对相关项目进行搜索
433"----------------------------------------------------------------------
434if executable('rg')
435 noremap <silent><F2> :AsyncRun! -cwd=<root> rg -n --no-heading
436 \ --color never -g *.h -g *.c* -g *.py -g *.js -g *.vim
437 \ <C-R><C-W> "<root>" <cr>
438elseif has('win32') || has('win64')
439 noremap <silent><F2> :AsyncRun! -cwd=<root> findstr /n /s /C:"<C-R><C-W>"
440 \ "\%CD\%\*.h" "\%CD\%\*.c*" "\%CD\%\*.py" "\%CD\%\*.js"
441 \ "\%CD\%\*.vim"
442 \ <cr>
443else
444 noremap <silent><F2> :AsyncRun! -cwd=<root> grep -n -s -R <C-R><C-W>
445 \ --include='*.h' --include='*.c*' --include='*.py'
446 \ --include='*.js' --include='*.vim'
447 \ '<root>' <cr>
448endif