Vim Tips

最後更新: 2016-11-09

介紹

在 Debian 5 內的 vim 是 vim-tiny 來, 它比原本的 vim 輕巧, 不過少了許多功能 ...

最少沒有了"語法高亮"及"用上下左右鍵移位"

我們可以用以下指令安裝回原全版的 vim

apt-get install vim

目錄

  • 設定檔
  • 'modeline' option
  • Space & Tab
  • 箭嘴外的 "上下左右"
  • 多窗分割
  • 多檔案編輯
  • 快速移動
  • Undo & Redo
  • 區塊複製
  • 在 shell 上執行指令
  • 字串取代
  • 範圍操作
  • 設定功能
  • Macro
  • Bookmark
  • 實用 hotkey
  • 編碼
  • ^M
  • Format Options
  • 多了 1 byte
  • Other

 


設定檔

 

vim 共有兩個設定檔, 分別是 global 檔 及 personal 檔

它們是 /etc/vim/vimrc 及 ~/.vimrc

vimrc 的 config file 係相當有趣的, 它可以 include 東西入去, 如

source /path/to/external/file

以下是我的 .vimrc 設定

set nocompatible
" 可以用返上下左右鍵

set nu
" 顯示行數

set incsearch
" Live Search

set autoindent
set tabstop=4
" 自動縮排, 且 tab 會看成 4 個 space 寬

syntax enable
set syntax=automatic
" 啟用自動 highlight (syntax=???)

source ~/.my-vim-key
" 載入另一檔案

~/.my-vim-key

" view next buffer
map <Esc>OC <C-right>
map <C-right> <Esc>:bn<CR>
" view before buffer
map <Esc>OD <C-left>
map <C-left> <Esc>:bn<CR>
“Hot key to switch between Big5 and UTF-8
set <C-u>=^U
set <C-b>=^B
map <C-u> :set fileencoding=utf-8<CR>
map <C-b> :set fileencoding=big5<CR>

從以上檔案好易看出, " 是代表 comments

map 是綁 keyboard 鍵的功能

在 .my-vim-key上, 我用了雙重 keyboard 綁定 @@"

這是因為經 putty 後, vi-tiny 的方向鍵會失效 .....

詳細請看 Escape character

首先我把 putty 輸出的 "Ctrl+右" map 成 terminal 的 "Ctrl+右" 先

之後再綁定 vi 的 "Ctrl+右" 的功能

 


'modeline' option

 

Help

:help 'modeline'

Enabling modeline

~/.vimrc

set modeline
set modelines=5

Remark

1. Debian-based distros disables modeline by default

vim /usr/share/vim/vim*/debian.vim

2. modeline = 啟用 modeline, default 用 modelines=5

Checking

:set modeline? modelines?

modeline
modelines=3

:verbose set modeline?

modeline

Last set from ~/.vimrc

Usage

# it must be in the first or last few lines (modelines) of file

# vim: sts=4:ts=4:sw=4:paste:et

"et" 要放在最尾, 否則會唔 work

 


Space & Tab

 

Tab 與 Space 的 ASCII

hexdump -C test.txt

20 = 空格, 0a = 新行, 09 = tab

00000000  20 20 20 20 0a 09 0a                              |    ...|

 

Setting

  • et (expandtab)
  • ts (tabstop)
  • sw (shiftwidth)
  • sts (softtabstop)
  • sta (smarttab)

show current setting

 * default setting 係不會 display 出來的

:set

:set ts sw sts

expandtab (et)

# 按 "tab" 時, 會用 "ts" 數量的空格取代 tab

# real tab character use Ctrl-V<Tab>

# 建議 et 前 settings

# set 'shiftwidth' and 'softtabstop' to the same value, while leaving 'tabstop' at its default value

:set et

tabstop (ts) # default 8

在 et 情況

設定每次按 TAB 相當多小個空格

在 noet 情況

設定一個 tab 顯示成多少個空格 (沒有 et 情況下)

shiftwidth (sw) # default 8

1. Number of spaces to use for each step of autoindent.

2. shiftwidth governs indentation via ">>" (:help shift-left-right)
    set shiftwidth=8 makes it so that each >> you do will
    indent a line 8 character blocks more to the right.

 * 建議 shiftwidth=0 => 令它與 tabstop 保持一致

:set sw=0

softtabstop (sts) # Default 0 => tabs are always 'tabstop' positions

Number of spaces that a <Tab> counts for while performing editing operations

* It affects what happens when you press the <TAB> or <BS> keys.

> 空格轉換成TAB

> makes spaces feel like tabs ( i.e. Deleting 時, 將 N 個 space 當做 1 個 tab 去 Delete )

* "x"(DEL) still work on the actual characters.

noet

If softtabstop is less than tabstop

=> vim will use a combination of tabs and spaces to make up the desired spacing.

If softtabstop equals tabstop

=> vim will always use tabs.

et

vim will always use the appropriate number of spaces.

Example

