Vi-Editor

Table of Contents


Introduction

vi (short for “visual editor”) is a text editor that is widely used in Unix-like operating systems. It is a terminal-based editor, which means it can be used from a command-line interface. vi is known for its mode-based interface and for being able to perform advanced text editing tasks efficiently.

There are two main modes in vi:

  • Command mode: The mode you start in when you first open a file in vi. In this mode, you can execute commands to perform actions such as saving changes, quitting the editor, or moving the cursor.
  • Insert mode: The mode you enter when you want to insert text into a file. In this mode, you can type text normally, as if you were using a word processor.

To switch from Command mode to Insert mode, you can press the i key. To switch back to Command mode, you can press the Esc key.

Here are some basic commands you can use in vi:

  • i: Enter Insert mode.
  • Esc: Return to Command mode.
  • :w: Save changes to the file.
  • :q: Quit vi without saving changes.
  • :wq: Save changes and quit vi.
  • :x: Save changes and quit vi (same as :wq).
  • dd: Delete the current line.
  • x: Delete the character under the cursor.
  • u: Undo the last change.
  • /pattern: Search for the pattern in the file.

Note that the commands in vi must be entered in Command mode

Commands that I used

Auto-complete the words

CTRL + p

Substitute with ascending numbers:

  • Suppose we want to replace each occurrence of “abc” with “xyz_N” where N is an ascending number (xyz_1, xyz_2, xyz_3, and so on). One approach uses the following command:

    :let i=1 | g/abc/s//\='xyz_'.i/ | let i=i+1
    
  • This will replace only first occurrence of each line. There is also command that can replace all, for it look at link below.

Ref: http://vim.wikia.com/wiki/Making_a_list_of_numbers

Comment all lines contaning a pattern:

        :%s/.*pattern/#&

This command adds # to the begining of each line contaning pattern.

Ref: https://stackoverflow.com/questions/19529278/how-do-i-comment-all-lines-that-match-a-search-pattern-in-vim

To insert a file immediately after the line containing the cursor:

:r examples.txt

This inserts the contents of the file examples.txt immediately after the current line.

To insert the contents of another file after a specific line in the current file:

    23:r toc.txt

This inserts the contents of the file “toc.txt” after line 23 of the current file. Line 24 is empty; the contents of the inserted file begin at line 25. 3. kk

vi cheatsheet link

search a keyword

press Esc key to go to command mode, then type

    /keyword

then press enter. And use key “n” to search next and use “shift/Caps Lock button” to search in reverse direction

Search and replace:

go in command mode by pressing Esc key, then type

    :%s/wordToBeReplaced/NewWord/gc

then press enter. Then if you want to change the highlighted word then use “y” else use “n” to go to next word.

Several different options for search and replace

  1. :s/foo/bar/g

    Change each ‘foo’ to ‘bar’ in the current line.

  2. :%s/foo/bar/g

    Change each ‘foo’ to ‘bar’ in all the lines.

  3. :5,12s/foo/bar/g

    Change each ‘foo’ to ‘bar’ for all lines from line 5 to line 12 (inclusive).

  4. :'a,'bs/foo/bar/g

    Change each ‘foo’ to ‘bar’ for all lines from mark a to mark b inclusive.

  5. :'<,'>s/foo/bar/g

    When compiled with, +visual change each ‘foo’ to ‘bar’ for all lines within a visual selection. Vim automatically appends the visual selection range (‘<,’>) for any ex command when you select an area and enter

  6. :.,$s/foo/bar/g

    Change each ‘foo’ to ‘bar’ for all lines from the current line (.) to the last line ($) inclusive.

  7. :.,+2s/foo/bar/g

    Change each ‘foo’ to ‘bar’ for the current line (.) and the two next lines (+2).

  8. :g/^baz/s/foo/bar/g

    Change each ‘foo’ to ‘bar’ in each line starting with ‘baz’.

Ref: http://vim.wikia.com/wiki/Search_and_replace

Inserting text in multiple lines (Visual Selection)

  • Press Ctrl+V

  • Extend the visual block using jj or arrow

  • Press $ for the end of line press ^ for beginning of line.

  • Press A or Shift+i for insert mode

  • Then type anything that you want

  • Then press ESC.

Ref: http://vim.wikia.com/wiki/Inserting_text_in_multiple_lines

Search and Replace using Visual Selection

  • Press Ctrl+V

  • Extend the visual block using jj or arrow

  • when text is selected visually, press : to enter the command (when you press : then :’<,’> will automatically come)

  • example of the command:

s/red/green/g

Ref: http://vim.wikia.com/wiki/Search_and_replace_in_a_visual_selection

Mark Option in Vi:

mx => mark the current line with letter x (where x is from a to z or A to Z)

‘x => Find line marked with letter x

Usual commands like d, y, etc also work with mark option.

For detail look at ref: http://vim.wikia.com/wiki/Using_marks

