This is my init.vim to make a stable neovim installation act as a IDE for R statistical analyses (not too much for package development).
The settings are not using neovim-lsp, so expect this is a temporary solution until someone comes up with a complete lsp configuration for R.
Because Rstudio Qt interface hangs with large data sets.
This settings are tailored to new Neovim users (as myself) with several keybindings that simulates the usual Ctrl-C, V, etc that one finds in other editors. So this should ease transition to scientists outside of the computer sciences realm.
Much inspired by Sublime Text, and not being a person who likes to memorise numerous bindings, I added Ctrl-P as a way of accessing options easily. So if you don't know how to do something in the editor, try hitting Ctrl-P, most common options were added there.
Add the following (or parts of it) to your init.vim:
" Installation {{{
call plug#begin('~/.vim/plugged')
Plug 'mbbill/desertex'
Plug 'tomasr/molokai'
Plug 'yegappan/greplace'
Plug 'imkmf/ctrlp-branches'
Plug 'jistr/vim-nerdtree-tabs'
Plug 'shaunsingh/solarized.nvim'
Plug 'ctrlpvim/ctrlp.vim'
Plug 'APZelos/blamer.nvim'
Plug 'kassio/neoterm'
Plug 'xianzhon/vim-code-runner'
Plug 'joshdick/onedark.vim'
Plug 'simplenote-vim/simplenote.vim'
Plug 'pineapplegiant/spaceduck'
Plug 'liuchengxu/vim-which-key'
Plug 'dense-analysis/ale'
Plug 'scrooloose/nerdtree'
Plug 'jiangmiao/auto-pairs'
Plug 'ryanoasis/vim-devicons'
Plug 'metakirby5/codi.vim'
Plug 'dbeniamine/cheat.sh-vim'
Plug 'ncm2/ncm2'
Plug 'roxma/nvim-yarp'
Plug 'gaalcaras/ncm-R'
Plug 'sirver/UltiSnips'
Plug 'tacahiroy/ctrlp-funky'
Plug 'ncm2/ncm2-ultisnips'
Plug 'wsdjeg/Nvim-R'
Plug 'ervandew/supertab'
Plug 'itchyny/lightline.vim'
Plug 'airblade/vim-gitgutter'
Plug 'cideM/yui'
Plug 'mhinz/vim-startify'
Plug 'endel/ctrlp-filetype.vim'
Plug 'ompugao/ctrlp-locate'
Plug 'halkn/ripgrep.vim'
Plug 'lokikl/vim-ctrlp-ag'
Plug 'suy/vim-ctrlp-commandline'
Plug 'dbeecham/ctrlp-commandpalette.vim'
Plug 'tomtom/tcomment_vim'
Plug 'raghur/fruzzy', {'do': { -> fruzzy#install()}}
Plug 'tpope/vim-fugitive'
Plug 'rhysd/vim-grammarous'
Plug 'ntk148v/vim-horizon'
Plug 'humanoid-colors/vim-humanoid-colorscheme'
Plug 'hara/ctrlp-colorscheme'
Plug 'alaviss/nim.nvim'
Plug 'prabirshrestha/asyncomplete.vim'
Plug 'itchyny/vim-gitbranch'
call plug#end()
" }}}
" General settings {{{
if exists('+termguicolors')
let &t_8f = "\<Esc>[38;2;%lu;%lu;%lum"
let &t_8b = "\<Esc>[48;2;%lu;%lu;%lum"
set termguicolors
endif
colorscheme desertEx
let g:molokai_original=1
let g:blamer_enabled = 1
let g:webdevicons_enable_ctrlp = 1
let g:disco_nobright = 1
let g:disco_red_error_only = 1
set bg=dark
let g:yui_comments = "fade"
let g:mapleader = "\<Space>"
let maplocalleader = "\<Space>"
set sessionoptions-=blank " This fixes a problem with nerdtree and sessions
set modelines=1
" set spell
" set spelllang=en
set mouse=a " Enable mouse support in insert mode.
set clipboard+=unnamedplus " Use clipboard
set guioptions+=a
set backspace=indent,eol,start " To make backscape work in all conditions.
set ma " To set mark a at current cursor location.
" set number " To switch the line numbers on.
set expandtab " To enter spaces when tab is pressed.
set smarttab " To use smart tabs.
set tabstop=2 " Two chars for a tab
set shiftwidth=2
set autoindent " To copy indentation from current line
set si " To switch on smart indentation.
set ignorecase " To ignore case when searching.
set smartcase " When searching try to be smart about cases.
set hlsearch " To highlight search results.
set incsearch " To make search act like search in modern browsers.
set magic " For regular expressions turn magic on.
set showmatch " To show matching brackets when text indicator
set mat=2 " How many tenths of a second to blink
syntax enable " Enable syntax highlighting.
set encoding=utf-8 fileencodings=ucs-bom,utf-8,gbk,gb18030,latin1 termencoding=utf-8
set nobackup " Turn off backup.
set nowb " Don't backup before overwriting a file.
set noswapfile " Don't create a swap file.
"set ffs=unix,dos,mac " Use Unix as the standard file type.
au! BufWritePost $MYVIMRC source % " auto source when writing to init.vm alternatively you can run :source $MYVIMRC
" autocmd CursorHold,CursorHoldI * update " Saves when changing from insert mode
set undofile " Maintain undo history between sessions
set undodir=~/.vim/undodir
" Return to last edit position when opening files
au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
" Reload vimrc on save
au BufWritePost ~/.config/nvim/*.{vim,lua} so $MYVIMRC
"map q :quit<CR> " Quit with q
" FIXME: (broken) ctrl s to save
noremap <C-S> :update<CR>
vnoremap <C-S> <C-C>:update<CR>
inoremap <C-S> <Esc>:update<CR>
" exit insert mode
" inoremap <C-c> <Esc>
" Find
map <C-f> /
" indent / deindent after selecting the text with (⇧ v), (.) to repeat.
vnoremap <Tab> >
vnoremap <S-Tab> <
" Cut, Paste, Copy
vmap <C-x> d
vmap <C-v> p
vmap <C-c> y
" Undo, Redo (broken)
nnoremap <C-z> :undo<CR>
inoremap <C-z> <Esc>:undo<CR>
nnoremap <C-y> :redo<CR>
inoremap <C-y> <Esc>:redo<CR>
" This mapping makes Ctrl-Tab switch between tabs.
" Ctrl-Shift-Tab goes the other way.
noremap <C-Tab> :tabnext<CR>
noremap <C-S-Tab> :tabprev<CR>
map <C-t> :tabnew<cr>
" switch between tabs with cmd+1, cmd+2,..."
map <C-1> 1gt
map <C-2> 2gt
map <C-3> 3gt
map <C-4> 4gt
map <C-5> 5gt
map <C-6> 6gt
map <C-7> 7gt
map <C-8> 8gt
map <C-9> 9gt
" until we have default MacVim shortcuts this is the only way to use it in
" insert mode
imap <C-1> <esc>1gt
imap <C-2> <esc>2gt
imap <C-3> <esc>3gt
imap <C-4> <esc>4gt
imap <C-5> <esc>5gt
imap <C-6> <esc>6gt
imap <C-7> <esc>7gt
imap <C-8> <esc>8gt
imap <C-9> <esc>9gt
" }}}
" SuperTab {{{
let g:SuperTabDefaultCompletionType = "<c-n>"
" }}}
" Nerdtree {{{
nnoremap <C-n> :NERDTreeTabsToggle<CR>
" Start NERDTree when Vim starts with a directory argument.
autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 1 && isdirectory(argv()[0]) && !exists('s:std_in') |
\ execute 'NERDTree' argv()[0] | wincmd p | enew | execute 'cd '.argv()[0] | endif
"autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
" Exit Vim if NERDTree is the only window left.
autocmd BufEnter * if tabpagenr('$') == 1 && winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() |
\ quit | endif
let g:NERDTreeChDirMode = 2
" If another buffer tries to replace NERDTree, put it in the other window, and bring back NERDTree.
autocmd BufEnter * if bufname('#') =~ 'NERD_tree_\d\+' && bufname('%') !~ 'NERD_tree_\d\+' && winnr('$') > 1 |
\ let buf=bufnr() | buffer# | execute "normal! \<C-W>w" | execute 'buffer'.buf | endif
autocmd BufWinEnter * silent NERDTreeMirror " Open the existing NERDTree on each new tab.
" }}}
" Lightline {{{
set laststatus=2 " To tell Vim we want to see the statusline.
let g:lightline = {
\ 'colorscheme': 'onedark',
\ }
" }}}
" Startify {{{
function! GetUniqueSessionName()
let path = fnamemodify(getcwd(), ':~:t')
let path = empty(path) ? 'no-project' : path
let branch = gitbranch#name()
let branch = empty(branch) ? '' : '-' . branch
return substitute(path . branch, '/', '-', 'g')
endfunction
autocmd VimLeavePre * silent execute 'SSave! ' . GetUniqueSessionName()
function! s:gitModified()
let files = systemlist('git ls-files -m 2>/dev/null')
return map(files, "{'line': v:val, 'path': v:val}")
endfunction
" same as above, but show untracked files, honouring .gitignore
function! s:gitUntracked()
let files = systemlist('git ls-files -o --exclude-standard 2>/dev/null')
return map(files, "{'line': v:val, 'path': v:val}")
endfunction
let g:startify_lists = [
\ { 'type': 'sessions', 'header': [' Sessions'] },
\ { 'type': function('s:gitModified'), 'header': [' git modified']},
\ { 'type': function('s:gitUntracked'), 'header': [' git untracked']},
\ { 'type': 'dir', 'header': [' MRU '. getcwd()] },
\ { 'type': 'files', 'header': [' MRU'] },
\ { 'type': 'bookmarks', 'header': [' Bookmarks'] },
\ { 'type': 'commands', 'header': [' Commands'] },
\ ]
" }}}
" CtrlP interface {{{
let g:ctrlp_working_path_mode = 'rw'
let g:ctrlp_map = '<C-p>'
let g:ctrlp_cmd = 'CtrlPCommandPalette'
let g:ctrlp_extensions = ['mixed', 'line', 'filetype', 'commandline', 'colorscheme', 'funky', 'branches']
let g:ripgrep_options='--hidden
\ -g "!/cache/*"
\ -g "!/data/*"
\ -g "!/reports/*"
\ -g "!/.git/*"
\ -- '
let g:ctrlp_ag_ignores = '--ignore .git
\ --ignore "deps/*"
\ --ignore "_build/*"
\ --ignore "node_modules/*"
\ --ignore "reports/*"
\ --ignore "data/*"
\ --ignore "cache/*"
\ --ignore ".git/*"'
let g:commandPalette = {
\ 'Ignorecase: Toggle': 'set ignorecase!',
\ 'File: save and close': 'wq',
\ 'Start R': 'call StartR("R")',
\ 'Start Object Browser': 'call RObjBrowser()',
\ 'Start Inim': 'T inim',
\ 'Search files, buffers, MRU': 'CtrlPMixed',
\ 'Search within project': 'call feedkeys(":CtrlPagLocate ")',
\ 'Search in this file': 'CtrlPLine',
\ 'Commend lines': 'TComment',
\ 'Check grammar': 'GrammarousCheck',
\ 'Set filetype': 'CtrlPFiletype',
\ 'Bye!': 'qa!',
\ 'Command history': 'call ctrlp#init(ctrlp#commandline#id())',
\ 'Find file anywhere in system': 'CtrlPLocate',
\ 'User defined commands': 'call ctrlp#init(ctrlp#key#id())',
\ 'Colorschemes': 'CtrlPColorscheme',
\ 'Unfold all lines': 'call feedkeys("\<Space>zR\<CR>")',
\ 'Fold all lines': 'call feedkeys("\<Space>zM\<CR>")',
\ 'Unfold here': 'call feedkeys("\<Space>zo\<CR>")',
\ 'Navigate sections of this file': 'CtrlPFunkyMulti',
\ 'Run!': 'call feedkeys("\<Space>B\<CR>")',
\ 'Branches': 'CtrlPBranches'}
" function BrightHighlightOn()
" hi CursorLine guibg=darkred
" endfunction
"
" function BrightHighlightOff()
" hi CursorLine guibg=#191919
" endfunction
" let g:ctrlp_buffer_func = { 'enter': 'BrightHighlightOn', 'exit': 'BrightHighlightOff', }
let g:fruzzy#usenative = 1 " optional - but recommended - see below
let g:ctrlp_match_func = {'match': 'fruzzy#ctrlp#matcher'} " tell CtrlP to use this matcher
let g:ctrlp_match_current_file = 1 " to include current file in matches
set wildignore+=*/.git/*,*/.hg/*,*/.svn/*
" }}}
" tComment {{{
" vmap <C-/> gc " comment / decomment & normal comment behavior
let g:tcomment#replacements_xml={} " Disable tComment to escape some entities
" }}}
" R configuration - Nvim-R {{{
let g:rout_follow_colorscheme = 1 " R output is highlighted with current colorscheme
let g:Rout_more_colors = 1 " R commands in R output are highlighted
let g:R_pdfviewer="evince"
let R_show_args = 1 " show the arguments for functions with autocompletion
let g:R_objbr_opendf = 0
let g:R_objbr_openlist = 0
autocmd VimLeave * if exists("g:SendCmdToR") && string(g:SendCmdToR) != "function('SendCmdToR_fake')" | call RQuit("nosave") | endif " exit R when you exit the vim
autocmd FileType rmd set foldmarker=```{,```
autocmd FileType rmd setlocal foldmethod=marker
vmap <Space><Space> <Plug>RDSendSelection
nmap <Space><Space> <Plug>RDSendLine
" }}}
" R configuration - NCM2 {{{
autocmd BufEnter * call ncm2#enable_for_buffer() " To enable ncm2 for all buffers.
set completeopt=noselect,noinsert,menuone,preview
" }}}
" Snips - Ultisnips - ncm2 {{{
" First use tab and shift tab to browse the popup menu and use enter to expand:
inoremap ncm2_ultisnips#expand_or("<CR>”, 'n')
inoremap pumvisible() ? "<C-n>" : "<Tab>"
inoremap pumvisible() ? "<C-p>" : "<S-Tab>"
let g:UltiSnipsExpandTrigger="<c-0>"
au BufNewFile,BufRead *.Rmd set filetype=rmd
" c-j c-k for moving in snippet
let g:UltiSnipsExpandTrigger = "<Plug>(ultisnips_expand)"
let g:UltiSnipsJumpForwardTrigger = "<c-j>"
let g:UltiSnipsJumpBackwardTrigger = "<c-k>"
let g:UltiSnipsRemoveSelectModeMappings = 0
" }}}
" ALE {{{
let g:ale_linters = {
\ 'nim': ['nimlsp', 'nimcheck'],
\ 'rmd': ['lintr'],
\ 'sh': ['shellcheck']
\}
let g:ale_fixers = {
\ '*': ['remove_trailing_lines', 'trim_whitespace'],
\ 'rmd': ['styler'],
\ 'nim': ['nimpretty'],
\}
let g:ale_fix_on_save = 1
let g:ale_linters_explicit = 1
let g:ale_set_loclist = 0
let g:ale_set_quickfix = 1
let g:ale_lint_on_text_changed = 'never'
let g:ale_lint_on_insert_leave = 0
let g:ale_fix_on_save = 1
let g:ale_sign_error = '✖✖'
let g:ale_sign_warning = '⚠⚠'
highlight ALEErrorSign guifg=Red
highlight ALEWarningSign guifg=Yellow
" Workaround to get auto omni completion FIXME very buggy
" from so/q/35837990/
" function! OpenCompletion()
" if ((v:char >= 'a' && v:char <= 'z') || (v:char >= 'A' && v:char <= 'Z'))
" call feedkeys("\<C-x>\<C-o>", 'n')
" endif
" endfunction
"
" autocmd FileType rmd autocmd InsertCharPre * call OpenCompletion()
" autocmd FileType r autocmd InsertCharPre * call OpenCompletion()
" }}}
" Nim configuration - asyncomplete {{{
au User asyncomplete_setup call asyncomplete#register_source({
\ 'name': 'nim',
\ 'whitelist': ['nim'],
\ 'completor': {opt, ctx -> nim#suggest#sug#GetAllCandidates({start, candidates -> asyncomplete#complete(opt['name'], ctx, start, candidates)})}
\ })
" }}}
" Nim configuration - CodeRunner and TREPL {{{
let g:CodeRunnerCommandMap = {
\ 'nim' : 'nim c -r $fileName'
\}
let g:code_runner_save_before_execute = 1
let g:neoterm_callbacks = {}
function! g:neoterm_callbacks.before_new()
if winwidth('.') > 100
let g:neoterm_default_mod = 'botright vertical'
else
let g:neoterm_default_mod = 'botright'
end
endfunction
nmap <silent><leader>B <plug>CodeRunner
autocmd FileType nim nmap <leader>d :TREPLSendLine<CR>
" }}}
" vim:foldmethod=marker:foldlevel=0