:set ts=8 sts=4 noet

第一次按 Tab 鍵時, vim 會插入 4 個空格, 而不是插入一個 "tab"

(由於 ts=8 及 noet, 所以它會看成 8 空格寬)

開新行(ENTER), 按 Tab 鍵(插入 4 個空格),

再按 Tab 鍵時, vim 會刪除前面的 4 個空格, 然後插入一個 tab 字符.

Remark

1. Backspace

    在插入模式下手動輸入 4 個空格, 此時按 Backspace 鍵只能刪除一個空格.

    退出插入模式, 再進入插入模式, 就能用 Backspace 鍵一次性刪除這 4 個空格.

smarttab (sta)

on: A "Tab" in front of a line inserts blanks according to'shiftwidth'

off: A "Tab" always inserts blanks according to 'tabstop' or 'softtabstop'

What gets inserted (a <Tab> or spaces) depends on the 'expandtab' option.

將 file 內所有 tab 換成"空格"

# Change all the existing tab characters to match the current tab settings

# After the 'expandtab' option is set

:retab

OR

:%s/\t/  /g

 

某類 file 用特定的 type

~/.vimrc

autocmd FileType python setlocal shiftwidth=4 tabstop=4 expandtab autoindent softtabstop=4

 


Compatible mode in Vim

 

# When you :set compatible, all the enhancements and improvements of Vi Improved are turned off.

a "vi" command that is implemented with "vim" in compatible mode

:set nocp

 


highlight search

 

# enable

:set hlsearch

# disable

:nohlsearch

# To turn off highlighting until the next search

:noh

 


箭嘴外的 "上下左右"

 

在這裡不能不提的是, 在 tiny-vim 裡,

上下左加只能用 k, j, h, l 這一行鍵操控. 原因=不詳 = , =??

圖示:

                       k
                   h     l
                     j

 


多檔案編輯

 

多檔案編輯是指用同一個 vi 打開多個檔案, 如

vi /etc/passwd /etc/group

查看開了什麼檔案

:ls

  1 %a   "/etc/resolv.conf"             line 1
  2      "/etc/passwd"                  line 0

我們可以用以下指令在它們之間切換

:n         編輯下一個檔案
:N         編輯上一個檔案
:files     列出正在在開啟的檔案

不過, 在 vi 內用 :e [file] 打開的檔案就叫作 buffer

它們不能用 :n, :N 切換 @@" 何苦呢 ??

因此要用以下 buffer 指令

:bn            編輯下一個檔案
:bp            編輯上一個檔案
:buffers      列出正在開啟的檔案 (如同 :files)
:buffer  n    跳到開啟的 檔案n

 


多窗分割

 

:sp [filename]        啟用多窗模式
ctrl+w k               移到上面的視窗。
ctrl+w j                移到下方的視窗。
ctrl+w q                結束當前視窗 ( :q )

 

 

=======================================

快速移動:

 

w     前一個生字
b     後一個生字
%    移到相對應的 (){}[]
n|    移到第 n  column

=======================================

Undo & Redo:

 

u                 Undo
.                  Redo
:e [file]         除消所有修改(重開 file)

=======================================

區塊複製:

 

  • v           單字選擇 ("-- VISUAL --")
  • V           整行選擇 (可連續多行 "-- VISUAL LINE --")
  • ctrl+v    區塊選擇 ("-- VISUAL BLOCK --")
  • y           複製選擇了的地方
  • d           刪除選擇了的地方

 

In visual block mode, you can press I to insert text at the same position in multiple lines

Ctrl-V-> select the block -> press I -> type # -> Esc

* I 一定要大寫

help:

:h v_b_I

Visual-block Insert                     *v_b_I*

* 要 vim 才有完整支援

=======================================

在 shell 上執行指令:

 

:! command

如 :!ls

=======================================

字串取代:

 

:n1,n2s/word1/word2/
// 一次取代

它是指在 n1 與 n2 行之後, 把 word1 取代成 word2

k          //重複以上取代指令

:n1,n2s/word1/word2/g
// 執行取代直到文尾

:1,$s/word1/word2/gc
// 使用者確認 (conform) 是否要取代當前一字

 

相當於 

:%s/OLD/NEW/g

 

=======================================

範圍操作:

 

在 vim 上, 單一個數字即代表重複做之後動作幾次, 如

 

3d

代表刪除 3 行, 相等於 dd, dd, dd, 又如

 

3dw

代表刪除 3 個字, 相等於 ctrl+w, ctrl+w, ctrl+w

 

另一方面, 有 , 豆號的代表一個範圍, 如

4,7d

這個刪除 第 4 行 至 第 7 行 的內容 ~

Remark

dd 刪除一行
dw 刪除一個字
D  刪至行尾
d0 刪至行首

 


設定功能

 

顯示行號:

:set nu

自動縮排: autoindent(ai) 與 smartindent(si)

autoindent

...

smartindent

