05.Command-Line Mode
Tip 27. Meet Vim's Command Line
Command-Line mode prompts us to enter an Ex command, a search pattern, or an expression. In this tip, we'll meet a selection of Ex commands that operate on the text in a buffer, and we'll learn about some of the special key mappings that can be used in this mode.
:
switches into Command-Line mode<Esc>
goes back to Normal mode<C-[
goes back to Normal mode
Command | Effect |
---|---|
:[range]delete [x] | Delete specified lines [into register x] |
:[range]yank [x] | Yank specified lines [into register x] |
:[line]put [x] | Put the text from register x after the specified line |
:[range]copy {address} | Copy the specified lines to below the line specified by |
:[range]move {address} | Move the specified lines to below the line specified by |
:[range]join | Join the specified lines |
:[range]normal {commands} | Execute Normal mode {commands} on each specified line |
:[range]substitute/{pattern}/{string}/[flags] | Replace occurrences of {pattern} with {string} on each specified line |
:[range]global/{pattern}/[cmd] | Execute the Ex command [cmd] on all specified lines where the {pattern} matches |
Table 7 — Ex Commands That Operate on the Text in a Buffer
We can use Ex commands to read and write files (:edit
and :write
), to create tabs (:tabnew
) or split windows (:split
), or to interact with the argument list (:prev/:next
) or the buffer list (:bprev/:bnext
). In fact, Vim has an Ex command for just about everything (see :h ex-cmd-index
for the full list).
Special Keys in Vim's Command-Line Mode
<C-w>
deletes backward to the start of the previous word<C-u>
deletes backward to the start of the line<C-v>
or<C-k>
to insert characters that are not found on the keyboard<C-r>{register}
to insert content of any register at the command line<left>
and<right>
arrow keys move the cursor
Here are some faking contents to play around with, testing <C-w>
and <C-u>
<C-h>
does not working in Insert mode<C-w>
appears most useful, just back by a word, but the key position is a bit difficult to reach<C-u>
cuts all the way back to the start of the line<C-u>
can be useful when cutting the auto-generated signs of bullets or comments
Ex Commands Strike Far and Wide
Tip 28. Execute a Command on One or More Consecutive Lines
Many Ex commands can be given a [range] of lines to act upon. We can specify the start and end of a range with either a line number, a mark, or a pattern.
In general, we could say that a range takes this form: :{start},{end}
- Use Line Numbers as an Address
:3p
print line 3
- Specify a Range of Lines by Address
:2,5p
print from line 2 to 5:.,$p
print from the current line to the end of the file:%p
print all the lines in the current file:%s/Practical/Pragmatic/
replace the first occurrence of "Practical" with "Pragmatic" on each line
- Specify a Range of Lines by Visual Selection
37G
thenVG
will select from line 37 to the end of this file, press:
- Specify a Range of Lines by Patterns
:/<html>/,/<\/html>/p
- Modify an Address Using an Offset
:/<html>/+1,/<\/html>/-1p
:.,.+3p
Symbol | Address |
---|---|
1 | First line of the file |
$ | Last line of the file |
0 | Virtual line above first line of the file |
. | Line where the cursor is placed |
'm | Line containing mark m |
'< | Start of visual selection |
'> | End of visual selection |
% | The entire file (shorthand for :1,$ ) |
Tip 29. Duplicate or Move Lines Using :t
and :m
Commands
The :copy
command (and its shorthand :t
) lets us duplicate one or more lines from one part of the document to another, while the :move
command lets us place them somewhere else in the document.
- Shopping list
- Beauty Parlor
- Buy nail polish remover
- Buy nails
- Hardware store
- Buy nails
- Buy new hammer
Duplicate Lines with the :t
Command
[range]copy {address}
Command | Effect |
---|---|
:6t. | Copy line 6 to just below the current line |
:t6 | Copy the current line to just below line 6 |
:t. | Duplicate the current line (similar to Normal mode yyp ) |
:t$ | Copy the current line to the end of the file |
:'<,'>t0 | Copy the visually selected lines to the start of the file |
<C-o>
in Normal mode
In Insert mode, <C-o>
escapes user to do one Normal mode command, and then return to the Insert mode. The same effect can be achieved by <ESC>
to Normal mode, doing the single command and then entering back to Insert mode. <C-i>
is simply a <Tab>
in Insert mode.
In Normal mode, <C-o>
and <C-i>
jump user through their "jump list", a list of places where your cursor has been to. The jumplist can be used with the quickfix feature, for example to quickly enter to a line of code containing errors.
See also the help on the jump list (:h jumplist
) in Vim.
Move Lines with the :m
Command
[range]move {address}
Vjj
then:'<,'>m$
move the selected text to the end of the file@:
repeat the last Ex command
Tip 30. Run Normal Mode Commands Across a Range
If we want to run a Normal mode command on a series of consecutive lines, we can do so using the :normal
command. When used in combination with the dot command or a macro, we can perform repetitive tasks with very little effort.
var foo = 1;
var bar = "a";
var baz = "z";
var foobar = foo + bar;
var foobarbaz = foo + bar + baz;
A;<Esc>
add to the first line,jVG
select all of the rest lines,:'<,'>normal.
repeat the last Normal command to all selected lines:%normal A;
append a semicolon at the end of every line of the file:%normal i//
comment out an entire JavaScript file:'<,'>normal A;
add a semicolon to the end of each selected lines:'<,'>normal $x
delete the last character from the end of each selected lines
Tip 31. Repeat the Last Ex Command
While the .
command can be used to repeat our most recent Normal mode command, we have to use @:
instead if we want to repeat the last Ex command. Knowing how to reverse the last command is always useful, so we'll consider that, too, in our discussion.
.
repeat the last command in Normal mode@:
repeat last Ex command in Command-Line mode
Tip 32. Tab-Complete Your Ex Command
Just like in the shell, we can use the <Tab>
key to autocomplete commands at the prompt.
- see
:h command-complete
- see
:h c_CTRL-D
- see
:h 'wildmode'
With the 'wildmenu' option enabled, Vim provides a navigable list of suggestions. We can
- scroll forward through the items by pressing
<Tab>
,<C-n>
, or<Right>
, and we can - scroll backward through them with
<S-Tab>
,<C-p>
, or<Left>
It's strange that my <Tab>
does not scroll forward the color scheme list but <S-Tab>
scroll backward works perfectly as described. I'm not sure whether there is any conflicts in my vimrc
file. Check and reset the following configurations:
set wildmenu
set wildmode=list:longest,full
Tip 33. Insert the Current Word at the Command Prompt
I don't get this tip and it does appears useful or important. Save it for later.
Tip 34. Recall Commands from History
Vim records the commands that we enter in Command-Line mode and provides two ways of recalling them: scrolling through past command-lines with the cursor keys or dialing up the command-line window.
:<Up>
most recent Ex command:help<Up>
:h viminfo
/<Up>
to scroll backward through previous searches:<C-f>
to open a history window:<C-c>
If you're in the command history, pressCtrl + C
to jump down to the bottom, and then either pressCtrl + C
orEsc
to close the window completely
Meet the Command-Line Window
Tip 35. Run Commands in the Shell
We can easily invoke external programs without leaving Vim. Best of all, we can send the contents of a buffer as standard input to a command or use the standard output from an external command to populate our buffer.
Executing Programs in the Shell
:!{cmd}
(see :h :!
)
:!ls
does not work in PowerShell 7.3 + Vim 9.1:!ls
works well in PowerShell + Neovim 0.10:!ruby %
run the current Ruby file:!python %
run the current Python file- See
:h filename-modifiers
:te[rminal] [!] [{cmd}]
(see :h :terminal
)
:shell
removed in Neovim:terminal
still works in Neovim, but seems to offer limited PowerShell capabilities
Using the Contents of a Buffer for Standard Input or Output
:read !{cmd}
puts the output from the{cmd}
into our current buffer (see:h :read!
):write !sh
each line of the current buffer is executed in the shell
Filtering the Contents of a Buffer Through an External Command
:[range]!{filter}
(see :h filter
)
"A filter is a program that accepts text at standard input, changes it in some way, and sends it to standard output."
Demo on the sort
filter below appears not working as expected, and needs a second look.
first name,last name,email
john,smith,john@example.com
drew,neil,drew@vimcasts.org
jane,doe,jane@example.com
:215,217!sort -t',' -k2
first name,last name,email
jane,doe,jane@example.com
drew,neil,drew@vimcasts.org
john,smith,john@example.com
:[range]!{filter}
is the full command syntax!{motion}
is the shortcut version for the first half, with the{filter}
half to be manually typed out
Discussion
Command | Effect |
---|---|
:shell | Start a shell (return to Vim by typing exit ) |
:!{cmd} | Execute {cmd} with the shell |
:read !{cmd} | Execute {cmd} in the shell and insert its standard output below the cursor |
:[range]write !{cmd} | Execute {cmd} in the shell with [range] lines as standard input |
:[range]!{filter} | Filter the specified [range] through external program {filter} |