Delete some characters from the end of many lines:

To delete 6 characters from the end of all line, use command:

       :%s/.\{6}$//

To list the line numbers from present line to end

       :%s/.\{1}$/\=printf('%-4d', line('.'))

How to use Recorder?

An example to replace string OldString with NewString contained in multiple *.cpp files:

  • vim *.cpp

  • qx # start recording to register x

  • :%s/OldString/NewString/g

  • :wnext

  • q # stop recording

  • @x # playback to see if it works correctly

  • 999@x # repeat 999 times to complete the job

Ref: http://vim.wikia.com/wiki/Recording_keys_for_repeated_jobs -> tutorial on record: http://www.thegeekstuff.com/2009/01/vi-and-vim-macro-tutorial-how-to-record-and-play/

How to edit record:

Assume that we are using register a for recording a task.

You can use “ap which will insert the text in the buffer (where a is your register):

        iThis is A<1b>

Now I can just change the line to maybe:

```bash
    iThis is an edited macro<1b>
```

Then I do ^v$"ay to yank (copy) this line to the a register:

        ^ for start of line
        v for visual mode
        $ for end of line
        "ay yank the selection to register a

Reference: https://vi.stackexchange.com/questions/759/how-can-i-view-and-edit-my-recording-i-e-recorded-macro

Efficient way to remove multiple spaces between two words

ciw and then escape back to normal mode.

duplicate lines matching a pattern, and modify the second line, all in one command

TASK: Search all lines containing “atributeA”, like this one

this.attributeA=attributeA //basic constructor

should turn into

this.attributeA=attributeA //basic constructor
this.attributeB=attributeB //basic constructor

Soulution

:g/attributeA/ copy . | s//attributeB/g

where

:g/pattern/ command1 | command2 | ...

executes commands on each line matching pattern (see :help :global).

Here,

copy .

copies the current line (see :help :copy) matched by :g to after the address .` (meaning the current line), and

s/pattern/replacement/g

then performs a substitution on the current line (see :help :substitute), i.e. the copy you just made. The g flag at the end causes the substitution to be performed for all matching patterns in the line, not just the first. Also note that I left the search pattern empty: Vim will remember the last search pattern used in the previous :global or :substitute command as a convenience.

Reference: https://stackoverflow.com/a/29369960/2302094

Some other commands

  • Insert output of command in vi-editor: :.! date

  • Increment a number : Ctrl-a

  • Decrement a number : Ctrl-x

  • Cursor movement: Put cursor to first line of screen : H

  • Cursor movement: Put cursor to last line of screen : L

  • Cursor movement: Put cursor to middle line of screen : M

  • Delete command: di( delete all character within parentheses

  • Delete command: di" delete all character within quotes

  • Toggle case of letter: ~

  • Toggle case of current line: g~~

  • Toggle case of all character from the cursor position to the end of line: ` g~$`

  • Change case of current line to Upper case: gUU

  • Change case of current line to lower case: guu

  • Go to end of word: w

    • Option e moves us to last letter of the word
  • vim options:

      -i  : ignore case
    
  • Run a command to place output in current line

      :r !command
    
  • Delete all empty lines ( Ref )

      :g/^$/d
    
  • Delete all empty lines or remove all lines containing only white spaces ( Ref )

      :g/^\s*$/d
    

Run Commands From Vi Editor: :! ls Insert output of the command in vi-editor: :.! date Run a command to place output in current line :r !command Increment a number : Ctrl-a Decrement a number : Ctrl-x Cursor movement: Put cursor to the first line of screen : H Cursor movement: Put cursor to the last line of screen : L Cursor movement: Put cursor to middle line of screen : M Delete command: di( delete all character within parentheses Delete command: di” delete all character within quotes Toggle case of the letter: ~ Toggle case of current line: g~~ Toggle case of all character from the cursor position to the end of line: g~$ Change case of the current line to Uppercase: gUU Change case of the current line to lowercase: guu vim options:

-i : ignore case Delete all empty lines ( Ref ) :g/^$/d Delete all empty lines or remove all lines containing only white spaces ( Ref ) :g/^\s*$/d Substitute with ascending numbers: => Suppose we want to replace each occurrence of “abc” with “xyz_N” where N is an ascending number (xyz_1, xyz_2, xyz_3, and so on). One approach uses the following command:

:let i=1 g/abc/s//=‘xyz_‘.i/ let i=i+1

This will replace the only first occurrence of each line. There is also command that can replace all, for it looks at the link below. Ref: http://vim.wikia.com/wiki/Making_a_list_of_numbers

Sort lines = > :%sort




Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • sed command
  • GitLab workflow for CMS-AN
  • awk command
  • Condor Jobs
  • Terminal multiplexer (screen/tmux)
  • Git CheatSheet
  • EOS uses
  • Mac Settings
  • Grep command
  • find command
  • XDAQ Basics