Skip to content
Search

Vi

lastmod 2026-04-03created 2014-01-11228 edits

VIM command shortcuts VIM movement shortcuts

vi ("vee-eye", /ˈviːˈaɪ/) is, along with Emacs, the most widely used text editor in Unix environments. Bill Joy created it in 1976 as an editor to be included in early BSD releases. The name vi comes from the fact that it is a visual editor that edits a whole screen, rather than a line editor that edits one line at a time. Simple yet powerful, it has many enthusiastic users.

Today the original vi is rarely used; people generally use clones built to imitate its features. Popular clones include Vim, which touts its rich features and is included in Linux distributions; nvi, provided under the BSD license and well known for its compatibility with the behavior of the original vi; and elvis, which has its own fan base.

How to install

$ yum install vim-X11 vim-common vim-enhanced vim-minimal

Category

Example

A summary of basic usage.

  • Visual Mode
    • <C-v> or <C-q>
  • Transform.
    • >, <: (In Visual Mode) indent & unindent (select a block and use it).
    • =: (In Visual Mode) auto-format.
    • <C-a>, <C-x>: (In Visual Mode) increment/decrement numbers.
    • u, U, ~: (In Visual Mode) lowercase, uppercase, toggle case.
  • History
    • u: Undo
    • <C-r>: Redo
  • Search
    • #, *: Search backward/forward for the word under the cursor.
  • Jumplist
    • :jumps: View the jump list.
    • ctrl-i: goes forward in jump list
    • ctrl-o: goes back in jump list
  • Buffer
    • :bp: Go to the previous buffer.
    • :bn: Go to the next buffer.
    • :ls: Print the buffer list.
    • :ls!: Print the buffer list. (Also prints Unlisted buffers)
  • Macro
    • qa: Start recording a macro into register a.
    • q: (While recording a macro) stop recording the macro into the register.
    • 3@a: Run the macro in register a 3 times.
  • Marking commands.
    • :marks: Print the list of marks.
    • mA: Set a mark. Global marks use uppercase (A ~ Z) and local marks use lowercase (a ~ z).
    • :delmarks A: Delete a mark. You can list multiple marks to delete.
    • &#96;A: Go to the marked position.
    • 'A: Go to the marked position.
    • &#96;&#96;: Go to the previous (last) cursor position.
    • '': Go to the previous (last) cursor position.
    • &#96;.: Move the cursor to the previous (last) edit position.
  • Register operations.
    • "ayy, "ap: Copy/paste with register a. There are 26 registers in total, from a to z.
    • <C-R>": When used in command-line mode, pastes the contents of the default register. (Using a ~ z instead of " uses that register.)
  • Screen movement.
    • z<CR>, zt: Move the current line to the top of the screen
    • z., zz: Move the current line to the center of the screen
    • z-, zb: Move the current line to the bottom of the screen
    • ctrl-f: Scroll forward one screen.
    • ctrl-b: Scroll back one screen.
    • ctrl-u: Scroll up one half of a screen.
    • ctrl-d: Scroll down one half of a screen.
    • ctrl-y: Scroll forward one line.
    • ctrl-e: Scroll back one line.
  • Cursor movement (Text object motions; object-motions)
    • H: Move the cursor to the top of the screen
    • M: Move the cursor to the middle of the screen
    • L: Move the cursor to the bottom of the screen
    • ]]: To the start of the next section.
    • [[: To the start of the previous section
    • ][:
    • []:
    • [{: Go to the open brace (Open Brace; {).
    • ]}: Go to the close brace (Close Brace; }).
    • %: Go to the matching brace of the Pair.
  • Delete
    • dd: Delete the line the cursor is on.
    • dw: Delete one word starting from the cursor. (Includes whitespace; the part before the cursor is not deleted)
    • diw: Delete the one word under the cursor (excluding whitespace)
    • daw: Delete the one word under the cursor (including whitespace up to the next word).
  • Moving the cursor between windows (Window).
    • <C-w>h: Move the cursor to the left window
    • <C-w>j: Move the cursor to the window below
    • <C-w>k: Move the cursor to the window above
    • <C-w>l: Move the cursor to the right window
    • <C-w>w: Cycle through windows in order
    • <C-w>W: Cycle through windows in reverse order
  • Moving windows (Window). (:help window-moving)
    • <C-w>r: This rotates the windows (the first window becomes the second, the second becomes the third, and so on).
    • <C-w>x: Exchange the current window with the next one.
    • <C-w>H: Move this window to the far left.
    • <C-w>K: Move this window to the very top.
  • Resizing windows (Window).
    • <C-w>[N]-: Decrease the window's rows by N
    • <C-w>[N]=: Increase the window's rows by N
    • <C-w>[N]<: Decrease the window's columns by N
    • <C-w>[N]>: Increase the window's columns by N
  • Shell integration
    • <C-z>: Drops out to the Shell. More precisely, it sends vi to the Background. You can come back with the fg command.
  • Other commands.
    • :map: Prints the list of currently bound keymaps (Key-map).
    • :f, <C-g>: Prints information about the current file.
    • q:: Opens the command-line mode history window (Window).
    • Q: Enters Ex-mode, where you can enter ":" commands one after another. Type :visual to get out.
  • Navigation
    • C-]: Jump tag. (or alternative keys CR)
    • C-T: Prev tag. (or alternative keys BS)
    • C-O: To the previous cursor position.
    • C-I: To the next cursor position.
  • Autocompletion
  • Go to definition.
    • gd: will take you to the local declaration.
    • gD: will take you to the global declaration.
    • g*: search for the word under the cursor (like , but g on 'rain' will find words like 'rainbow').
    • g#: same as g* but in backward direction.
    • gg: To the first line.
    • G: To the last line.
    • gf: will go to the file under the cursor
    • g]: and other commands will jump to a tag definition (a tag can be a function or variable name, or more).
  • Filename
    • :echo @%: Print file path (relative)
    • :echo expand('%:p'): Print file path (absolute)
  • HEX
    • :%!xxd: View in HEX mode.
    • :%!xxd -r: View in normal TEXT mode.

