VIM Editor

2018/07/21

創用CC


https://hackmd.io/p/ryg-CBkmm#/
tags: Vim, 簡報

黃柏瑄 (Huang Po Hsuan)

大二暑假不小心都拿來研究 vim my_vim
十月把自己所有的設定包成一個 plugin aben20807.vim
寒假到開學寫了三個bug滿滿的 plugin commentersurrounderrunner
還有一個寫到一半不知道何時繼續 snipmater

有任何問題都歡迎提出~


Outline

  • 簡介
  • 操作和指令
  • 休息
  • .vimrc 設定
  • plugin
  • Q&A

各種編輯器


Text Editor

  • 讓使用者可以輸入、修改、儲存文字的程式 [詳細]
  • e.g. VIM, Sublime, Notepad++, Gedit, Emacs, 記事本


Integrated Development Environment

  • 由開發所需的基本編輯、測試等軟體集合而成的電腦軟體組
    通常包含 code editor、compiler、debuger 並且有 GUI [詳細]
  • 反正就開啟時間超久(x
  • e.g. Eclipse、Visual Studio


其實有點模糊 → 主打 Editor 以上,IDE 未滿

  • e.g. Visual Studio Code, VIM(?)

真的有點模糊



選擇?

大型專案(?)、視窗類(C#, Qt)會較推薦 IDE
還有一些檔案相依性很大的 e.g. Java
不想等開啟時間就來用 vim 吧

主要還是看個人
或是看一下附近的人


這個不知道放哪裡就先講了@@

Q:

os 上沒有 vim 也没有 vi 也沒有 nano 等 editor 的時候

怎麼編輯文件啊?除了echo

A:
用 ssh?
利用 REPL 寫檔 e.g. perl、python?
https://superuser.com/a/464082


歷史


Vi IMproved

  • 原本只是模擬 vi (Vi IMitation)


https://www.quora.com/Why-is-Bram-Moolenaar-the-only-Vim-maintainer

缺點

  • 大檔案操作 (需 -u NONE)
  • 還是有些按鍵不能 map
  • plugin 過多會影響啟動速度
  • 假開源 人家是嚴謹

做個對比


缺點

  • 穩定性較低 (開發階段)
  • 跨平臺性低
  • 檔案較大
  • 反應較慢 (界面和邏輯分離)
  • 特別的功能 vim8 幾乎都有

https://twitter.com/iamdevloper/status/993821761648103425

怎麼離開 vim ?

https://conanquotes.wordpress.com/2011/11/17/tv003/

練習

  • 首先打開終端機,再輸入
$ vim
:q[uit]<enter>
:wq<enter>         " write and quit "
:q[uit]!<enter>    " 強制! "
:w[rite]<enter>

恭喜各位贏過這些人


不過

https://www.quora.com/How-did-you-master-GNU-Emacs-and-how-long-did-it-take-you

Mode

有沒有人知道 vim 總共有幾個模式? OuO

  • Normal
  • Insert
  • Visual

意義

  • 用同樣的按鍵做不同的事
  • 每個編輯器都有類似概念
  • e.g. ctrl-v 是貼上而不是打出 ctrl-v

這麼多模式

但我還是會看到有人一用 vim 編輯文件

就先按 i 進到 Insert 模式然後方向鍵移動

http://theawesomedaily.com/43-meme-faces-rage-comics-to-finally-explain-you-what-they-all-mean/

基本操作


測試檔案下載

$ curl -fLo ~/xxx.c \
    https://gist.githubusercontent.com/aben20807/c6a637586db809220d2af7c8029ce646/raw/ffa899f651c50763757bf4aa693ce9e45802020f/xxx.c

本日目標(?)

  • 不用滑鼠
  • 不用方向鍵

hackmd 也有 vim mode !!!!


為什麼不? 職業傷害(?)

https://www.careonline.com.tw/2017/12/carpal-tunnel-syndrome.html

Normal 移動

h← j↓ k↑ l→

投影片用 hjkl 也可以移動 !!!!


Normal 移動 (cont'd)

w: 下一個單字頭
hello world  -> hello world
e: 往後單字尾
hello world  -> hello world
b: 往前單字頭
hello world  -> hello world

Normal 移動 (cont'd)

fx/Fx        搜尋同一行的 x 字元
hello woxld  -'fx'->  hello woxld
heylo world  -'Fy'->  heylo world

數字前綴

4j
3w
2fx

Normal 移動 (cont'd)

gg           文件頭
G            文件尾
H/M/L        視窗上/中/下 (scrolloff)
^            移到行首
$            移到行尾

Normal 進入其他模式

i/I, a/A, s/S, o/O
v/V/ctrl-v

ESC/ctrl-[ (回到 Normal)

i/I (Insert)

hello world  -'i'->  hello world
hello world  -'I'->  hello world

a/A (Append)

hello world  -'a'->  hello world
hello world  -'A'->  hello world 

s/S (Substitute)

hello world  -'s'->  helo world
hello world  -'S'->   

o/O (Begin a new line)

hello world          hello world
hello world  -'o'->  hello world
hello world           
                     hello world
hello world          hello world
hello world  -'O'->   
hello world          hello world
                     hello world

Normal 編輯

複製     y
貼上     p
剪下     d/x
整行複製 Y/yy
整行剪下 dd
上一步   u
重做     ctrl + r

覺得多記不住是正常

但請想想你的手腕

按越少就對它越好


練習

進入 Insert模式打一些字
不打字就回到 Normal模式
試試上面的操作
既然是練習就不管手腕了請按多次一點 OuO

  • 0、^ 有什麼不一樣?
  • w/e/b 改成 W/E/B 有什麼不一樣?
  • d、x 有什麼不一樣?
  • p、P 有什麼不一樣?
  • ctrl-v 同時編輯多行

常用奇技淫巧快捷鍵


選取一個單字、"內容"

viw         Pneumonoultramicroscopicsilicovolcanoconiosis
vi"

選取整份文件

ggVG

複製到系統剪貼簿

"+y

不能複製? 檢查一下版本

$ vim --version | grep clipboard
  • clipboard 前若不是 + 號就要安裝 gvim (vim-gnome or vim-gtk)
$ sudo apt install vim-gnome

整份文件自動縮排

最適合用在別人叫你幫忙 debug,排版卻很悲劇的時候
gg=G

選取上次選取區塊

gv

交換大小寫

~

暫時跳出 vim

ctrl-z

回到剛跳出的 vim

$ fg

基本指令

通常會先打一個 :


離開

剛剛學過囉OuO

移動

:n   " 移到第 n 行 , n ∈ 非負整數 "
:-n   " 向上移 n 行 "
:+n   " 向下移 n 行 "

編輯

:e[dit] filename    " 編輯或新增 "
:vs[plit] [filename] " 不打filename就是原文件 "

搭配 :bn[ext], :bp[rev] 在多檔間移動
搭配 ctrl-w h, l 在多分割間移動


查看說明文件

:h[elp] {keyword}

休息一下吧

[松尼 instagram](https://www.instagram.com/p/BjkFSBZnmAT/?hl=zh-tw&taken-by=sweethouse.sl)

Why VIM?


客製化 !!!!


字型

vim 不支援不同 token 不同字型,但可以粗體斜體


這其實是終端機設定

https://i.imgur.com/4nJTUWk.png

不過我們先來備份吧

  • 開啟隱藏檔,應該不會有怪怪的東西 吧OuO
  • /home/ 下 .vimrc 和 .vim/

真 ⦁ 客制化


\ .vimrc / 之前

隨時隨地都可以設定 (local setting)

一樣是指令

:set nu[mber]
:set nonu[mber]
但是離開就沒有了
真 ⦁ \ .vimrc /
$ vim ~/.vimrc
:h vimrc

註解

懂你到底設定了什麼 !!!!

" 這是註解 "
" 因為沒有支援 vim 的 highlight.... "
" 正常寫左邊就好


Map

方向鍵我不想用 hjkl 可不可以? 可以
nmap i k     " n 表示 Normal, 也有 i, v... "
nmap j h
nmap k j

"   i   "
" j k l "

怪怪的?

怎麽大家都變成 h 了 @@

\recursive/

i map k map j map h


Map (cont'd)

nnoremap i k     " nore 表示 no recursive "
nnoremap j h
nnoremap k j

"   i   "
" j k l "

肌肉記憶

想改 wasd 或用方向鍵都可以
最重要的是自己順手
不過初學都會建議使用 hjkl
手的移動範圍較小

用久自然習慣在 vs code、word... 一直打hjkl (欸?

按完 ESC 會延遲?

set ttimeoutlen=100

行號顯示

set number

底線目前行

" hilight current line "
set cursorline

搜尋

" hilight serach result "
set hlsearch
" show result before typing finished "
set incsearch
" igonre case "
set ignorecase

怎麼搜尋?
/xxx、#、* 加 n、N
取消搜尋結果
:noh


縮排

" tab size "
set tabstop=4
" regard multiple spaces as tab "
set softtabstop=4
" let tab become space "
set expandtab
" indent size "
set shiftwidth=4
" auto indent "
set autoindent
set smartindent
" let line cannot wrap "
set nowrap

theme

$ curl -fLo ~/.vim/colors/ouo.vim --create-dirs \
    https://raw.githubusercontent.com/aben20807/aben20807.vim/master/colors/ouo.vim
$ vim ~/.vimrc
syntax on
set t_Co=256
colorscheme ouo

刻一個theme頗耗工費時QuQ


.vimrc 奇技淫巧


行號顯示 卍解

" show line numbers, use <F2> to switch "
nnoremap <F2> :set norelativenumber!<CR>:set nonumber!<CR>
set number
set relativenumber

回到上次編輯位置

" return to last edit position when opening files "
autocmd BufReadPost *
        \ if line("'\"") > 0 && line("'\"") <= line('$') |
        \   exe "normal! g`\"" |
        \ endif

上次位置移到視窗中間

" let cursor in the middle of screen when entering vim "
autocmd VimEnter * :exec "normal! \zz"

自動移除行末空白和文件末空行

" remove trailing whitespace when writing a buffer. "
" From: Vigil <vim5632@rainslide.net> "
function! RemoveTrailingWhitespace()
    if &ft != "diff"
        let b:curcol = col(".")
        let b:curline = line(".")
        silent! %s/\s\+$//
        silent! %s/\(\s*\n\)\+\%$//
        call cursor(b:curline, b:curcol)
    endif
endfunction
autocmd BufWritePre * call RemoveTrailingWhitespace()

還記得 ggVG ?

nnoremap <C-a> ggVG

用 tab 縮排啊

" tab indent "
vmap <TAB> >gv
vmap <S-TAB> <gv

視窗間移動還要先按 ctrl-w 好麻煩 ="=

(欸,不是說好不用方向鍵的?

" move among split windows "
nnoremap <silent> <C-Right> <C-w>l
nnoremap <silent> <C-Left>  <C-w>h
nnoremap <silent> <C-Up>    <C-w>k
nnoremap <silent> <C-Down>  <C-w>j

我打錯又怎樣(x

" command abbreviate "
cnoreabbrev WQ wq
cnoreabbrev Wq wq
cnoreabbrev W w
cnoreabbrev Q q
cnoreabbrev db bd

連離開都一鍵解決

" exit vim "
nnoremap <F10> :exec "q!"<CR>
nnoremap <F11> :exec "up"<CR>
nnoremap <F12> :exec "x"<CR>

總之就是考驗懶惰的極限

可以按一個鍵的你要按三個就輸了 (x


特殊經驗

OS commit 要 tab 但是我喜歡用空白

function! SpacesToTabs()
    execute "set expandtab"
    execute "retab"
    execute "up"
endfunction

autocmd BufRead,BufNewFile ~/col5/os/**/*.c call SpacesToTabs()
autocmd BufRead,BufNewFile ~/col5/os/**/*.h call SpacesToTabs()
autocmd VimLeave ~/col5/os/**/*.c execute "!astyle *.c *.h"
autocmd VimLeave ~/col5/os/**/*.h execute "!astyle *.c *.h"

除了 .vimrc


也常用 .vim/after/ftplugin/

針對不同的檔案類型做設定
e.g. HTML 縮排間隔跟 C++ 不一樣

" 檔名:html.vim "
setlocal tabstop=2
setlocal softtabstop=2
setlocal shiftwidth=2
" 檔名:cpp.vim "
setlocal tabstop=4
setlocal softtabstop=4
setlocal shiftwidth=4

插件 (plugin)


plugin 管理工具

雖然 vundle 不錯但我們用 vim-plug

$ curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
    https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
$ vim ~/.vimrc

.vimrc

set nocompatible
filetype off
" set the runtime path to include Vundle and initialize "
call plug#begin('~/.vim/plugged')
" 插件和設定放這裡(設定也可以放外面) "
Plug 'Yggdroot/indentLine' " 直接複製 github 作者/插件名 "
let g:indentLine_setColors = 0
let g:indentLine_char = '┊'
let g:indentLine_fileTypeExclude = ['help', 'text']
nnoremap <F3> :IndentLinesToggle<CR>
call plug#end()
filetype plugin indent on

安裝 plugin

$ vim
:PlugInstall

:qa  " 一次跳出多個視窗

推薦 plugin


vim-airline/vim-airline

vim-airline/vim-airline-themes

  • 好看一點的狀態列
  • (別懷疑我一樣自己配一個顏色,在這裡)


scrooloose/nerdtree

  • 在 vim 中瀏覽檔案


terryma/vim-multiple-cursors

  • 同時改一堆變數名稱超好用


Yggdroot/indentLine

  • 縮排指示線


w0rp/ale

  • 非同步程式碼除錯,vim 還只是 editor?


octol/vim-cpp-enhanced-highlight

  • 因為 c++ 的 keyword 比較多一點


iamcco/markdown-preview.vim

  • Markdown 即時預覽


pseewald/vim-anyfold

  • 程式碼折疊


majutsushi/tagbar

  • tag 之間快速移動


aben20807/vim-commenter

  • :star:
  • 你沒看錯 OuO
  • 懶人註解器
  • 區塊註解還有 bug 所以暫不開放


aben20807/vim-runner

  • :star:
  • 你沒看錯 again
  • 一鍵編譯加執行
  • 還可以設定用 redirection 輸入輸出
  • 我修 ACM 用這個超省時


還有時間?


寫個簡單 plugin

去後面加完分號再回來 (夠懶OuO

https://www.webdevelopersnotes.com/joke-programmer-and-hacker-funny

VimScript (VimL)

  • 其實就是在 .vimrc 寫的東西
  • vim plugin 也可用 python 寫
  • vim script 是單位行數報酬率最高的程式碼 :+1:
  • 寫 plugin 有點像在寫 pushdown automata(?)
  • 寫個幾次計理就過了

plugin 開發 SOP

  1. 在 github 新增 repo,git clone
  2. 檔案架構
  3. 用編輯器(我是用 vim)開啟檔案編輯
  4. 儲存,不要離開
  5. 開啟另一個終端機利用 vim-plug 安裝本地端 plugin
  6. 開啟 vim 測試功能
  7. ok,git add,git commit :+1:

https://me.me/i/fix-stupid-mistake-code-new-feature-get-roasted-for-coding-17298725

事不宜遲 OuO

簡化版的~


檔案架構 [詳細]

$ mkdir ~/.vim/plugged/vim-addsemi/plugin -p
vim-addsemi/
    doc/
        vim-addsemi.txt
    plugin/
        vim-addsemi.vim
    README
    LICENSE

vim-addsemi.vim

$ vim ~/.vim/plugged/vim-addsemi/plugin/vim-addsemi.vim
function! AddSemiColon()
    let b:curline = line(".")
    let b:curcol = col(".")
    execute "normal! A;\<ESC>"
    call cursor(b:curline, b:curcol)
endfunction

function! SetUpKeyMap()
    execute "nnoremap <C-e> :<C-u>call AddSemiColon()<CR>"
    execute "inoremap <C-e> <ESC>l:<C-u>call AddSemiColon()<CR>i"
endfunction

call SetUpKeyMap()

~/.vimrc

$ vim ~/.vimrc
Plug '~/.vim/plugged/vim-addsemi'

https://blog.dice.fm/swift-moves-rewriting-dice-with-apples-new-language-a183b039dc33

完成 YA

$ vim t.c


一些參考資料



Q&A

Select a repo