Normally 'autoindent' should also be on when using 'smartindent'.

 * When typing '#' as the first character in a new line, the indent for that line is removed

自動儲存備份檔

:set backup
// 在編輯的檔案會 backup 成 filename~

 


語法顏色(syntax)

 

# Enable(on) / Disable(off) highlight

:syntax on

# 設定用什麼 highlight

# set filetype

:set ft=dosini

# set syntax

:set syntax=dosini

# 查看此 syntax highlight 了什麼

:syntax list

No Syntax items defined for this buffer

OR

--- Syntax items ---
dosiniNumber   xxx match /\<\d\+\>/
                   match /\<\d*\.\d\+\>/
                   match /\<\d\+e[+-]\=\d\+\>/
                   links to Number
dosiniLabel    xxx match /^.\{-}=/
                   links to Type
dosiniHeader   xxx start=/^\s*\[/ end=/\]/
                   links to Special
dosiniComment  xxx match /^[#;].*$/
                   links to Comment

 

自定 Syntax

套用別人寫好的 Syntax

ls /usr/src/nginx/nginx-1.16.0/contrib/vim

ftdetect  ftplugin  indent  syntax

cp -a /usr/src/nginx/nginx-1.16.0/contrib/vim ~/.vim/

設定檔

# 用 filepath 設定 filetype

ftdetect/nginx.vim

au BufRead,BufNewFile *.nginx set ft=nginx
au BufRead,BufNewFile */etc/nginx/* set ft=nginx
au BufRead,BufNewFile */usr/local/nginx/conf/* set ft=nginx
au BufRead,BufNewFile nginx.conf set ft=nginx

# au

:au[tocmd] [group] {event} {pat} [nested] {cmd}

Add {cmd} to the list of commands that Vim will execute automatically on {event} for a file matching  {pat}.

syntax/nginx.vim

" Vim syntax file
" Language: nginx.conf

if exists("b:current_syntax")
  finish
end

" general syntax

...

 


Macro

 

q mymacro             最之後的操作建立為 mymacro
q                           中止記錄
@mymacro             執行 mymacro

 


Bookmark

 

建立

mc             // 將當前一行 bookmark 為 c

 

它支援 characters 有 a-z 不過只能用單字母

a-z 只用於當前檔案, 離開後就消失

0-9 留了給 "最近開過的檔案"月1

A-Z 係擁有永久保存能力的 bookmark 來, 而且可以跨

此外, 我們可以用 :marks 查看 bookmark 了什麼

 

跳到

'c              // 返回 bookmark c

 

刪除

:delmarks [markid] ...          // 刪除數個指定的 bookmark
:delmarks!                         // 刪除所有 bookmark

 


實用 hotkey

 

ZZ        保存並且離開 (相等於 :wq!)

ZQ        離開 !!! (相等於 :q!)

它們只會在瀏覽模式下生效

 


編碼

 

  • set encoding=utf8
  • set fileencoding=utf-8

set encoding=utf8

# 指定 Vim 內部對於文字編碼方式

# The encoding written to file.

set fileencoding=utf-8

# This is a list of character encodings considered when starting to edit an existing file.

# Vim tries to use the first mentioned character encoding. If an error is detected, the next one in the list is tried

# If all fail, 'fileencoding' is set to an empty string, which means the value of 'encoding' is used.

# (The encoding written to file.)
 


Disable automatic comment insertion

 

[方案1]

# turn off smartindenting and autoindenting

:set nosi noai

[方案2]

# turn on paste before pasting

:set paste

paste

:set nopaste

[方案2]

# 有時縮是 filetype 負責的

:filetype plugin indent off

 


^M

 

^M is a carriage return, and is commonly seen when files are copied from Windows (Control+M or ^M)

Line Feed(LF)           – \n            # a move to the next line

Carriage Return(CR) – \r             # to move the position of the cursor to the first position on the same line

 * Windows should be "CR+LF" whereas on Unix, it's just "LF"

<CRLF>  # \r\n

Unix uses 0xA for a newline character. Windows uses a combination of two characters: 0xD 0xA.

 

You can remove all the ^M characters by entering the following:

:%s/CTRL-V+CTRL-M/\r/g

 


Format Options

# check your format options:

:set formatoptions?

P.S.

縮寫 formatoptions => fo

Default:

formatoptions=tcq

# 設定

(-=)
(+=)

# formatoptions=croql

:set formatoptions-=r

# stop Vim from auto-creating comments

To disable it while hitting ENTER in insert mode

set formatoptions-=r

To disable it while hitting o or O in normal mode

set formatoptions-=o

# Help

:help fo-table

:help 'formatoptions'

 


多了 1 byte

 

vim save 單字 file 也會有 0a

cat test.js

1

hexdump -C test.js

00000000  31 0a                                             |1.|
00000002

 


Other

 

輸入特別字元

在 insert mode 內,  我們可以鍵入 ctrl+v 之後,

輸入特別字元的 ascii 碼, 那就可輸入它們

如 ctrl+v 48 是 0