Settings

:help vimrc
HELP Manual for the vimrc file.
:!echo $VIMRUNTIME
Check the Vim installation path.
:colorscheme [테마이름]
Changes the theme. Check the colors directory for the list of themes.
:help feature-list
Prints the feature list. You can check whether a feature is available with has().
:help expr-env
:help expression-syntax
Check variables
:set listchars=eol:$,tab:>-,trail:~,extends:>,precedes:<
:set list
Displays special characters (whitespace, etc.) replaced with other characters. 1
:set scrolloff=n
Keeps a margin of n lines when scrolling.
:set cursorline
:set cursorcolumn
Highlights the line and column of the current cursor.
:set filetype={원하는파일타입}
Sets the file type of the current buffer.
For example, if you open an empty buffer and type :set filetype=python, it is recognized as a Python file.
:let mapleader=","
Sets the LEADER KEY.
:echo mapleader
Prints the LEADER KEY.
:e ++enc=인코딩
Changes the encoding of the current file. (Displays it in this encoding)
After that, typing set fileencoding=utf-8 treats the current file's character set as that fileencoding. (Modifies the file) -> Can be replaced with iconv.

Basic search and replace

:%s/foo/bar/g
Find each occurrence of 'foo' (in all lines), and replace it with 'bar'.
:s/foo/bar/g
Find each occurrence of 'foo' (in the current line only), and replace it with 'bar'.
:%s/foo/bar/gc
Change each 'foo' to 'bar', but ask for confirmation first.
:%s/\<foo\>/bar/gc
Change only whole words exactly matching 'foo' to 'bar'; ask for confirmation.
:%s/foo/bar/gci
Change each 'foo' (case insensitive) to 'bar'; ask for confirmation.
This may be wanted after using :set noignorecase to make searches case sensitive (the default).
:%s/foo/bar/gcI
Change each 'foo' (case sensitive) to 'bar'; ask for confirmation.
This may be wanted after using :set ignorecase to make searches case insensitive.
:%s/^M//g
^M is CR (carriage return). Note that you must not type it literally; you have to press Ctrl+V and then Ctrl+M.
:g/profile/d
Delete lines containing the pattern ("profile").
:v/profile/d
Delete lines not containing the pattern ("profile").
:g!/^\s*"/d
Delete lines that do not contain the pattern.
:g/^\s*$/d or :v/\S/d
Delete empty lines that contain whitespace.
:s/_\([a-zA-Z0-9]*\)/\u\1/g
Converts text written in Snake case to Pascal case.
:%s/aaa/bbb/e
When the search pattern fails, do not issue an error message and, in particular, continue as if no error occurred. This is useful when chaining with a Pipe (|).
  • ex - :%s/aaa/bbb/e | %s/111/222/e
