I've been using Vim and Neovim as my main editor for a bit (i.e., since the late 1990's) and have a small but useful-to-me configuration file. The Vim script configuration has served me well, but some newer Neovim functionality (e.g., the Language Server Protocol) uses Lua. Vim script allows this, but it requires using a here-document:
"""""""""""""""""""""""""""""""""""""""""""""""""
" Search recursively for files from "here"
set path +=**
"""""""""""""""""""""""""""""""""""""""""""""""""
" Set up Language Sever Protocol plugin
lua << EOF
-- Use an on_attach function to only map the following keys
-- after the language server attaches to the current buffer
local on_attach = function(client, bufnr)
-- Enable completion triggered by
vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc')
While this isn't terrible, it is a bit ugly and evidently, enough so to motivate converting my configuration to Lua.
Plugin Manager
My plugin needs have been modest (cscope bindings and mark) and haven't required a manager. But at some point, mark added a dependency on another package, making having a package manager more useful. vim-plug was a good match and has served me well, and while I'm changing over the init script to Lua, it made sense to use the packer.nvim package manager. Additionally, I moved all plugin definitions to nvim/lua/plugins.lua. This file also includes code to bootstrap packer if needed. After copying the files to a new machine, I use the command
$ nvim --headless -c 'autocmd User PackerComplete quitall' -c 'PackerSync'
to run the bootstrap and install the plugins. The plugins.lua file looks like:
local ensure_packer = function()
local fn = vim.fn
local install_path = fn.stdpath('data')..'/site/pack/packer/start/packer.nvim'
if fn.empty(fn.glob(install_path)) > 0 then
fn.system({'git', 'clone', '--depth', '1', 'https://github.com/wbthomason/packer.nvim', install_path})
vim.cmd [[packadd packer.nvim]]
return true
end
return false
end
local packer_bootstrap = ensure_packer()
return require('packer').startup(function(use)
-- Packer can manage itself
use 'wbthomason/packer.nvim'
use {
'inkarkat/vim-mark',
requires = {'inkarkat/vim-ingo-library'}
}
-- Automatically set up your configuration after cloning packer.nvim
-- Put this at the end after all plugins
if packer_bootstrap then
require('packer').sync()
end
end)
Rosetta Stone
The Set List
set nobackup " do not keep a backup file, use versions instead
vim.opt.backup = false -- do not keep a backup file, use versions instead
set title " change the window title to be the file name
vim.opt.title = true -- change the window title to be the file name
Map to the stars
imap <S-Tab> <Esc> < i
is a mapping while in insert mode. Orvnoremap "*ygv
vim.api.nvim_set_keymap("i", " ", "< i", {})
vim.api.nvim_set_keymap("v", "", '"*ygv', { noremap = true })
Some examples I found use keymap.set instead of nvim_set_keymap. The later appears to be an older version of the API, but I have chosen to use it as some Linux distributions ship older versions of Neovim which don't support the new syntax.
Bits-n-bobs
There were two other settings that don't fall into the "set" or "map" categories. The first allows recursively searching the current file path. Vim script uses += while Lua uses :append:
"""""""""""""""""""""""""""""""""""""""""""""""""
" Search recursively for files from "here"
set path +=**
" and search the Mercurial directory above if it exists
set path +=../.hg**
becomes--------------------------------------------------
-- Search recursively for files from "here"
vim.opt.path:append('**')
-- and search the Mercurial directory above if it exists
vim.opt.path:append('../.hg**')
The other restores the cursor to its previous position in the file (see "BufWinEnter" below). The function mapping is as one would expect. The careful observer will notice a few settings disappeared. They are ones that either a) didn't get used or b) are holdovers from Vim.
Overall, this exercise was not too bad. See below for the before and after.
init.vim
" neovim settings
" relies on neovim defaults which are different than vim
set nobackup " do not keep a backup file, use versions instead
set nowritebackup " dont want a backup file while editing
set ruler " show the cursor position all the time
set showcmd " display incomplete commands
set title " change the window title to be the file name
set modeline
set cscopetagorder=0 " search cscope database before tags
set cscopetag " search cscope database for tags
set nocscopeverbose
set termguicolors
set guicursor=
set background=light
set mouse=a
"""""""""""""""""""""""""""""""""""""""""""""""""
" Plug
call plug#begin()
" Dependency of vim-mark
Plug 'inkarkat/vim-ingo-library'
Plug 'inkarkat/vim-mark'
call plug#end()
" use ESC to close a terminal window
tnoremap <ESC> <C-\><C-n><C-w><C-p>
set clipboard+=unnamedplus
" From the neovim wiki under "clipboard=autoselect is not implemented yet"
" oh, and xsel doesn't seem to work but xclip does
vnoremap <LeftRelease> "*ygv
"""""""""""""""""""""""""""""""""""""""""""""""""
" Use all available colors for highlight (mark.vim)
let g:mwDefaultHighlightingPalette = 'maximum'
"""""""""""""""""""""""""""""""""""""""""""""""""
" Don't use Ex mode, use Q for formatting
map Q gq
"""""""""""""""""""""""""""""""""""""""""""""""""
" allow tab/shift-tab of selected sections
map <Tab> >0
map <S-Tab> <0
imap <S-Tab> <Esc> < i
" CTRL-U in insert mode deletes a lot. Use CTRL-G u to first break undo,
" so that you can undo CTRL-U after inserting a line break.
inoremap <C-U> <C-G>u<C-U>
"""""""""""""""""""""""""""""""""""""""""""""""""
" Restore cursor to previous position in a file
function! ResCur()
if line("'\"") <= line("$")
normal! g`"
return 1
endif
endfunction
augroup resCur
autocmd!
autocmd BufWinEnter * call ResCur()
augroup END
"""""""""""""""""""""""""""""""""""""""""""""""""
" Convenient command to see the difference between the current buffer and the
" file it was loaded from, thus the changes you made.
" Only define it when not defined already.
if !exists(":DiffOrig")
command DiffOrig vert new | set bt=nofile | r ++edit # | 0d_ | diffthis
\ | wincmd p | diffthis
endif
" don't wrap long lines, but set the bottom scroll bar
" TODO this might be gvim specific
set nowrap guioptions+=b
"""""""""""""""""""""""""""""""""""""""""""""""""
" Search recursively for files from "here"
set path +=**
" and search the Mercurial directory above if it exists
set path +=../.hg**
init.lua
-- neovim settings
-- relies on neovim defaults which are different than vim
vim.opt.backup = false -- do not keep a backup file, use versions instead
vim.opt.writebackup = false -- dont want a backup file while editing
vim.opt.ruler = true -- show the cursor position all the time
vim.opt.showcmd = true -- display incomplete commands
vim.opt.title = true -- change the window title to be the file name
vim.opt.modeline = true
vim.opt.cscopetagorder = 0 -- search cscope database before tags
vim.opt.cscopetag = true -- search cscope database for tags
vim.opt.cscopeverbose = false
vim.opt.termguicolors = true
vim.opt.guicursor = ''
vim.opt.background = 'light'
vim.opt.mouse = 'a'
vim.opt.clipboard = 'unnamedplus'
--------------------------------------------------
-- Search recursively for files from "here"
vim.opt.path:append('**')
-- and search the Mercurial directory above if it exists
vim.opt.path:append('../.hg**')
--------------------------------------------------
-- Use all available colors for highlight (mark.vim)
vim.g.mwDefaultHighlightingPalette = 'maximum'
--------------------------------------------------
-- From the neovim wiki under "clipboard=autoselect is not implemented yet"
-- oh, and xsel doesn't seem to work but xclip does
-- TODO this seems to work with both nvim-0.6 and nvim-0.7 where as
-- vim.keymap.set("v", "<LeftRelease>", '"*ygv', {}) only works in 0.7
vim.api.nvim_set_keymap("v", "<LeftRelease>", '"*ygv', { noremap = true })
--------------------------------------------------
-- Don't use Ex mode, use Q for formatting
vim.api.nvim_set_keymap("", "Q", "gq", {})
--------------------------------------------------
-- allow tab/shift-tab of selected sections
vim.api.nvim_set_keymap("", "<Tab>", ">0", {})
vim.api.nvim_set_keymap("", "<S-Tab>", "<0", {})
vim.api.nvim_set_keymap("i", "<S-Tab> <Esc>", "< i", {})
--------------------------------------------------
-- Restore cursor to previous position in a file
vim.api.nvim_create_autocmd({ "BufWinEnter" }, {
pattern = { "*" },
callback = function()
if vim.fn.line("'\"") <= vim.fn.line("$") then
vim.api.nvim_exec('silent! normal! g`"zv', false)
end
end,
})
--------------------------------------------------
-- All Packer plugins in lua/plugins.lua
require('plugins')