From f551318edc32b88eba8e3c5410de79b4343342af Mon Sep 17 00:00:00 2001 From: Vladan Popovic Date: Thu, 25 Nov 2021 22:10:31 +0100 Subject: [PATCH] move to lua and make a poor man's ide --- .gitignore | 1 + _init.vim | 0 init.lua | 79 ++++++++++++++++++++++++ init.vim | 143 ------------------------------------------- lua/completion.lua | 7 +++ lua/config/compe.lua | 78 +++++++++++++++++++++++ lua/config/init.lua | 2 + lua/keymappings.lua | 2 + lua/lang.lua | 133 ++++++++++++++++++++++++++++++++++++++++ lua/lsp_lua.lua | 27 ++++++++ lua/plugins.lua | 44 +++++++++++++ lua/settings.lua | 24 ++++++++ lua/utils/init.lua | 16 +++++ plugin/compe.vim | 5 ++ 14 files changed, 418 insertions(+), 143 deletions(-) create mode 100644 .gitignore create mode 100644 _init.vim create mode 100644 init.lua delete mode 100644 init.vim create mode 100644 lua/completion.lua create mode 100644 lua/config/compe.lua create mode 100644 lua/config/init.lua create mode 100644 lua/keymappings.lua create mode 100644 lua/lang.lua create mode 100644 lua/lsp_lua.lua create mode 100644 lua/plugins.lua create mode 100644 lua/settings.lua create mode 100644 lua/utils/init.lua create mode 100644 plugin/compe.vim diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c84aa4a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +plugin/packer_compiled.lua diff --git a/_init.vim b/_init.vim new file mode 100644 index 0000000..e69de29 diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..c9b6111 --- /dev/null +++ b/init.lua @@ -0,0 +1,79 @@ +-- LSP +-- Map leader to space +vim.g.mapleader = ' ' + +local fn = vim.fn +local execute = vim.api.nvim_command + +-- Sensible defaults +require('settings') + +-- Auto install packer.nvim if not exists +local install_path = fn.stdpath('data')..'/site/pack/packer/opt/packer.nvim' +if fn.empty(fn.glob(install_path)) > 0 then + execute('!git clone https://github.com/wbthomason/packer.nvim '..install_path) +end +vim.cmd [[packadd packer.nvim]] +vim.cmd 'autocmd BufWritePost plugins.lua PackerCompile' -- Auto compile when there are changes in plugins.lua + +vim.opt.autoindent = true +vim.opt.background = 'light' +vim.opt.errorformat:prepend('%f|%l col %c|%m') +vim.opt.expandtab = true +vim.opt.fileformat = 'unix' +vim.opt.number = true +vim.opt.pastetoggle = '' +vim.opt.shiftwidth = 4 +vim.opt.softtabstop = 4 +vim.opt.tabstop = 4 +vim.opt.textwidth = 125 +vim.opt.undofile = true +-- Enable vimrc files per project and disable unsafe commands in project vimrc +vim.opt.exrc = true +vim.opt.secure = true + +vim.cmd 'noremap :bn' +vim.cmd 'noremap :bp' + +-- Toggles on different plugins/modes +vim.cmd 'nmap :ToggleMouse' +vim.cmd 'nmap :set nonumber!' +vim.cmd 'nmap :NERDTreeToggle' +-- +-- Highlight trailing whitespace (darker red) and remove all with Ctrl+k +vim.cmd 'highlight WhitespaceEOL ctermbg=red guibg=#ab0d0d' +vim.cmd 'match WhitespaceEOL /\\s\\+\\%#\\@ :let _s=@/:%s/\\s\\+$//e:let @/=_s' + +vim.cmd 'highlight Visual cterm=bold ctermbg=Grey ctermfg=NONE' +vim.cmd 'highlight Search ctermfg=Black' +vim.cmd 'highlight Comment ctermfg=DarkGrey' +vim.cmd 'highlight SignColumn ctermbg=0' +vim.cmd 'highlight LineNr ctermbg=0 ctermfg=248' +vim.cmd 'highlight Folded ctermbg=Green ctermfg=Black' +vim.cmd 'highlight Pmenu ctermbg=gray guibg=gray' +vim.cmd 'let g:airline_theme=\'papercolor\'' + +-- Find files using Telescope command-line sugar. +vim.cmd 'nnoremap ff Telescope find_files' +vim.cmd 'nnoremap fg Telescope live_grep' +vim.cmd 'nnoremap fb Telescope buffers' +vim.cmd 'nnoremap fh Telescope help_tags' +vim.cmd 'nnoremap fl Telescope git_files' + + +-- Install plugins +require('plugins') + +-- Key mappings +require('keymappings') + +-- Setup Lua language server using submodule +require('lsp_lua') + +-- OR you can invoke them individually here +--require('colorscheme') -- color scheme +require('config.compe') -- completion +--require('fugitive') -- fugitive + +require('lang') diff --git a/init.vim b/init.vim deleted file mode 100644 index 919f6ce..0000000 --- a/init.vim +++ /dev/null @@ -1,143 +0,0 @@ -call plug#begin('~/.local/share/nvim/plugged') - -Plug 'davidhalter/jedi-vim' -Plug 'ncm2/float-preview.nvim' -Plug 'dense-analysis/ale' -Plug 'jacoborus/tender.vim' -Plug 'vim-airline/vim-airline' -Plug 'vim-airline/vim-airline-themes' -Plug 'airblade/vim-gitgutter' -Plug 'scrooloose/nerdtree' -Plug 'gleam-lang/gleam.vim' -Plug 'cespare/vim-toml' -Plug 'rust-lang/rust.vim' -Plug 'vim-scripts/DrawIt' - -call plug#end() - -let g:airline_theme='papercolor' -let g:airline#extensions#ale#enabled=1 - -inoremap pumvisible() ? "\" : "\" -inoremap pumvisible() ? "\" : "\" - -let g:jedi#completions_enabled=0 -let g:jedi#use_splits_not_buffers="right" - -" Preview window is floating -let g:float_preview#docked=0 -let g:float_preview#max_width=100 -let g:float_preview#max_height=150 -let g:float_preview#auto_close=0 - -set tabstop=4 -set softtabstop=4 -set shiftwidth=4 -set textwidth=79 -set expandtab -set autoindent -set fileformat=unix -set number -" Hide top preview window, use float_preview instead -set completeopt-=preview -" Enable folding on indent -set foldmethod=indent -set foldlevel=79 -set omnifunc=ale#completion#OmniFunc - -" Lint and check types -let b:ale_linters={ -\ 'python': ['mypy', 'pyls', 'pylint'], -\ 'ocaml': ['merlin'], -\ 'rust': ['analyzer', 'cargo'] -\ } -let b:ale_fixers = { -\ 'rust': ['rustfmt'], -\ 'python': ['autopep8'], -\ 'ocaml': ['ocamlformat'] -\} - -let g:ale_rust_rustfmt_options='--edition 2018' - -let g:ale_fix_on_save=1 -let g:ale_lint_on_save=1 -let g:ale_lint_on_enter=0 -let g:ale_list_window_size=20 -" Use .venv as a global default -let g:ale_virtualenv_dir_names=['.venv'] -let g:ale_completion_enabled=1 -let g:ale_sign_error="✗" -let g:ale_sign_warning="⚠" -let g:ale_echo_msg_error_str = 'E' -let g:ale_echo_msg_warning_str = 'W' -let g:ale_echo_msg_format = '[%linter%] %s [%severity%]' - -" Enable warnings about trailing whitespace for all files. -let b:ale_warn_about_trailing_whitespace=1 - -nmap e :ALEDetail -noremap d :ALEGoToDefinition -noremap g] :ALEGoToDefinition -noremap h :ALEHover - -" ALE colors -highlight ALEError ctermbg=DarkRed ctermfg=Black -highlight ALEWarning ctermbg=Yellow ctermfg=White - -" Use TAB to switch between buffers -noremap :bn -noremap :bp - -" Highlight trailing whitespace (darker red) and remove all with Ctrl+k -highlight WhitespaceEOL ctermbg=red guibg=#ab0d0d -match WhitespaceEOL /\s\+\%#\@ :let _s=@/:%s/\s\+$//e:let @/=_s - -" Much better with Tomorrow Night Bright color theme set in alacritty -" set background=dark -highlight Search ctermfg=Black -highlight Comment ctermfg=Grey -highlight SignColumn ctermbg=0 -highlight LineNr ctermbg=0 ctermfg=248 -highlight Folded ctermbg=Green ctermfg=Black -highlight Pmenu ctermbg=gray guibg=gray - -highlight GitGutterAdd ctermfg=Green -highlight GitGutterChange ctermfg=Red -highlight GitGutterDelete ctermfg=DarkRed -highlight GitGutterAddLine ctermbg=LightGreen -highlight GitGutterChangeLine ctermbg=Yellow -highlight GitGutterDeleteLine ctermbg=LightRed -highlight GitGutterChangeDeleteLine ctermbg=LightRed - -nmap ]h (GitGutterNextHunk) -nmap [h (GitGutterPrevHunk) - -let g:gitgutter_sign_added='+' -let g:gitgutter_sign_modified='±' -let g:gitgutter_sign_removed='-' -let g:gitgutter_sign_removed_first_line='^' -let g:gitgutter_sign_modified_removed='-' -let g:gitgutter_map_keys=0 -let g:gitgutter_set_sign_backgrounds=1 - -" Toggles on different plugins/modes -nmap :ToggleMouse -set pastetoggle= -nmap :set nonumber! -nmap :GitGutterBufferToggle -nmap :NERDTreeToggle -nmap :GitGutterLineHighlightsToggle - -autocmd FileType yaml setlocal ts=2 sts=2 sw=2 expandtab - -" Maintain undo history between sessions -if !isdirectory("/tmp/.vim-undo-dir-vladan") - call mkdir("/tmp/.vim-undo-dir-vladan", "", 0700) -endif -set undodir=/tmp/.vim-undo-dir-vladan -set undofile -" Enable vimrc files per project -set exrc -" Disable unsafe commands in project vimrc -set secure diff --git a/lua/completion.lua b/lua/completion.lua new file mode 100644 index 0000000..e93ee93 --- /dev/null +++ b/lua/completion.lua @@ -0,0 +1,7 @@ +local utils = require('utils') +utils.opt('o', 'completeopt', 'menuone,noinsert,noselect') +vim.cmd [[set shortmess+=c]] +vim.g.completion_confirm_key = "" +vim.g.completion_matching_strategy_list = {'exact', 'substring', 'fuzzy'}-- to navigate the completion menu +utils.map('i', '', 'pumvisible() ? "\\" : "\\"', {expr = true}) +utils.map('i', '', 'pumvisible() ? "\\" : "\\"', {expr = true}) diff --git a/lua/config/compe.lua b/lua/config/compe.lua new file mode 100644 index 0000000..3d01a95 --- /dev/null +++ b/lua/config/compe.lua @@ -0,0 +1,78 @@ +-- Configuration for nvim-compe + +local utils = require('utils') + +vim.cmd [[set shortmess+=c]] +utils.opt('o', 'completeopt', 'menuone,noselect') + +require'compe'.setup { + enabled = true; + autocomplete = true; + debug = false; + min_length = 1; + preselect = 'enable'; + throttle_time = 80; + source_timeout = 200; + incomplete_delay = 400; + allow_prefix_unmatch = false; + max_abbr_width = 1000; + max_kind_width = 1000; + max_menu_width = 1000000; + documentation = true; + + + source = { + path = true; + buffer = true; + calc = true; + vsnip = true; + nvim_lsp = true; + nvim_lua = true; + spell = true; + tags = true; + snippets_nvim = true; + treesitter = true; + }; +} + +local t = function(str) + return vim.api.nvim_replace_termcodes(str, true, true, true) +end + +local check_back_space = function() + local col = vim.fn.col('.') - 1 + if col == 0 or vim.fn.getline('.'):sub(col, col):match('%s') then + return true + else + return false + end +end + +-- Use (s-)tab to: +--- move to prev/next item in completion menuone +--- jump to prev/next snippet's placeholder +-- _G.tab_complete = function() +-- if vim.fn.pumvisible() == 1 then +-- return t "" +-- elseif vim.fn.call("vsnip#available", {1}) == 1 then +-- return t "(vsnip-expand-or-jump)" +-- elseif check_back_space() then +-- return t "" +-- else +-- return vim.fn['compe#complete']() +-- end +-- end +-- _G.s_tab_complete = function() +-- if vim.fn.pumvisible() == 1 then +-- return t "" +-- elseif vim.fn.call("vsnip#jumpable", {-1}) == 1 then +-- return t "(vsnip-jump-prev)" +-- else +-- return t "" +-- end +-- end + +-- utils.map("i", "", "v:lua.tab_complete()", {expr = true}) +-- utils.map("s", "", "v:lua.tab_complete()", {expr = true}) +-- utils.map("i", "", "v:lua.s_tab_complete()", {expr = true}) +-- utils.map("s", "", "v:lua.s_tab_complete()", {expr = true}) diff --git a/lua/config/init.lua b/lua/config/init.lua new file mode 100644 index 0000000..97bca80 --- /dev/null +++ b/lua/config/init.lua @@ -0,0 +1,2 @@ +-- nvim-compe +require('config.compe') diff --git a/lua/keymappings.lua b/lua/keymappings.lua new file mode 100644 index 0000000..958a746 --- /dev/null +++ b/lua/keymappings.lua @@ -0,0 +1,2 @@ +local utils = require('utils') +utils.map('n', '', 'noh') -- Clear highlights diff --git a/lua/lang.lua b/lua/lang.lua new file mode 100644 index 0000000..e2d8f4e --- /dev/null +++ b/lua/lang.lua @@ -0,0 +1,133 @@ +USER = vim.fn.expand('$USER') + +-- Language specific key mappings +--require('lang.keymappings') + +local on_attach = function(client, bufnr) + + require'lsp_signature'.on_attach(client) + + local function buf_set_keymap(...) + vim.api.nvim_buf_set_keymap(bufnr, ...) + end + local function buf_set_option(...) + vim.api.nvim_buf_set_option(bufnr, ...) + end + + buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc') + + -- Mappings. + local opts = {noremap = true, silent = true} + buf_set_keymap('n', 'gD', 'lua vim.lsp.buf.declaration()', opts) + buf_set_keymap('n', 'gd', 'lua vim.lsp.buf.definition()', opts) + buf_set_keymap('n', 'K', 'lua vim.lsp.buf.hover()', opts) + buf_set_keymap('n', 'gi', 'lua vim.lsp.buf.implementation()', opts) + buf_set_keymap('n', '', 'lua vim.lsp.buf.signature_help()', opts) + buf_set_keymap('n', 'gr', 'lua vim.lsp.buf.references()', opts) + buf_set_keymap('n', '[d', 'lua vim.lsp.diagnostic.goto_prev()', opts) + buf_set_keymap('n', ']d', 'lua vim.lsp.diagnostic.goto_next()', opts) + buf_set_keymap('n', '[l', 'lua vim.lsp.diagnostic.show_line_diagnostics()', opts) + buf_set_keymap('n', ']l', 'lua vim.lsp.diagnostic.set_loclist()', opts) + buf_set_keymap('n', 'law', 'lua vim.lsp.buf.add_workspace_folder()', opts) + buf_set_keymap('n', 'lrw', 'lua vim.lsp.buf.remove_workspace_folder()', opts) + buf_set_keymap('n', 'llw', 'lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))', opts) + buf_set_keymap('n', 'lt', 'lua vim.lsp.buf.type_definition()', opts) + buf_set_keymap('n', 'lrn', 'lua vim.lsp.buf.rename()', opts) + buf_set_keymap('n', 'lca', 'lua vim.lsp.buf.code_action()', opts) + + -- Set some keybinds conditional on server capabilities + if client.resolved_capabilities.document_formatting then + buf_set_keymap("n", "lf", + "lua vim.lsp.buf.formatting()", opts) + elseif client.resolved_capabilities.document_range_formatting then + buf_set_keymap("n", "lf", + "lua vim.lsp.buf.range_formatting()", opts) + end + + -- Set autocommands conditional on server_capabilities + if client.resolved_capabilities.document_highlight then + vim.api.nvim_exec([[ + hi LspReferenceRead cterm=bold ctermbg=red guibg=LightYellow + hi LspReferenceText cterm=bold ctermbg=red guibg=LightYellow + hi LspReferenceWrite cterm=bold ctermbg=red guibg=LightYellow + augroup lsp_document_highlight + autocmd! * + autocmd CursorHold lua vim.lsp.buf.document_highlight() + autocmd CursorMoved lua vim.lsp.buf.clear_references() + augroup END + ]], false) + end +end + +local nvim_lsp = require('lspconfig') +local capabilities = vim.lsp.protocol.make_client_capabilities() + +-- Code actions +capabilities.textDocument.codeAction = { + dynamicRegistration = true, + codeActionLiteralSupport = { + codeActionKind = { + valueSet = (function() + local res = vim.tbl_values(vim.lsp.protocol.CodeActionKind) + table.sort(res) + return res + end)() + } + } +} + +capabilities.textDocument.completion.completionItem.snippetSupport = true; + +-- LSPs +local servers = {"pylsp", "rust_analyzer", "vimls"} +for _, lsp in ipairs(servers) do + nvim_lsp[lsp].setup {capabilities = capabilities, on_attach = on_attach} +end + +-- symbols-outline.nvim +vim.g.symbols_outline = { + highlight_hovered_item = true, + show_guides = true, + auto_preview = false, -- experimental + position = 'right', + keymaps = { + close = "", + goto_location = "", + focus_location = "o", + hover_symbol = "", + rename_symbol = "r", + code_actions = "a" + }, + lsp_blacklist = {} +} + +-- LSP Enable diagnostics +vim.lsp.handlers["textDocument/publishDiagnostics"] = + vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, { + virtual_text = false, + underline = true, + signs = true, + update_in_insert = false + }) + +-- Send diagnostics to quickfix list +do + local method = "textDocument/publishDiagnostics" + local default_handler = vim.lsp.handlers[method] + vim.lsp.handlers[method] = function(err, method, result, client_id, bufnr, + config) + default_handler(err, method, result, client_id, bufnr, config) + local diagnostics = vim.lsp.diagnostic.get_all() + local qflist = {} + for bufnr, diagnostic in pairs(diagnostics) do + for _, d in ipairs(diagnostic) do + d.bufnr = bufnr + d.lnum = d.range.start.line + 1 + d.col = d.range.start.character + 1 + d.text = d.message + table.insert(qflist, d) + end + end + vim.lsp.util.set_qflist(qflist) + end +end diff --git a/lua/lsp_lua.lua b/lua/lsp_lua.lua new file mode 100644 index 0000000..c825708 --- /dev/null +++ b/lua/lsp_lua.lua @@ -0,0 +1,27 @@ +-- Your custom attach function for nvim-lspconfig goes here. +local on_attach = function(client, bufnr) + require('completion').on_attach() + + local function buf_set_keymap(...) vim.api.nvim_buf_set_keymap(bufnr, ...) end + local function buf_set_option(...) vim.api.nvim_buf_set_option(bufnr, ...) end + + buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc') + + -- Mappings + local opts = { noremap=true, silent=true } + buf_set_keymap('n', 'gD', 'lua vim.lsp.buf.declaration()', opts) + buf_set_keymap('n', 'gd', 'lua vim.lsp.buf.definition()', opts) + buf_set_keymap('n', 'H', 'lua vim.lsp.buf.hover()', opts) + buf_set_keymap('n', 'gi', 'lua vim.lsp.buf.implementation()', opts) + buf_set_keymap('n', '', 'lua vim.lsp.buf.signature_help()', opts) + buf_set_keymap('n', 'gr', 'lua vim.lsp.buf.references()', opts) + buf_set_keymap('n', '[d', 'lua vim.lsp.diagnostic.goto_prev()', opts) + buf_set_keymap('n', ']d', 'lua vim.lsp.diagnostic.goto_next()', opts) + +end + +-- To get builtin LSP running, do something like: +-- NOTE: This replaces the calls where you would have before done `require('nvim_lsp').sumneko_lua.setup()` +--require('nlua.lsp.nvim').setup(require('lspconfig'), { +-- on_attach = on_attach, +--}) diff --git a/lua/plugins.lua b/lua/plugins.lua new file mode 100644 index 0000000..32397a0 --- /dev/null +++ b/lua/plugins.lua @@ -0,0 +1,44 @@ +return require('packer').startup(function() + + -- Packer can manage itself as an optional plugin + use {'wbthomason/packer.nvim', opt = true} + + -- Fuzzy finder + use { + 'nvim-telescope/telescope.nvim', + requires = {{'nvim-lua/popup.nvim'}, {'nvim-lua/plenary.nvim'}} + } + + -- LSP and completion + use { 'neovim/nvim-lspconfig' } + use { 'nvim-lua/completion-nvim' } + + -- Lua development + use { 'tjdevries/nlua.nvim' } + + + -- Vim dispatch + use { 'tpope/vim-dispatch' } + + -- Fugitive for Git + use { 'tpope/vim-fugitive' } + + -- Fugitive for Git + use { 'ray-x/lsp_signature.nvim' } + + -- Airline status bar + use { 'vim-airline/vim-airline' } + use { 'vim-airline/vim-airline-themes' } + + use { 'cespare/vim-toml' } + use { 'folke/trouble.nvim' } + use { 'glepnir/lspsaga.nvim' } + use { 'hrsh7th/nvim-compe' } + use { 'jacoborus/tender.vim' } + use { 'kyazdani42/nvim-web-devicons' } + use { 'RRethy/vim-illuminate' } + use { 'rust-lang/rust.vim' } + use { 'scrooloose/nerdtree' } + use { 'vim-scripts/DrawIt' } + +end) diff --git a/lua/settings.lua b/lua/settings.lua new file mode 100644 index 0000000..d67e471 --- /dev/null +++ b/lua/settings.lua @@ -0,0 +1,24 @@ +local utils = require('utils') + +local cmd = vim.cmd +local indent = 4 + +cmd 'syntax enable' +cmd 'filetype plugin indent on' +utils.opt('b', 'expandtab', true) +utils.opt('b', 'shiftwidth', indent) +utils.opt('b', 'smartindent', true) +utils.opt('b', 'tabstop', indent) +utils.opt('o', 'hidden', true) +utils.opt('o', 'ignorecase', true) +utils.opt('o', 'scrolloff', 4 ) +utils.opt('o', 'shiftround', true) +utils.opt('o', 'smartcase', true) +utils.opt('o', 'splitbelow', true) +utils.opt('o', 'splitright', true) +utils.opt('o', 'wildmode', 'list:longest') +utils.opt('w', 'number', true) +utils.opt('o', 'clipboard','unnamed,unnamedplus') + +-- Highlight on yank +vim.cmd 'au TextYankPost * lua vim.highlight.on_yank {on_visual = false}' diff --git a/lua/utils/init.lua b/lua/utils/init.lua new file mode 100644 index 0000000..bd53235 --- /dev/null +++ b/lua/utils/init.lua @@ -0,0 +1,16 @@ +local utils = { } + +local scopes = {o = vim.o, b = vim.bo, w = vim.wo} + +function utils.opt(scope, key, value) + scopes[scope][key] = value + if scope ~= 'o' then scopes['o'][key] = value end +end + +function utils.map(mode, lhs, rhs, opts) + local options = {noremap = true} + if opts then options = vim.tbl_extend('force', options, opts) end + vim.api.nvim_set_keymap(mode, lhs, rhs, options) +end + +return utils diff --git a/plugin/compe.vim b/plugin/compe.vim new file mode 100644 index 0000000..2503d85 --- /dev/null +++ b/plugin/compe.vim @@ -0,0 +1,5 @@ +inoremap compe#complete() +inoremap compe#confirm('') +inoremap compe#close('') +inoremap compe#scroll({ 'delta': +4 }) +inoremap compe#scroll({ 'delta': -4 })