檔案改到一半發現自己失憶,忘記改了哪些東西,只好跟上次 git push 的狀態比較看看了。
正統作法是在 shell 下指令 git diff
,或下 git difftool
用 vimdiff 分割視窗顯示,如下圖,前者在檔案多時容易快速概觀,但單一檔案時還是 vimdiff 方便。
封存
檔案改到一半發現自己失憶,忘記改了哪些東西,只好跟上次 git push 的狀態比較看看了。
正統作法是在 shell 下指令 git diff
,或下 git difftool
用 vimdiff 分割視窗顯示,如下圖,前者在檔案多時容易快速概觀,但單一檔案時還是 vimdiff 方便。
目前看到兩個插件 hypergit、vcscommand 都可以在 Vim 裡直接顯示 diff 結果,前者是 git-diff 型式,後者是 vimdiff 型式(取出舊版內容,再切割視窗作 vimdiff)。我的需求比較接近後者,但又不想裝整支 vcscommand,於是擅自取出原始碼,改寫進 vimrc。
git rev-parse --show-prefix
git log -1 --format=format:%s\ %n%h' -- '%an' -- '%ai\ '('%ar') HEAD
git show HEAD:some_path/some_file
gist: 558647 - [.vimrc] git diff.
:GitDiff
即可切割視窗顯示目前檔案的 HEAD 版本,可加一個參數指定更早的 HEAD,例如 :GitDiff 99
取得 HEAD~99 版本。顯示後會進入 diff 模式。另外可用 echo t:git_diff_info
顯示該 commit 的簡易資訊。 :diffoff
指令可能會把本來的 foldmethod 等 diff 相關選項蓋掉,所以改用 :MyDiffOff
來關閉 diff。 :GitDiff
後,用 :GitDiffOff
快速恢復到原始狀態。(目前只支援從兩視窗的狀態復原) 艱難學習至今,提出三項。
切換 normal mode 是最硬的基本技,<Esc> 不快你立馬被打爆。
可以用 <C-[> 取代,或配合 <Leader>(預設是 \,Enter 鍵是一字或 L 型會影響其手感)或 <LocalLeader> 鍵。
例:按兩下 , 即進入 normal mode
let maplocalleader = "," noremap <LocalLeader>, <C-\><C-N> noremap! <LocalLeader>, <C-\><C-N>
GSession 配合 git branch(不過 Windows 下比較難使用 git)是管理 session 的快樂方案。參考 Vim-Taiwan 上的討論串。
因為多檔編輯需求大,但 session 操作繁瑣,所以認定首要插件就此一支。
大量招式(睇 :help quickref
)不是單純常用就能學會的,已知指令也值得翻文複習。畢竟軟體演變下來,誰比較懂得善用靠的還是知識。
:!cd $VIMRUNTIME :!aap -f ftp://ftp.vim.org/pub/vim/runtime/main.aap fetch另外安裝插件等操作動到 doc 檔案時,也需要重建一下 tag(讀 help 時用來 jump 的、類似超連結的東西)
:helptags ~/.vim/doc(其中 ~/.vim/doc 可能是其他位置,即放說明文件的地方)
預設 <F1> 等同於 :help
其實不易利用,可改為:
map <F1> :help <C-R>=expand('<cword>')<CR><CR> map <LocalLeader><F1> :tab help <C-R>=expand('<cword>')<CR><CR> xmap <F1> :<C-U>call RegStash(1)<CR>gvy:let b:tempReg=@"<CR>:call RegStash()<CR>:help <C-R>=b:tempReg<CR><CR> xmap <LocalLeader><F1> :<C-U>call RegStash(1)<CR>gvy:let b:tempReg=@"<CR>:call RegStash()<CR>:help <C-R>=b:tempReg<CR><CR>(其中 RegStash 來自暫存與還原 register 的 function,也可移掉)
在 help 文件中,預設可用 <C-]> 跳到游標所在單字的說明(類似超連結),按 <C-O> 和 <C-I> 則是在次次跳轉的位置來回(類似上一頁、下一頁),這裡也可稍微 map:
nnoremap <expr> <CR> &modifiable ? "i<CR><C-\><C-N>" : "<C-]>" nnoremap <expr> <BS> &modifiable ? "i<C-W><C-\><C-N>" : "<C-O>" nnoremap <M-Left> <C-O> nnoremap <M-Right> <C-I>
註:以上只是讓動作變簡單,要真正愛用 help,還是要親身體會、自求多福~
部分操作會將相關資訊暫存備用,例如 d 掉的文字會被放進 register 變數,以便之後貼上。
執行 vim script(例如自訂的 map)時若做了這類操作,便可能把本來的 register 等資料蓋掉。以下幾個 function 先將暫存資訊另存,以供 script 結束後還原。
gist: 555806 - [.vimrc] simple functions to save/restore position, register or mark.
:call PosStash(1) " 暫存目前游標位置 :call PosStash() " 還原游標位置 :call RegStash(1) " 暫存目前 register :call RegStash() " 還原 register :call MarkStash(1) " 暫存目前 mark :call MarkStash() " 還原 mark
一般選擇連續多行的註解時,會按 V 進入 visual mode,然後移動游標框住想要的;行數一多,懶惰就出現了。
以下簡陋模擬一個註解用的 text object,方便在 normal mode 按 vac 選取整塊註解(不含空行);同樣按 dac 刪除、yac 複製。
gist: 554634 - [.vimrc] Simple text object for continuous comment
實作上只判斷每行的第一個非空白字元是否被 syntax highlight 為 Comment,所以並不十分可靠,也僅能做 linewise 的選取。若要改善功能,可考慮導入 'comments'、'commentstring'、'filetype' 等選項(參考 EnhancedCommentify 和 tComment 的做法),不過複雜度的增加也令人卻步。
附 tComment 用的 map,若游標在註解區就反轉整塊註解,否則照常 :TComment。
map <silent><expr> <LocalLeader>ca IsInComment() ? "vac:TComment<CR>" : ":TComment<CR>"
以前都靠 PSPad 用來製作 bookmarklet 的簡易 script,現在改讓 Vim 處理。
這個 funcion 需要上一篇的 Vim funcion:使用 closure compiler 壓縮 js 文件,還有 Vim 的 ruby 支援(其實只是用來 encodeURI ……)
原始碼展開如下,但以後更新會放在 gist: 546828 - [.vimrc] make bookmarklet。
command! -nargs=* Bookmarklet call Bookmarklet(<f-args>) fun! Bookmarklet(...) let result = JsCompress(0, 0, '--compilation_level=WHITESPACE_ONLY') if len(getqflist()) == 0 && strlen(result) > 0 let reuse_win = 0 for winnr in tabpagebuflist(tabpagenr()) if bufname(winnr) == '[Bookmarklet]' exec winnr . 'wincmd w' let reuse_win = winnr endif endfor if ! reuse_win exec 'belowright 5new [Bookmarklet]' setlocal noswapfile bufhidden=wipe winfixheight filetype=javascript endif let result = substitute(result, '[\n]', '', '') setlocal buftype= call setline(1, 'javascript:(function(){' . result . '})();') if has('ruby') ruby require("uri"); VIM::Buffer.current.line = URI.escape(VIM::Buffer.current.line); else echohl WarningMsg | echomsg "No ruby support. Can't do URI encoding." | echohl None endif setlocal buftype=nofile endif endf
註:僅測試於 Cygwin console Vim + Windows 版的 java,其他環境只測過 Win32 gVim ——失敗。
通用的解決方案請參考 othree 寫的 Vim 儲存完 JavaScript 檔案後自動用 yuicompressor。
本篇特徵為:
:make
執行,故能以 Quick Fix 視窗除錯。 let jar = '/scripts/google-compiler-20100616.jar'
) :call JsCompress(1, 0, '--warning_level=DEFAULT')
:JsCompress! 1 '--compilation_level=WHITESPACE_ONLY'
au FileWritePost,BufWritePost *-debug.js :JsCompress! 1
中文檔名在 make 出錯時,quickfix 和產生的新檔是亂碼。
用了半年的 Vim,一向認為預設的 slate 加上少許自訂就相當管用,不必再創招煩人了。
直到開始調 gVim,才發現 gui 配色跟 term 實在差很多……
(對付此問題可參考依云寫的 gui2term.py,由 gui 轉出 256 term 的配色。 ——只可惜我的需求是 term2gui)
8/22 放上自訂的 colorscheme bootleg(不是 bootleq 喔)
gist: 543652 - Vim colorscheme: bootleg
Vim Tips Wiki 已經有一篇 CamelCase to under lined and vice versa 提供 visual mode 用的兩份 map。
這篇則是在 normal mode 取得游標所在的 word,若符合 CamelCase 或 under_score 型式便直接變更文字。
特別考慮游標不在 keyword 上的情形,例如 <camelCase>
,游標在 <
上也能轉換。
但游標在行尾時,因為 non-blank 的字皆被 <cword> 接受,就先不研究怎麼排除 non-keyword 了。
原始碼:gist: 541723 - [.vimrc] toggle between CamelCased/under_scored word
./configure --with-features=big
(也可加 --enable-rubyinterp
等 optional feature,詳見 ./configure --help)
make
make install
之後下 vim --version
應該就能看到新設定。
if version >= 703 set conceallevel=1 set concealcursor=nc set colorcolumn=+1 set cinoptions+=L0 set undofile set undodir=~/.vim/undofiles if !isdirectory(&undodir) call mkdir((&undodir, "p") endif map <C-ScrollWheelDown> <ScrollWheelRight> map <C-ScrollWheelUp> <ScrollWheelLeft> imap <C-ScrollWheelDown> <ScrollWheelRight> imap <C-ScrollWheelUp> <ScrollWheelLeft> endif
以 help 檔為例,平時只要把 |:autocmd| 左右的「|」塗黑,不必真的移除。
但游標移到該行時,因為 CursorLine 有上深灰,所以能識別有文字被隱藏掉。
最後在 insert mode(如圖下半部)或 visual mode,應照實顯示原文。
:e!
或下次進入 Vim 後還能 undo 的便利功能啊。 fun! s:help_rc() set number if version >= 703 set conceallevel=1 set concealcursor=nc set colorcolumn=+1 endif endf au FileType help :call s:help_rc()
因 help 類型檔案會重設 conceal 設定所以為之。
if version >= 703 hi Conceal ctermfg=240 ctermbg=Black guifg=#585860 guibg=Black hi ColorColumn ctermbg=Black guibg=Black endif
為了前述效果所用的顏色設定(換個跟我不一樣的 colorscheme 就不適用了。)
如果用了之前寫的 Vim 分頁列(tabline)設定,script 空間就會出現變數 s:tabLineTabs,內含所有分頁編號、檔名等資料。
於是可以用 FuzzyFinder 尋找分頁,例如 map
接著按 <CR> 便會跳到該分頁,按 <LocalLeader><CR> 則是關閉該分頁。(當然 g:fuf_keyOpen 系列變數要先設好)
let g:fuf_tabListener = {} function! g:fuf_tabListener.onComplete(item, method) let l:tabnr = matchstr(a:item, '\d\+') if a:method == 4 silent exec 'normal ' . l:tabnr . 'gt' else silent exec 'tabclose ' . l:tabnr endif endf function g:fuf_tabListener.onAbort() endf function! g:fuf_tabFinder() if exists("s:tabLineTabs") let l:tabList = [] for tab in s:tabLineTabs let label = tab.n . '. ' . (strlen(tab.split) > 0 ? ('(' . tab.split . ')') : '') . tab.flag . tab.filename if tab.n == tabpagenr() let label = '*' . label endif call add(l:tabList, label) endfor call fuf#callbackitem#launch('', 1, 'tabs>', g:fuf_tabListener, l:tabList, 0) endif endf nnoremap <LocalLeader>fg :call g:fuf_tabFinder()<CR>
若沒有用之前寫的 tabline 設定,也可嘗試取該 tabline 原始碼產生 s:tabLineTabs 的部分來用;或從 :tabs
抓分頁資料,再仿照 用 FuzzyFinder 尋找 register 自己建立分頁資料 list。
修改方式是重寫 tabline 這個選項,實際上頗為麻煩,因為整條 tabline 必須一次輸出,而非設定個別 tab 即可。參考 :help setting-tabline
,其中給的例子也只提示基本功能而已。
受惠於 Vim 7.3 的幾個進化,這才把 tabline 調成比較堪用的狀態。調整如下:
gist: 523783 - Vim tabline setting
因為沒寫成 plugin,只是放在 .vimrc 的 function,所以請直接改原始碼的下列項目:
let tabMinWidth = 0
let tabMaxWidth = 40
let tabMinWidthResized = 15
let tabScrollOff = 5
let tabEllipsis = '…'
let tabDivideEquel = 0
在 Vim 7.3e BETA 測試,全型字和自訂 highlight 有時會造成 tabline 重繪不正確。有先發到 vim-dev 再看看情況。
不幸地 Vim 7.3f 狀況仍然存在。
為了計算字串的實際顯示寬度(column 數),需用到新增的 strwidth()
函數。(目前程式若找不到此函數,就會改用 strlen()
,計算全型字寬度時結果便不正確)
註:關於全型半型甚至無法確定的狀況,可參考 LGJ Notes | 全型字(Full-Width)、半型字(Half-Width)。
此外 Vim 7.3 還新增了滑鼠拖曳分頁調整順序的功能,比起以往只能用 :tabmove N
方便得多。
set showtabline=2
set guioptions-=e
set ambiwidth=double
以避免 '…' 等不定寬度的字顯示錯誤。 hi TabLine cterm=underline ctermfg=15 ctermbg=242 gui=underline guibg=#6c6c6c guifg=White hi TabLineSel cterm=bold gui=NONE guifg=White hi TabLineNr cterm=underline ctermbg=238 guibg=#444444 hi TabLineNrSel cterm=bold ctermfg=45 guifg=#00d7ff hi TabLineFill cterm=reverse gui=reverse hi TabLineMore cterm=underline ctermfg=White ctermbg=236 gui=underline guifg=White guibg=#303030 hi TabLineSplitNr cterm=underline ctermfg=148 ctermbg=240 gui=underline,italic guifg=#afd700 guibg=#6c6c6c hi TabLineSplitNrSel cterm=NONE ctermfg=148 ctermbg=236 gui=NONE,italic guifg=#afd700 guibg=#303030
神奇的解法!
取得BlogId >> data:blog.blogId
不妙,我也沒留底了
大大
檔案已失聯,跪求檔案
Yeah it really works but its better to keep a towel or any kind of cloth below the stained cloth nor the stain will be absorbed by the other side of that cloth.And it really doesn't matter whether the stain is of 1 week or 1 month.
Alec is awesome! I fix nearly everything that I possibly can in my home and use youtube almost exclusively. Most posts are a constant ramble and yammering and words filling dead air space. It 's unnecessary and confusing. Alec speaks only when necessary and demonstrates each fix quickly and accurately. Camera person is completely tuned in to every move Alec makes. Thanks! Just spot on