:%s/pattern/\U&/g
Converts the entire matched string (&) to uppercase.

Information

:scriptnames
Prints the list of currently LOADed vim scripts.
:function
List of available functions
:command
List of available commands
:map, :vmap
List of available Key maps
:messages
Prints the message history.
:version
Prints the same output as vim --version. The Features item lists the Runtime plugins installed at compile time.
:checkhealth
Checks the state of vim. You can check whether Python is installed and so on, or check for errors in configuration files.
In the health#provider#check item you can check the state of Providers (e.g. python, ruby, node).
:NeoBundleList
Prints the full list of plugins installed with NeoBundle.

abbreviate

You can register abbreviations.

  • A kind of autocompletion that works only in insert and command-line modes.
    • abbr: works in both insert and command-line modes.
    • iabbr: works only in insert mode
    • cabbr: works only in command-line mode
  • :ab also works.
    • That's so short it can be confusing, so I use :abbr.

Scripting

:py {python-code}
You can run Python code. You can use the vim extension with :py import vim.

Ignorecase find string

A simple way to ignore case is to use \c as below.

/\cstring

pattern

ignorecase

smartcase

matches

foo

off

-

foo

foo

on

-

foo Foo FOO

Foo

on

off

foo Foo FOO

Foo

on

on

Foo

\cfoo

-

-

foo Foo FOO

foo\C

-

-

foo

Select area command

If you want to use a command limited to the selected area (string substitution, etc.), entering a command with : in VisualMode displays the following.

:'<,'>

The command entered at this point operates only on the selected area.

Word under the cursor

expand("<cword>")

MACRO

You can specify registers from a to z. A macro is recorded as follows.

q<letter><commands>q

A macro is run as follows.

<number>@<letter>

So, the complete process looks like:

qd  start recording to register d
... your complex series of commands
q   stop recording
@d  execute your macro
@@  execute your macro again

JUMP

Buffers

  • [Stackoverflow - Vim: How do you open another No Name buffer like the one on startup?]
  • :new will create a split window with an unnamed buffer.
  • :enew will open one in the current window.
  • :vnew will open one in a vertically split window.
  • :tabnew will open one in a new tab.

Sorting

:sort
Sort
:%sort!
Reverse sort
:%sort u
Remove duplicate lines
:sort n
Numeric sort

Keymaps from a script

Use the feedkeys function.

Also, if you want to include special keys, use double quotes and the "\..." notation.

Example:

call feedkeys("\<C-Y>")

Multiple commands on one line

Chain them with a pipe (|).

:%s/aaa/bbb/e | %s/111/222/e

Check the manual with the following command:

:help :s_flags

Simple settings

set hlsearch " 검색어 하이라이팅
set nu " 줄번호
set autoindent " 자동 들여쓰기
set scrolloff=2
set wildmode=longest,list
set ts=4 "tag select
set sts=4 "st select
set sw=1 " 스크롤바 너비
set autowrite " 다른 파일로 넘어갈 때 자동 저장
set autoread " 작업 중인 파일 외부에서 변경됬을 경우 자동으로 불러옴
set cindent " C언어 자동 들여쓰기
set bs=eol,start,indent
set history=256
set laststatus=2 " 상태바 표시 항상
"set paste " 붙여넣기 계단현상 없애기
set shiftwidth=4 " 자동 들여쓰기 너비 설정
set showmatch " 일치하는 괄호 하이라이팅
set smartcase " 검색시 대소문자 구별
set smarttab
set smartindent
set softtabstop=4
set tabstop=4
set ruler " 현재 커서 위치 표시
set incsearch
set statusline=\ %<%l:%v\ [%P]%=%a\ %h%m%r\ %F\

" 마지막으로 수정된 곳에 커서를 위치함
au BufReadPost *
\ if line("'\"") > 0 && line("'\"") <= line("$") |
\ exe "norm g`\"" |
\ endif

" 파일 인코딩을 한국어로
if $LANG[0]=='k' && $LANG[1]=='o'
set fileencoding=korea
endif

