Table of Contents
这个系列视频来自: http://vimcasts.org/episodes/archive
作者每个月会录1-5个视频放出来.从2010年坚持到现在.
这个网站的作者经常进行 vim 课程, $250 每次.(4小时) 他也是 <Practical Vim> 的作者(豆瓣8.9分)
对tabstop 不熟悉的, 建议观看1,2,4
显示不可见字符:
set list set nolist
修改使用的不可见字符样式:
" Use the same symbols as TextMate for tabstops and EOLs set listchars=tab:▸\ ,eol:¬
tabstop: | tab符宽度 |
---|---|
softtabstop: | 使用<-键删除的时候, 删除多少宽度 |
shiftwidth: | 用>, <缩进的时候, 插入多宽. |
expandtab: | 输入的tab, shift 时, 都替换为空格. |
默认值:
tabstop = 8 softtabstop = 0 shiftwidth = 8 no expandtab
不一样会很混乱
结论:
retab
用autocommand实现对python 和Makefile 不同的缩进设置.
autocmd FileType html setlocal ts=2 sts=2 sw=2 expandtab autocmd FileType css setlocal ts=2 sts=2 sw=2 expandtab autocmd FileType javascript setlocal ts=4 sts=4 sw=4 noexpandtab
noexpandtab 的时候, retab 把space 变成tab, expandtab 的时候 retab 把tab变成space.
不错的函数例子, 保存当前位置:
function! <SID>StripTrailingWhitespaces() " Preparation: save last search, and cursor position. let _s=@/ let l = line(".") let c = col(".") " Do the business: %s/\s\+$//e " Clean up: restore previous search history, and cursor position let @/=_s call cursor(l, c) endfunction
删除空白行
:g/^$/d
g命令:
:g 表示范围 global command
d 是一个Ex command
就是讲>> 和 << 还有:
vmap <D-[> <gv (我用tab和shift-tab) vmap <D-]> >gv
~/.vim/indent/python.vim
讲的不错:
:buffers 1 # ".recent" line 2 # 是上一个活跃buffer 2 "./notes/misc/vim_usage.rst" line 217 3 %a "./notes/misc/vim-vimcasts.rst" line 123 %a是active buffer
如果修改了一下 .recent. 就需要 bn! 才能切到下一个buffer:
:ls 1 #h + ".recent" line 3 +表示有modify, h 表示hidden 2 %a "./notes/misc/vim_usage.rst" line 217 3 a "./notes/misc/vim-vimcasts.rst" line 0
bn时不要求buffer 一定要写入:
:set hidden
:tabedit xxx.txt :tabonly :3gt, 直接到第几个tab.
map <C-1> 1gt map <C-2> 2gt map <C-3> 3gt map <C-4> 4gt map <C-5> 5gt map <C-6> 6gt map <C-7> 7gt map <C-8> 8gt map <C-9> 9gt map <C-0> :tablast<CR>
可惜在我这用不了
tabmove tabmove 1
这一节基本没有什么内容..
ASCII art
在线工具: http://patorjk.com/software/taag/#p=display&v=0&f=Bulbhead&t=hello
宏:
qavwr_jq q q 两个q作为起始和结束 a 表示放在a这个寄存器.
这一节对vim 的:
等的介绍, 对初学者是 很好的例子 .
有用hint, 如何在ctrl+v (C-V)模式下, 只替换选中的内容:
aaxxxaaaaaabbbbbb aaxxxaaaaaabbbbbb aaxxxaaaaaabbbbbb aaxxxaaaaaabbbbbb aaxxxaaaaaabbbbbb
选中后 '<,'>s/./x/g, 替换是在整个行上的. 会把ab都替换
需要加上 \%V
:'<,'>s/\%V./x/g
changelist:
:changes g; 到上一个编辑点. g,
10g; 到倒数第10个编辑点. 10 269 0 ============================ 9 197 8 #10 <nice>Creating the Vimcasts logo as ASCII art (5:47) 8 269 0 ============================ 7 232 0 6 269 0 ============================ 5 235 0 4 269 0 ============================ 3 269 0 ============================ 2 238 4 :changes 1 242 0 > 0 250 0 1 247 9 ctrl+I 2 269 0 ============================ 3 248 0 4 269 0 ============================ 5 239 29 g; 到上一个编辑点. 6 269 0 ============================ 7 269 0 ============================ 8 240 36 10g; 到倒数第10个编辑点. 9 269 0 ============================ 10 269 0 ============================
jumplist, 比较熟悉了:
:jumps ctrl+O ctrl+I
.是对编辑命令重复, 不会对移动命令.
有用 :
:e
:help expand
map <leader>ew :e <C-R>=expand("%:p:h") . "/" <CR>
后, 通过,ew, 就可以:
e /home/ning/idning/blog_and_notes/notes/misc/
有点用处, 不过不大, 下面这个更有用些:
Thanks to Gary Bernhardt, here is a less horrible way of creating the same mappings: cnoremap %% <C-R>=fnameescape(expand('%:h')).'/'<cr> this allows you to expand the directory of the current file anywhere at the command line by pressing %%. A top tip from Max Cantor!
cmap 是命令行的map, 可以在命令行里面, 用%%表示当前文件路径, 这个收入我的.vimrc
用 :E, 用原生的目录管理器打开 一个目录, 支持排序,创建文件/目录, 删除, 重命名等:
" Netrw Directory Listing (netrw v149) " /home/ning/idning/blog_and_notes " Sorted by time " Quick Help: <F1>:help -:go up dir D:delete R:rename s:sort-by x:exec % create a new file d create a new directory R rename the file/directory under the cursor D Delete the file/directory under the cursor
关于:
set wrap set linebreak set showbreak=◀ (在被wrap的行前面加个符号)
关闭wrap:
set nowrap (此时可以用zl来向右滚动)
开启wrap:
set wrap
此时默认是会断开单词的, 可以用 :set linebreak, 设置为不断开单词, (这和 :set list 是冲突的)
有用: 有wrap时候的移动 :
0 , $ , k , j 等前面加上 g , 就是按照break后的行来移动了(按照显示行移动)
未看
强制断行.
选中一段``gq``就是按照80列格式化,
the textwidth setting is a number representing the maximum allowed width of a line. when set to zero, which is the default, vim will use the full width of the window up to a maximum of 80 characters. when set to a value above zero, vim will format lines of text so as not to exceed the value of textwidth.
相关设置:
set textwidth=xx " 一行最多多宽 默认 textwidth=0, 表示按照当前窗口宽度(但是得小于80)来做断行. set wrapmargin=xx " 断行的时候, 右边空多少个字符(set nu后就需要这个了) 如果设置了textwidth, 则这个选项没有用 默认wrapmargin=0,
::set formatoptions=tcq 默认: formatoptions=tcroql :set formatoptions+=a " 在输入的时候自动断行. 会比较奇怪. 不要设
两个format engine: formatexpr vs formatprg.
设置外部fromat engine:
:set formatprg=par
par 输出更好看, 能处理注释格式.
太复杂, 木有必要
:set spell 对txt文件有用, 写代码用不着. ~/.vim/spell/LL.EEE.add
IRB: interactive ruby shell
在irb解释器里面调用vim来编辑代码(比如定义一个多行的函数), 确实不错的特性
python 要有这个多好
surround.vim 插件
用例子讲解.
非常好的例子, 应该再看一遍 , 虽然不是很常用, 而且可以用脚本实现, 但是用的多了, 还是很有效率!!
比如 "zdw 剪切到 z 寄存器 "zP 粘贴出来, 这样的寄存器, 一般多用在宏里面.
对 ctrl+v 非常好的例子, 自己已经用习惯了:)
textmate 也有这个功能.
ctrl+v 可以用
例子:
############################ # nihao ,wo hao # # # ############################
也是例子, 没有特别的东东, 例子需要对ruby 熟悉才比较好懂.
:source $MYVIMRC autocmd bufwritepost .vimrc source $MYVIMRC
默认放在~/.vim/colors/下面:
highlight Todo guifg=#990000 guibg=NONE gui=NONE highlight link Comment Todo
对颜色没有特殊癖好.
类似Eclise <ctrl+up> <ctrl-down> 之类的功能:
" Bubble single lines nmap <C-Up> ddkP nmap <C-Down> ddp " Bubble multiple lines vmap <C-Up> xkP`[V`] vmap <C-Down> xp`[V`]
虽然自己基本不用, 不过还是 不错的tip
下面这个很有用
gV 选择刚编辑的地方:
" Visually select the text that was last edited/pasted nmap gV `[v`]
用这种方法管理模块:
Installation: git clone git://github.com/nelstrom/dotvim.git ~/.vim Create symlinks: ln -s ~/.vim/vimrc ~/.vimrc ln -s ~/.vim/gvimrc ~/.gvimrc Switch to the `~/.vim` directory, and fetch submodules: cd ~/.vim git submodule init git submodule update
附带了一个简单的github用法介绍.
Pathgon: 10年10月就有了的, 现在已然3年过去了.
我用svn+vundle.
Refining 是提炼的意思
When you press : or / in Vim, you go into commandline mode. 此时:
ctrl-p: | Show previous historical command/search |
---|---|
ctrl-n: | Show next historical command/search |
ctrl-f: | Switch from commandline mode to the co mmandline window |
在normal模式下:
command-line window, 需要练习, 对正则式来说也是不错的例子
在写command的时候, 可以用 ctrl+n 自动提示.
例子:
\v'.+' \v'[^']+' \v'('\w|[^'])+' \v'(('\w|[^'])+)'
练习
:Tab /= :Tab /:
下面这个如果用在输入等号的时候格式化应该不错:
inoremap <silent> <Bar> <Bar><Esc>:call <SID>align()<CR>a function! s:align() let p = '^\s*|\s.*\s|\s*$' if exists(':Tabularize') && getline('.') =~# '^\s*|' && (getline(line('.')-1) =~# p || getline(line('.')+1) =~# p) let column = strlen(substitute(getline('.')[0:col('.')],'[^|]','','g')) let position = strlen(matchstr(getline('.')[0:col('.')],'.*|\s*\zs.*')) Tabularize/|/l1 normal! 0 call search(repeat('[^|]*|',column).'\s\{-\}'.repeat('.',position),'ce',line('.')) endif endfunction
每次回到normal 状态的时候, 记录一个undo record, 这很重要!!
在riv.vim插件里面, 如果设置了:
let s:default.buf_imaps = { \'<BS>' : 'riv#action#ins_backspace()', \'<CR>' : 'riv#action#ins_enter()' , \'<KEnter>' : 'riv#action#ins_enter()' , ... }
这里粘贴一段多行文字的时候, 每次遇到<CR>都会切入normal模式, 造成多个undo history
自己的修改LastModified 字段的插件, 每次保存的时候, 都会生成两个undo history, undo 的时候会跳到文件头.
不少人遇到这个问题:
都没有很好解决.
我通过在python里面判断, 如果last modify 正好是当天, 就不做update, 来减少undo history
vim 7.0的特性
这里讲解非常好!!
因为undo, redo 只能在一个分支上走, 不能到一个已经被丢弃的分支, 但是可以通过 g+ , g- 回到上一个状态(可以在undo branch之间切换!) 类似时光机.
:earlier {count} Go to older text state {count} times. :earlier {N}s Go to older text state about {N} seconds before. :earlier {N}m Go to older text state about {N} minutes before. :earlier {N}h Go to older text state about {N} hours before. :earlier {N}d Go to older text state about {N} days before.
Git run任何git命令:
:Git log :Git lg :Gwrite :Gread :Gremove :Gmove
感觉没有必要
Gstatus
Gblame, Gdiff 是有点用.
Gdiff 3路merge , 太复杂.
diffput, diffget 太夫在, dp 还好
Gbrowser挺强大和方便, 但是少用
statusline显示git branch:
set statusline=%<%f\ %h%m%r%{fugitive#statusline()}%=%-14.(%l,%c%V%)\ %P
Fugitive.vim这个插件挺强大和方便, 但是这些功能太少用了 -- 很多人几乎一年浏览一下某个项目的历史项目, 就不错了.
VimGolf是一个Vim挑战网站, 从获得Prime Numbers这个例子上, 可以学习宏/正则式.
:help fold-methods
nnoremap <Space> za 不错, 很方便.
知识点不多, 基本都用惯了.
foldcolumn 是说左边有几个列是放fold标记的
使用foldmethod=marker 时, 可以用:
{{{ {{{1 这里1表示级别
Here’s the boilerplate fold expression that we used to begin with:
function! MarkdownFolds() return "0" endfunction setlocal foldmethod=expr setlocal foldexpr=MarkdownFolds()
返回值:
"0" the line is not in a fold "1", "2", ... the line is in a fold with this level "=" use fold level from the previous line ">1", ">2" a fold with this level starts at this line
可以通过这个函数, 设置fold的区域显示什么:
function! MarkdownFoldText() return getline(v:foldstart) endfunction setlocal foldtext=MarkdownFoldText()
有用但是不重要
vim --cmd 'profile start vimrc.profile' --cmd 'profile! file ~/.vimrc'
会把profile结果记录在vimrc.profile 里面
赞 , 有用技巧
没用, 不方便, 把第9行拷贝到16行:
:9copy16
拷贝到当前行:
:9t.
set relativenumber, 显示相对行号 :-7t.
:args
. 是重复上一个编辑命令 @: 是重复上一个命令模式的命令
buffer list 包含 argument list, 比如我用 lsrecent 打开一个文件后, :args 显示:
[.recent]
并不显示当前文件.
how to set the contents of the arglist using the :args command, which can receive filepaths, globs, or even backtick expressions.
比如:
:args notes/misc/vim-ctags-vs-cscope.rst
会打开这个文件.
args 有点像用 vim *.rst 这样的命令打开多个文件的时候, 带的参数 *.rst, 可以传shell 命令给args:
args `cat a.txt`
vimgrep is Vim’s built-in command for searching across multiple files. It’s not so fast as external tools like ack and git-grep, but it has its uses. vimgrep uses Vim’s built-in regex engine, so you can reuse the patterns that work with Vim’s standard search command.
不如:
ack git-grep ag
快.
grep 一个东西:
:Ack ensureIndex :grep ensureIndex * -r 会把svn 之类的grep出来. 在当前文件中找: :vimgrep /ensureIndex/g % :vimgrep /ensureIndex/g * :vimgrep /ensureIndex/g `find . -type f` 在arglist 里面搜索 :vimgrep /ensureIndex/g ##
:vim /pattern1/ `find . -type f` :vim /pattern2/ `find . -type f` :vim /pattern3/ `find . -type f`
可以换成:
:args `find . -type f` :vim /pattern1/ ## :vim /pattern2/ ## :vim /pattern3/ ##
vimgrep 的优势只有: 和vim使用同样的正则.
把quickfix 窗口里面的文件名, 放到arglist里面去, 非常有用, 但是用到这种全局替换的case不多:
command! -nargs=0 -bar Qargs execute 'args' QuickfixFilenames() function! QuickfixFilenames() " Building a hash ensures we get each buffer only once let buffer_numbers = {} for quickfix_item in getqflist() let buffer_numbers[quickfix_item['bufnr']] = bufname(quickfix_item['bufnr']) endfor return join(map(values(buffer_numbers), 'fnameescape(v:val)')) endfunction
这样, 流程变为:
用内置功能:
:vmap X y/<C-R>"<CR>
用插件:
visual-star-search plugin from github,
非常有用, 效果比之前用的 UtilVisualSelection 好.
某些时候可以替代ack 也不错:
" recursively vimgrep for word under cursor or selection if you hit leader-star nnoremap <leader>* :execute 'noautocmd vimgrep /\V' . substitute(escape(expand("<cword>"), '\'), '\n', '\\n', 'g') . '/ **'<CR> vnoremap <leader>* :<C-u>call <SID>VSetSearch()<CR>:execute 'noautocmd vimgrep /' . @/ . '/ **'<CR>
,* 这个map比 F3 也更好
abolish插件对我应该不太有用.
Abolish's killer feature is that it handles the fight between logical names & the English language. 在替换的时候能自动处理单复数, 大小写, 前后缀:
:%s/Notes/Entries/g :%s/Note/Entry/g :%s/notes/entries/g
Vspec is a library that allows you to test-drive your Vimscript code. In this tutorial, we’ll cover the basics: how to inspect the contents of a buffer, how to simulate the actions of a user, and how to invoke user-defined mappings.
可以给vim 插件写测试:
nnoremap x daw describe 'vspec' before new put! = 'Welcome to Vimcasts' end after close! end it 'can read the contents of the buffer' #一个case Expect getline(1) == "Welcome to Vimcasts" end it 'feels just like operating Vim!' #一个case normal gg$ normal daw Expect getline(1) == 'Welcome to' Expect getreg('"') == ' Vimcasts' end it 'can exercise user-defined mappings' #一个case normal gg$ normal x Expect getline(1) == 'Welcome to' Expect getreg('"') == ' Vimcasts' end end
非常赞 .
已知, 比较简单
insert下/命令模式下, 按 crtl+r 0, 粘贴0号寄存器.
表达式寄存器: "=
有用 : 编辑模式下: ctrl+r = 输入 3*5 , 插入结果
用下面这个map:
nnoremap Q 0yt=A<C-r>=<C-r>"<CR><Esc>
3*2 =
system() 函数
"= 下可以用 abs(), round(), system()之类函数
:help function-list
:put = 3+3 :put =system('echo $RANDOM')
"+y 粘贴, 不需要设置set paste:
"+gp :put +
If you’d like to make it easier to interact with the system clipboard, try out this setting,
:set clipboard=unnamed,unnamedplus
有用, 但是会破坏我在 rst_bold_it 的ctrl+c, ctrl+b, 因为这里我用了默认寄存器 " , 我换成命名寄存器 n 就好了
上面这个行为想当于 在d, x, y, p 命令前都加了"*
set paste 之后 , imap都失效了.
unimpaired 这个插件, 可以在我想要粘贴的时候, 按 yo , 此时会自动 set paste 贴完之后, 会自动 set nopaste
-对我基本没用
:windo diffthis 比较两个win. :windo diffoff
前30个非常好, 后面知识较少.