wiki:Tools/Neovim

Neovim

Neovim is a wrapper of asynchronous interfaces around the original Vim engine. It is a nice community effort which is worth using. Basically, it makes Vim a Emacs-like editor, with dynamic plugins, etc. Most of the plugins are over-kill and poorly designed bloatware, but some are essential.

Learning vi basics is absolutely essential, not only to quick "in-place" remote editing (via ssh) but to learn the old-school way of looking at things (Unix philosophy - minimalistic, simple, approaching a local optimum, programs for manipulating text streams). The motions, for example, reflect the underlying nested structures of a texts - sequences of characters, sequences of words and higher level structures, such as expressions, blocks, procedures, etc.

Last but not least, you could use vi key bindings with necessary crapware like Eclipse or IntelliJ, which makes one's life a bit less frustrating and painful.

Applied Unix Philosophy

Vim is based on vi from University of Berkeley, which in turn is based on ed from Unix of Bell Labs, which got lots of ideas from University of Toronto, so it is based on the ideas and concepts from the best minds of the time.

The whole philosophy is based upon the concept of stream of text, which, in turn, has been influenced by the recent hot research topics involving DNA structure and the new thriving field molecular biology in general.

The first principle is that a text has structure - it is a of sequences of words (which are sequences of characters) composed into sentences, which in turn are composed into paragraphs, which form chapters (which are sequences of paragraphs), and these are stored in a file, which is a fundamental distinct named entity which contain arbitrary sequence of bytes.

Like it is with a human language, the structure of a text is regular. Like a human language, a text has many nested structure. Words have its length (in characters), beginning and end, they are separated within a sentence with spaces (ordinary characters). Sentences within a line are separated with punctuation marks (ordinary characters).

Lines of text are separated within a file by distinct special characters (separators). Sentences have lengths, beginnings and ends, so do paragraphs, etc. Actually, text is a stream of nested sequences of higher orders.

If you think about it for a moment, it is quite similar to proteins - there is a language of aminoacidos (which are words) and whole proteins, which are sentences (as a naive mystic would say, of God). The crucial difference is that proteins fold into a precise 3d-shapes which have unique chemical properties (hemoglobin, for example, due to its 3d-structure is able to bind 4 oxygen molecules).

The second principle is that regular structures could be traversed (searched) and transformed (modified) with Regular Expressions, and this is the essence of ex and vi.

The text is navigated (traversed) using commands (in command mode), which are, basically, key-bindings to "parts" of regular expressions - commands execute simple regexps, which could be composed. The result of W, B, E or $ or 0 is changing position of the cursor in a file. Other commands, like yyp or c$ or d3W runs regular expressions which transform (change) the parts of a text. Almost like enzymes.

Unlike, say, Emacs, which is much more functional, commands of vi are fundamentally imperative (and mutating). A vi session could be viewed (and recorded) as a script (sequence of commands), which is exactly how Vim's macros work.

If you look at the summary of basic vim commands below, you will notice that they are not just regular (following a regular structure of a text) but also almost uniform, at least there was a lot of effort to make them consistent. This is not a coincidence and is based on fundamental principles.

If you are following the right principles, chances are that you will reach the right destination. Starting from a wrong premises, however, will inevitably lead to a wrong conclusion. vi is a product of right philosophy based on right principles. That is why it is still in use after almost 40 years.

The Classic Vi

Vi is a small wonder of a classic old-school Unix software engineering, and like Lisp, it probably has been discovered (and then evolved), not created.