" 구문 강조 사용
if has("syntax")
 syntax on
endif

" 컬러 스킴 사용
colorscheme jellybeans

Clipboard tool

If a working clipboard tool is present, the + and * registers are implicitly enabled. This lets you copy to the global clipboard when you yank. Nvim looks for the following clipboard tools in order of priority.

Use the clipboard

Copy/paste in vi

  • "+Y: Copy the current line to the clipboard.
  • "+gP: Paste text from the clipboard and move the cursor after the pasted position.

You can use keymaps as below.

map <F3> "+Y
map <F4> "+gP
vmap <F3> "+y
vmap <F4> "+gP
imap <F4> <ESC>"+gPi

Synchronized scrolling

Useful when editing text at the same position (line number), such as for multilingual support.

After splitting vertically with :vs, enter the following command in each buffer you want to synchronize.

:set scrollbind

In this case, it is better to turn off automatic line wrapping.

:set nowarp

Colors

t_Co

The t_Co option (&t_Co) is the value that Vim considers to be the maximum number of colors the host terminal can display.

It is defined as follows depending on the $TERM value in terminfo:

term

t_Co

xterm

8

xterm-256color

256

screen

8

screen-256color

256

When Vim starts, it takes the value of the TERM environment variable, queries the terminfo database with that value, and stores a lot of information about the environment in various t_... variables.

For reference, if this value is 88, see xterm-88color for details.

Copying selected text into a variable

