From b275d74db59a52046a66f24e581badf67e53c2a3 Mon Sep 17 00:00:00 2001 From: nemirwen Date: Mon, 29 Apr 2024 10:41:02 +0200 Subject: [PATCH] Transition setup to modern neovim Abandon common config for both vim and neovim, as the neovim ecosystem is just diverging more and more. For now the goals is to have an IDE-like neovim config, with a fallback minimal vimrc. As of this config, only the first part has been started --- config/nvim/init.lua | 51 ++++++ config/nvim/init.old.vim | 272 +++++++++++++++++++++++++++++ config/nvim/init.vim | 4 - config/nvim/lua/keys.lua | 59 +++++++ config/nvim/lua/plugins-config.lua | 127 ++++++++++++++ config/nvim/lua/plugins.lua | 95 ++++++++++ 6 files changed, 604 insertions(+), 4 deletions(-) create mode 100644 config/nvim/init.lua create mode 100644 config/nvim/init.old.vim delete mode 100644 config/nvim/init.vim create mode 100644 config/nvim/lua/keys.lua create mode 100644 config/nvim/lua/plugins-config.lua create mode 100644 config/nvim/lua/plugins.lua diff --git a/config/nvim/init.lua b/config/nvim/init.lua new file mode 100644 index 0000000..ce72271 --- /dev/null +++ b/config/nvim/init.lua @@ -0,0 +1,51 @@ +-- http://vimcasts.org/episodes/meet-neovim/ +-- `^=` means prepend +vim.api.nvim_command('set runtimepath^=~/.vim') +vim.opt.runtimepath:append(",~/.vim/after") +vim.api.nvim_command('let &packpath = &runtimepath') + +require("plugins") + +vim.cmd.source("~/.config/nvim/init.old.vim") + +-- Colorscheme -- +vim.cmd([[colorscheme base16-gruvbox-dark-pale]]) + + +-- Sets how long the cursor needs to wait before showing the diagnostic modal +vim.o.updatetime = 250 + +vim.diagnostic.config({ + virtual_text = false, + signs = true, + underline = true, + update_in_insert = false, + severity_sort = true, +}) + +-- Show code diagnostics in a floating window instead of inline +-- https://github.com/neovim/nvim-lspconfig/wiki/UI-Customization#show-line-diagnostics-automatically-in-hover-window +vim.api.nvim_create_autocmd('LspAttach', { + callback = function(args) + vim.api.nvim_create_autocmd("CursorHold", { + buffer = bufnr, + callback = function() + local opts = { + focusable = false, + close_events = { "BufLeave", "CursorMoved", "InsertEnter", "FocusLost" }, + border = 'rounded', + source = 'always', + prefix = ' ', + scope = 'cursor', + } + vim.diagnostic.open_float(nil, opts) + end + }) + end, +}) + + +require("plugins-config") +require("keys") + + diff --git a/config/nvim/init.old.vim b/config/nvim/init.old.vim new file mode 100644 index 0000000..e9c3795 --- /dev/null +++ b/config/nvim/init.old.vim @@ -0,0 +1,272 @@ +set nocompatible +if &shell =~# 'fish$' + set shell=sh +endif + +" Allow backspacing over everything in insert mode. +set backspace=indent,eol,start +set number +set relativenumber +"[Hide/show the white-space and more invisible symbols]" +set list +set listchars=tab:▸\ ,nbsp:¬,trail:- +" | | + Trailing spaces +" | + Non breakable spaces +" + Tabulations: `tab xy`, x: first char, y: following chars +set nojoinspaces +"[Indent & Tab/mode-line settings]" +set breakindent +set nopaste +set smarttab +set tabstop=4 " tabs size on screen " +set expandtab " inserts spaces " +set autoindent +set copyindent " copy existing tab/spaces mix on newline " +set smartindent " overruled by cindent " +set cinwords=except,finally,def,class,with,do,if,elif,else,for,while,try,switch +set cinoptions+=l1 " switch case label alignement, :h cinoptions-values " +set shiftwidth=4 " number of space to use on indent. Use tabstop if 0" +"set softtabstop=4 +"[Matching chars]" +set showmatch +set matchpairs=\":\" +set matchpairs+=(:) +set matchpairs+={:} +set matchpairs+=[:] +"[TextWidth settings]" +set textwidth=0 +"[Look for a single modeline in files]" +set modeline +set modelines=1 + +set ruler " show the cursor position all the time +set showcmd " display incomplete commands +set laststatus=2 +set noshowmode + +"[Command mode autocompletion]" +set wildmenu +set wildmode=longest:full,full +" `------------|---- First complete till longest common string, open wildmenu +" `---- Then, complete next full match + +set ttimeout " time out for key codes +set ttimeoutlen=100 " wait up to 100ms after Esc for special key + +"[Turn backup off and value of history]" +set nobackup +set noswapfile +set history=1000 +set nowritebackup +set undolevels=5000 + +"[Setup history file]" +set viminfo=%,<0,'10,/16,:16,h,f0 +" | | | | | | + file marks 0-9,A-Z 0=NOT stored +" | | | | | + disable 'hlsearch' loading viminfo +" | | | | + command-line history saved +" | | | + search history saved +" | | + files marks saved +" | + lines saved each register (old name for <, vi6.2): NOT STORED +" + save/restore buffer list +if !has('nvim') + "[Declutter $HOME]" + set viminfo+=n~/.vim/cache/.viminfo +endif + +" Show @@@ in the last line if it is truncated. +set display=truncate +"[Splitting rules]" +set splitbelow +set splitright +set equalalways + +" Show a few lines of context around the cursor. +set scrolloff=5 +" Try to keep the cursor in the same column while scrolling +set nostartofline + +set autochdir +set autoread +set autowrite + +"[Shared with OS clipboard]" +set clipboard=unnamed + +"[For regular expressions turn magic on, use \v to get regex parent]" +set magic +"[Search settings]" +set hlsearch +set incsearch +set smartcase +set ignorecase +set wrapscan +"[When on, the ":substitute" flag 'g' is default on]" +set nogdefault +"[Enable realtime feedback for substitution]" +if has("nvim") + set inccommand=nosplit +endif + + +"[Kitty doesn't support background color erase]" +let &t_ut='' +let base16colorspace=256 +set background=dark +colorscheme base16-default-dark +"[Fix background transparency]" +if has("autocmd") + autocmd ColorScheme * highlight Normal ctermbg=None + autocmd ColorScheme * highlight NonText ctermbg=None +endif + + +"[Define the leader key]" +let mapleader="," +let maplocalleader="," +"[Reselect visual block after indent/outdent]" +vnoremap < >gv +"[Improve up/down movement on wrapped lines]" +"[If preceded by a count, jump actual lines. Also if > 5, save to jumplist]" +nnoremap j v:count ? (v:count > 5 ? "m'" . v:count : '') . 'j' : 'gj' +nnoremap k v:count ? (v:count > 5 ? "m'" . v:count : '') . 'k' : 'gk' +"[Easy split navigation]" +nnoremap j +nnoremap k +nnoremap h +nnoremap l +nnoremap k +nnoremap j +nnoremap h +nnoremap l +"[Locate the desired objects in the center of the screen]" +nnoremap n nzz +nnoremap N Nzz +nnoremap * *zz +nnoremap # #zz +"[New line under/bellow current line without jump to insert-mode]" +nnoremap o o +nnoremap O O +"[Clear search highlights]" +nnoremap // :nohlsearch +"[Reflow current paragraph]" +"[http://stevelosh.com/blog/2010/09/coming-home-to-vim/]" +nnoremap q :call ReflowParagraph() +" http://stackoverflow.com/questions/1005/getting-root-permissions-on-a-file-inside-of-vi +cmap w!! w !sudo tee >/dev/null % +"[To disable the arrow keys]" +for prefix in ['i', 'n', 'v'] + for key in ['', '', '', ''] + execute prefix . "noremap " . key . " " + endfor +endfor +"[Switch quickly between source and header]" +nnoremap f :e =SwapExtension() + + + +" Do incremental searching when it's possible to timeout. +if has('reltime') + set incsearch +endif + +" LaTeX ftdetect +let g:tex_flavor = "latex" + +" Switch syntax highlighting on when the terminal has colors or when using the +" GUI (which always has colors). +if &t_Co > 2 || has("gui_running") + " Revert with ":syntax off". + syntax on + + " I like highlighting strings inside C comments. + " Revert with ":unlet c_comment_strings". + let c_comment_strings=1 +endif + +"[Reflow current paragraph]" +function! ReflowParagraph() + let l:view = winsaveview() + normal gwip + call winrestview(l:view) +endfunction +"[Remove tabs and spaces at the end of lines]" +function! DeleteTrailingTWS() + "[Do not clean up trailing spaces in binary mode or in diff files]" + if &binary || &ft =~ 'diff' + return + endif + let l:view = winsaveview() + silent %s/[ \t]*$//g + silent %s/\s\+$//ge + call winrestview(l:view) +endfunction +"[Make the scripts executable]" +function! ChangeScriptMode() + if getline(1) =~ "#!" + if getline(1) =~ "bin/" + silent !chmod +x + endif + endif +endfunction +"[Swap file extensions, for example cpp/h]" +"https://stackoverflow.com/a/22145246" +function! SwapExtension() + let [rest, ext] = [expand('%:r'), expand('%:e')] + if ext ==? 'h' + if filereadable(rest . '.c') + let ext = 'c' + elseif filereadable(rest . '.cpp') + let ext = 'cpp' + endif + elseif ext ==? 'cpp' || ext ==? 'c' + let ext = 'h' + "swap between vertex and fragment shader" + elseif ext ==? 'vsh' + let ext = 'fsh' + elseif ext ==? 'fsh' + let ext = 'vsh' + endif + return rest . '.' . ext +endfunction + +" Only do this part when compiled with support for autocommands. +if has("autocmd") + + " Enable file type detection. Use the default filetype settings, so that + " mail gets 'tw' set to 72, 'cindent' is on in C files, etc. Also load + " indent files, to automatically do language-dependent indenting. + " Revert with ":filetype off". + filetype plugin indent on + + " Put these in an autocmd group, so that you can revert them with: + " ":augroup vimStartup | au! | augroup END" + augroup vimStartup + au! + + " When editing a file, always jump to the last known cursor position. + " Don't do it when the position is invalid, when inside an event handler + " (happens when dropping a file on gvim) and for a commit message (it's + " likely a different one than last time). + autocmd BufReadPost * + \ if line("'\"") >= 1 && line("'\"") <= line("$") && &ft !~# 'commit' | + \ exe "normal! g`\"" | + \ endif + + augroup END + + "[Try not to pollute the undo tree (https://vi.stackexchange.com/a/13401)]" + autocmd BufWritePre * + \ try | + \ undojoin | + \ catch /^Vim\%((\a\+)\)\=:E790/ | + \ finally | + \ call DeleteTrailingTWS() | + \ endtry + + if has("unix") || has("mac") + autocmd BufWritePost * call ChangeScriptMode() + endif + +endif " has("autocmd") diff --git a/config/nvim/init.vim b/config/nvim/init.vim deleted file mode 100644 index a80e7b8..0000000 --- a/config/nvim/init.vim +++ /dev/null @@ -1,4 +0,0 @@ -" http://vimcasts.org/episodes/meet-neovim/ -set runtimepath^=~/.vim runtimepath+=~/.vim/after -let &packpath=&runtimepath -source ~/.vimrc diff --git a/config/nvim/lua/keys.lua b/config/nvim/lua/keys.lua new file mode 100644 index 0000000..b57227e --- /dev/null +++ b/config/nvim/lua/keys.lua @@ -0,0 +1,59 @@ +-- Global mappings. + +-- Telescope -- +local tsbuiltin = require('telescope.builtin') + +-- Which key -- +local wk = require('which-key') +wk.register({ + ["space"] = { + e = {vim.diagnostic.open_float, "Open diagnostic float"}, + q = {vim.diagnostic.setloclist, "Add diagnostics to location list"}, + }, + [""] = { + e = { + name = "Telescope", -- optional group name + f = {tsbuiltin.find_files, "Find file"}, + F = {tsbuiltin.git_files, "Find file in git repo"}, + g = {tsbuiltin.live_grep, "Live grep"}, + o = {tsbuiltin.oldfiles, "Find previously open files"}, + q = {tsbuiltin.quickfix, "List items in quickfix"}, + r = {tsbuiltin.lsp_references, "List LSP references under the cursor"}, + }, + }, +}) + +-- See `:help vim.diagnostic.*` for documentation on any of the below functions +vim.keymap.set('n', '[d', vim.diagnostic.goto_prev) +vim.keymap.set('n', ']d', vim.diagnostic.goto_next) + +-- Use LspAttach autocommand to only map the following keys +-- after the language server attaches to the current buffer +vim.api.nvim_create_autocmd('LspAttach', { + group = vim.api.nvim_create_augroup('UserLspConfig', {}), + callback = function(ev) + -- Enable completion triggered by + vim.bo[ev.buf].omnifunc = 'v:lua.vim.lsp.omnifunc' + + -- Buffer local mappings. + -- See `:help vim.lsp.*` for documentation on any of the below functions + local opts = { buffer = ev.buf } + vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, opts) + vim.keymap.set('n', 'gd', vim.lsp.buf.definition, opts) + vim.keymap.set('n', 'gk', vim.lsp.buf.hover, opts) + vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, opts) + vim.keymap.set('n', 'k', vim.lsp.buf.signature_help, opts) + vim.keymap.set('n', 'wa', vim.lsp.buf.add_workspace_folder, opts) + vim.keymap.set('n', 'wr', vim.lsp.buf.remove_workspace_folder, opts) + vim.keymap.set('n', 'wl', function() + print(vim.inspect(vim.lsp.buf.list_workspace_folders())) + end, opts) + vim.keymap.set('n', 'D', vim.lsp.buf.type_definition, opts) + vim.keymap.set('n', 'rn', vim.lsp.buf.rename, opts) + vim.keymap.set({ 'n', 'v' }, 'ca', vim.lsp.buf.code_action, opts) + vim.keymap.set('n', 'gr', vim.lsp.buf.references, opts) + vim.keymap.set('n', 'f', function() + vim.lsp.buf.format { async = true } + end, opts) + end, +}) diff --git a/config/nvim/lua/plugins-config.lua b/config/nvim/lua/plugins-config.lua new file mode 100644 index 0000000..643920a --- /dev/null +++ b/config/nvim/lua/plugins-config.lua @@ -0,0 +1,127 @@ +-- completion config (nvim-cmp) -- +local cmp = require("cmp") +local luasnip = require("luasnip") + +cmp.setup({ + snippet = { + -- REQUIRED - you must specify a snippet engine + expand = function(args) + require('luasnip').lsp_expand(args.body) -- For `luasnip` users. + end, + }, + + window = { + -- completion = cmp.config.window.bordered(), + -- documentation = cmp.config.window.bordered(), + }, + + mapping = cmp.mapping.preset.insert({ + [''] = cmp.mapping.scroll_docs(-4), + [''] = cmp.mapping.scroll_docs(4), + [''] = cmp.mapping.complete(), + [''] = cmp.mapping.abort(), + -- [''] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items. + -- https://github.com/hrsh7th/nvim-cmp/wiki/Example-mappings + [''] = cmp.mapping(function(fallback) + if cmp.visible() then + if luasnip.expandable() then + luasnip.expand() + else + cmp.confirm({ select = true }) + end + else + fallback() + end + end), + + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item() + elseif luasnip.locally_jumpable() then + luasnip.jump() + else + fallback() + end + end, { "i", "s" }), + + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + elseif luasnip.locally_jumpable(-1) then + luasnip.jump(-1) + else + fallback() + end + end, { "i", "s" }), + }), + + sources = cmp.config.sources({ + { name = 'nvim_lsp' }, + -- { name = 'vsnip' }, -- For vsnip users. + { name = 'luasnip' }, -- For luasnip users. + -- { name = 'ultisnips' }, -- For ultisnips users. + -- { name = 'snippy' }, -- For snippy users. + }, { + { name = 'buffer' }, + }) + }) + +-- Set configuration for specific filetype. +cmp.setup.filetype('gitcommit', { + sources = cmp.config.sources({ + { name = 'git' }, -- You can specify the `git` source if [you were installed it](https://github.com/petertriho/cmp-git). + }, { + { name = 'buffer' }, + }) + }) + +-- Use buffer source for `/` and `?` (if you enabled `native_menu`, this won't work anymore). +cmp.setup.cmdline({ '/', '?' }, { + mapping = cmp.mapping.preset.cmdline(), + sources = { + { name = 'buffer' } + } + }) + +-- Use cmdline & path source for ':' (if you enabled `native_menu`, this won't work anymore). +cmp.setup.cmdline(':', { + mapping = cmp.mapping.preset.cmdline(), + sources = cmp.config.sources({ + { name = 'path' } + }, { + { name = 'cmdline' } + }), + matching = { disallow_symbol_nonprefix_matching = false } +}) + +-- Set up lspconfig. +local capabilities = require('cmp_nvim_lsp').default_capabilities() + +-- Setup language servers. +local lspconfig = require('lspconfig') +lspconfig.clangd.setup { + capabilities = capabilities +} +lspconfig.pyright.setup { + capabilities = capabilities +} +-- lspconfig.tsserver.setup {} +lspconfig.rust_analyzer.setup { + -- Server-specific settings. See `:help lspconfig-setup` + settings = { + ['rust-analyzer'] = {}, + }, + capabilities = capabilities +} + +-- LSP signature -- +local lsp_sig_cfg = {} +require('lsp_signature').setup(lsp_sig_cfg) + +-- Lualine -- +require("lualine").setup { + options = { + icons_enabled = false, + theme = "base16" + }, +} diff --git a/config/nvim/lua/plugins.lua b/config/nvim/lua/plugins.lua new file mode 100644 index 0000000..81bcdd1 --- /dev/null +++ b/config/nvim/lua/plugins.lua @@ -0,0 +1,95 @@ +local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" +if not (vim.uv or vim.loop).fs_stat(lazypath) then + vim.fn.system({ + "git", + "clone", + "--filter=blob:none", + "https://github.com/folke/lazy.nvim.git", + "--branch=stable", -- latest stable release + lazypath, + }) +end +vim.opt.rtp:prepend(lazypath) + +require("lazy").setup({ + { + "folke/which-key.nvim", + init = function() + vim.o.timeout = true + vim.o.timeoutlen = 500 + end + }, + "RRethy/base16-nvim", + "neovim/nvim-lspconfig", + "ray-x/lsp_signature.nvim", + -- { + -- "itchyny/lightline.vim", + -- init = function() + -- vim.g.lightline = {colorscheme = "base16lightline"} + -- end, + -- dependencies = {{"nolo18/base16lightline"}}, + -- }, + { + 'nvim-lualine/lualine.nvim', + dependencies = { 'nvim-tree/nvim-web-devicons' } + }, + "beyondmarc/opengl.vim", + { + "arrufat/vala.vim", + init = function() + vim.g.vala_syntax_folding_enabled = 0 + end + }, + 'tikhomirov/vim-glsl', + 'jamessan/vim-gnupg', + 'https://git.sr.ht/~sircmpwn/hare.vim', + 'romainl/vim-cool', + { + 'machakann/vim-highlightedyank', + init = function() + vim.g.highlightedyank_highlight_duration = 200 + end + }, + { + 'tcbbd/detectindent', + init = function() + vim.g.detectindent_preferred_indent=4 + vim.g.detectindent_autodetect=1 + end + }, + { + 'lambdalisue/suda.vim', + -- Allow writing of unwritable file with sudo, until neovim#1716 is fixed + init = function() + vim.g.suda_smart_edit = 1 + end + }, + 'neovim/nvim-lspconfig', + 'hrsh7th/cmp-nvim-lsp', + 'hrsh7th/cmp-buffer', + 'hrsh7th/cmp-path', + 'hrsh7th/cmp-cmdline', + 'hrsh7th/nvim-cmp', + + 'L3MON4D3/LuaSnip', + 'saadparwaiz1/cmp_luasnip', + { + 'nvim-telescope/telescope.nvim', + branch = "0.1.x", + dependencies = {{"nvim-lua/plenary.nvim"}} + }, + { + "nvim-treesitter/nvim-treesitter", + build = ":TSUpdate", + config = function () + local configs = require("nvim-treesitter.configs") + + configs.setup({ + ensure_installed = { "c", "lua", "vim", "vimdoc", "javascript", "html" }, + sync_install = false, + highlight = { enable = true }, + indent = { enable = true }, + }) + end + } +})