:q! - exit without saving :q - exit ZZ - save & exit
/ - search for a pattern n - next occurence N - next occurence in a reversed direction
x - cut a char X - cut a char before (a-la backspace) dd - delete a line
i - insert at the cursor I - insert at the beginning of a line Esc - back to the command mode
a - append after the cursor A - append at the end of a line Esc - back to the command mode
o - insert a line below O insert a line above J - join/concatenate lines
:w - save a file :w! - save file :wq - save & exit
l - one char forward w - one subWord forward W - one word forward
e - one subWord forward E - one word forward
h - one char backward b - one subWord backward B - one word backward
r - replace a char R - replace a word
0 - begin of a line ^ - first word $ - end on a line
} - one line forward { - one line backward
j - one line down Ctrl-d - half-page down G - end of a file
k - one line up Ctrl-u - half-page up gg - beginning of a file
u - undo Ctrl-r - redo Ctrl-p - a grep plugin
c_ where _ is a modificator cc - change whole line
cw - change a subWord cW - change a word c$ - change to the end of a line
d_ where _ is a modificator dd - delete whole line p - paste deleted piece
dw - delete a subWord dW - delete a word d$ - delete to the end of a line
y_ where _ is a modificator yy - yank a whole line P - paste before cursor
yw - yank a subWord yW - yank a word y$ - yank to the end of a line
. - repeat the last command u - undo Ctrl-r - redo
Ctrl-o - previous item in a stack Ctrl-i - next item in a stack
H - up M - middle L - bottom
G - end of the file gg - beginning of the file
V - this line in visual mode

Chords

ct<char> - change up to but not including this <char>

Vy or y$and then jp or even better yy then just p vf<char>yi and then O<Esc>p

Commands

:set rnu! just do it

:$s search for /this pattern and replace it with /this string/ in the whole file g with confirmation c

:$s/\<x\>/y/gc

set args to multiple files

:args 'find src test -name "*.py"'

search and replace in all files from args

:argdo $s/\<x\>/y/g | w

Installation

The code

$ git clone git://github.com/neovim/neovim
$ cd neovim
$ rm -rf CMakeFiles CMakeCache.txt
$ make -s CMAKE_BUILD_TYPE=Release
$ sudo make -s install

Python3 module

$ sudo pip3 install -U --force neovim

optional module for obsoleted python2.7

sudo pip2 install -U --force neovim

Set up .config/nvim/init.vim

set t_Co=256

set encoding=utf-8
set fileformat=unix

set showmatch
set showcmd

set incsearch
set hlsearch

set lazyredraw

set laststatus=0 noshowmode noruler

Some plugins

call plug#begin('~/.local/share/nvim/plugged')

Plug 'Shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' }
Plug 'Shougo/denite.nvim', { 'do': ':UpdateRemotePlugins' }

Plug 'scrooloose/syntastic', { 'do': ':UpdateRemotePlugins' }
Plug 'scrooloose/nerdcommenter'

Plug 'fatih/vim-go'
Plug 'nsf/gocode'

Plug 'neomake/neomake', { 'do': ':UpdateRemotePlugins' }

Plug 'rust-lang/rust.vim'
Plug 'sebastianmarkow/deoplete-rust', { 'do': ':UpdateRemotePlugins' }

Plug 'ervandew/supertab'

call plug#end()

Setup the proper python3 module

let g:python3_host_prog = '/usr/local/bin/python3'
""" disable python2, ruby and node
let g:python_host_prog = '/usr/local/bin/python'
let g:loaded_python_provider = 1
let g:loaded_ruby_provider = 1
let g:node_host_prog = '/usr/local/bin/node'
let g:loaded_node_provider = 1

Plugins

  • Hardtime
    Plug 'takac/vim-hardtime'
    
    let g:hardtime_default_on = 1
    let g:hardtime_allow_different_key = 1
    
  • Language Server Client
       git clone git://github.com/autozimu/LanguageClient-neovim.git
       cd LanguageClient-neovim
       cargo install --force
    
    let g:LanguageClient_autoStart = 1
    
    let g:LanguageClient_serverCommands = {
        \ 'c': ['clangd'],
        \ 'cpp': ['clangd'],
        \ 'go': ['go-langserver'],
        \ 'python': ['pyls'],
        \ 'haskell': ['hie-wrapper'],
        \ 'rust': ['rls'],
        \ 'javascript': ['javascript-typescript-stdio'],
        \ 'typescript': ['javascript-typescript-stdio']
        \ }
    
  • ale (supports more linters, but is bloated, conflicts with syntastic)
    let g:ale_enabled = 0
    let g:ale_lint_on_enter = 1
    let g:ale_set_quickfix = 1
    "let g:ale_lint_on_text_changed = 'never'
    let g:ale_python_pylint_executable = 'python3'
    let g:ale_python_pylint_use_global = 1
    let g:ale_python_flake8_executable = 'python3'
    let g:ale_python_flake8_use_global = 1
    let g:ale_python_mypy_use_global = 1
    let g:ale_python_mypy_options = '--ignore-missing-imports'
    

Command line tools

  • denite + ripgrep - a parallel grep

Set up .config/nvim/init.vim

nnoremap <C-p> :Denite file_rec<cr>

call denite#custom#var('file_rec', 'command',
            \ ['rg', '--files', '--glob', '!.git'])
call denite#custom#var('grep', 'command', ['rg'])
call denite#custom#var('grep', 'default_opts',
            \ ['--vimgrep', '--no-heading'])
call denite#custom#var('grep', 'recursive_opts', [])
call denite#custom#var('grep', 'pattern_opt', ['--regexp'])
call denite#custom#var('grep', 'separator', ['--'])
call denite#custom#var('grep', 'final_opts', [])
  • ag - a search tool
  • fzf - a parallel search tool
Last modified 3 years ago Last modified on Nov 22, 2018, 3:56:04 AM
Note: See TracWiki for help on using the wiki.