function! s:get_visual_selection()
    let [line_start, column_start] = getpos("'<")[1:2]
    let [line_end, column_end] = getpos("'>")[1:2]
    if (line2byte(line_start) + column_start) > (line2byte(line_end) + column_end)
        let [line_start, column_start, line_end, column_end] = [line_end, column_end, line_start, column_start]
    endif
    let lines = getline(line_start, line_end)
    if empty(lines)
        return ''
    endif
    let lines[-1] = lines[-1][: column_end - (&selection ==# 'inclusive' ? 1 : 2)]
    let lines[0] = lines[0][column_start - 1:]
    return join(lines, "\n")
endfunction

Or maybe you can just copy the * register?

let v = @*

How to enter <ESC> in KeyMappings for Neovim terminal mode

When I wanted to apply a key mapping in Neovim terminal mode, using tnoremap<silent><C-L><Esc>:ClaudeCursorToggle<CR> just typed the characters. (I expected it to switch to Command Mode because of the <Esc>, but it didn't work)

The cause of the problem is that in terminal mode, <Esc> is passed to the terminal itself before it can be handled as the special key that switches vim to normal mode. So the mapping doesn't work properly and the characters get typed.

So in terminal mode you have to use <C-\><C-N> or <C-\><C-O>.

" 방법 1: 노말 모드로 완전히 전환 후 명령 실행
" <C-\><C-N>: 완전히 노말 모드로 전환 (명령 실행 후 노말 모드에 유지)
tnoremap <silent> <C-L> <C-\><C-N>:ClaudeCursorToggle<CR>

" 방법 2: 일시적으로 노말 모드 명령 하나만 실행
" <C-\><C-O>: 명령 하나만 실행하고 다시 터미널 모드로 복귀
tnoremap <silent> <C-L> <C-\><C-O>:ClaudeCursorToggle<CR>

compatible options

A set of options that control Vi compatibility. So when developing a plugin, you add the following:

" 사용자의 cpo 설정 저장
let s:save_cpo = &cpo
" Vim 기본값으로 변경 - 플러그인이 예측 가능하게 동작하도록
set cpo&vim

" ... 플러그인 코드 ...

" 사용자의 원래 설정 복구
let &cpo = s:save_cpo
unlet s:save_cpo

TIP

Vim messages to buffer

Here is how to paste the messages output by vim into a buffer. Pressing Q switches to ex mode.

:redir > messages.txt
:messages
:redir END

Switch from Ex mode to Visual mode with the :visual command. Then open the file with the :e messages.txt command.

PS. If you want to suppress output to the screen while the command is being captured, use :silent messages instead of :messages.

Replace newline

If you want to use a Newline (Enter) in the Replace string, it should look like this.

:%s/CHAR/^M/g

Here, ^M is entered by pressing Ctrl + v followed by Enter.

When a newline (\n) is replaced with the ^@ character

:%s/,/\n/g

When used like this, the newline (\n) is replaced with the ^@ character.

In conclusion, use \r instead of \n.

ALT key binding

Ctags tselect

If Ctrl+] does not work properly, you can use a different keymap as below.

nmap <leader>d :tselect <C-R>=expand("<cword>")<CR><CR>

For reference, <C-R>=expand("<cword>")<CR><CR> means to substitute the word at the current cursor position.

Here is how to print the current file name.

:echo @%

Shell setting

The default shortcuts can be checked as follows.

:help index

The Map list is shown as follows.

:verbose map
:map

Unused keys

<Plug>

This is used by plugin authors to make complex mappings available to users. In plugin code, <plug>... defines a mapping that is not an actual key sequence but that users can use as the right-hand expression in their own mappings.

Here is how to run a <Plug> command:

:execute "normal \<Plug>NiceCenterCursor"

See :h using-<Plug> for details.

Quick command in insert mode

You can run a normal mode command without leaving insert mode by using CTRL-O or CTRL-\ CTRL-O (see :help ins-special-special).

Mainly used when using normal mode commands in an inoremap.

inoremap <C-P> <C-\><C-O>:call CocActionAsync('showSignatureHelp')<cr>

How to run a script or command from the command line without 'More'

See the bin/neoinstall script of NeoBundle.

For vim:

ARGS=(
    -N  # No-compatible mode
    -u "$HOME/.vimrc"
    -c "try | NeoBundleUpdate! | finally | qall! | endtry"
    -U NONE  # GUI initializations
    -i NONE  # viminfo file
    -V1 # Verbose level 1
    -e  # Start Vim in Ex mode
    -s  # Silent mode
)
vim "${ARGS[@]}" 2>&1 | grep -v "^not found in"

For neovim:

ARGS=(
    -u "$HOME/.config/nvim/init.vim"
    -c "try | UpdateRemotePlugins | finally | qall! | endtry"
    -V1
    -es
)
nvim "${ARGS[@]}" 2>&1 | grep -v "^not found in"

How to view all Keymaps

You can check them as follows:

:map
:nmap
:imap
:vmap

They are printed to Vim's messages, which makes searching awkward. So use the redir! command (Redirection) to save them to a file:

:redir! > vim_keys.txt
:silent verbose map
:redir END

Still somewhat inconvenient. If you want to write directly into a buffer, use the put command.

:silent put =execute('map')
:silent put =execute('nmap')
:silent put =execute('imap')
:silent put =execute('vmap')

When you want to use a slash (/) in a keymap

How to stop the staircase effect when pasting

Enter paste mode:

:set paste

Leave paste mode:

set nopaste

Shortcut to toggle paste mode:

set pastetoggle=<F3>

Troubleshooting

Describes problems that can occur while using VIM.

E21: Cannot make changes, 'Modifiable' is off

Add the following to .vimrc.

set modifiable

E474: Invalid argument

An error message like the following may be printed.

E474: Invalid argument: listchars=eol:¶,tab:»

In this case, set the encoding of script files such as .vimrc correctly.

scriptencoding utf-8

Font setting

How do I make vim with netbeans_intg

See: Vim:Netbeans#How_do_I_make_vim_with_netbeans_intg

gVim GUI Setting

On Ubuntu, the GUI font may not be applied properly and can look strange. In this case, configure it as follows.

if has('gui_running')
  set guioptions-=T  " no toolbar
  colorscheme elflord
  set lines=60 columns=108 linespace=0
  if has('gui_win32')
    set guifont=DejaVu_Sans_Mono:h10:cANSI " 이 방식은 Windows에서만 가능하다.
  else
    set guifont=DejaVu\ Sans\ Mono\ 10
  endif
endif

VIM Korean localization

Download: Vim-ko-master-_4ef19e0.zip

See also

Favorite site

Cheat Sheet

Documentation

Tutorial

Guide

Project site

References


  1. http://askubuntu.com/questions/74485/how-to-display-hidden-characters-in-vim ↩

  2. Joinc-used_vim.pdf ↩

  3. Joinc.co.kr-UsedVim.zip ↩

  4. ViEditor_-_GyparkWiki.pdf ↩

  5. Learn_Vimscript_the_Hard_Way.pdf ↩

author Zer0 sitemap