diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d7ad043 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +plugin/ diff --git a/init.lua b/init.lua index 2b183c1..c9a4c0a 100644 --- a/init.lua +++ b/init.lua @@ -1,219 +1,5 @@ --- Install packer -local execute = vim.api.nvim_command -local install_path = vim.fn.stdpath('data')..'/site/pack/packer/opt/packer.nvim' - --- Check that packer is installed -if vim.fn.empty(vim.fn.glob(install_path)) > 0 then - execute('!git clone https://github.com/wbthomason/packer.nvim '..install_path) -end - -vim.cmd [[packadd packer.nvim]] -vim.api.nvim_exec([[ - augroup Packer - autocmd! - autocmd BufWritePost plugins.lua PackerCompile - augroup end -]], false) - -local use = require('packer').use -local packer = require('packer') -packer.startup(function() - use { 'wbthomason/packer.nvim', opt = true } -- Package manager - - -- visuals - use 'gruvbox-community/gruvbox' - - -- file management - use { - 'nvim-telescope/telescope.nvim', - requires = { - {'nvim-lua/popup.nvim'}, - {'nvim-lua/plenary.nvim'}, - {'nvim-treesitter/nvim-treesitter'}, - } - }-- search and select tool - use 'preservim/nerdtree' - - -- editing behaviour - use 'jiangmiao/auto-pairs' - use 'tpope/vim-commentary' -- Easily comment/uncomment code - use 'tpope/vim-surround' -- surround text objects with delimiters - - -- git TODO: Learn how to use - use 'airblade/vim-gitgutter' - use 'tpope/vim-fugitive' - - -- LSP - use 'neovim/nvim-lspconfig' - use 'nvim-lua/lsp_extensions.nvim' - use 'nvim-lua/completion-nvim' - - -- Language specific - use 'rust-lang/rust.vim' -end) - --- settings -- this is all of the basic vim settings -local o = vim.o -- global -local g = vim.g -- global 2? -local wo = vim.wo -- window local -local bo = vim.bo -- buffer local - --- basic UI -o.background = 'dark' -o.termguicolors = true -- enable 24 bit colors in TUI -vim.cmd('colorscheme gruvbox') -vim.cmd('syntax enable') -wo.number = true -wo.relativenumber = true -o.signcolumn = 'yes' -o.splitright = true -o.splitbelow = true - --- text -wo.wrap = false -wo.foldenable = false -o.mouse = 'a' - --- search -o.hlsearch = false -o.incsearch = true -o.ignorecase = true - --- temporary file configuration -o.swapfile = false -o.undofile = true -bo.undofile = true -o.dir = '/tmp' -o.hidden = true -- do not save when switching buffers - --- LSP -o.updatetime = 250 -o.completeopt = 'menuone,noinsert,noselect' -o.inccommand = 'nosplit' - --- keybindings -local map = vim.api.nvim_set_keymap -g.mapleader = ' ' --- window navigation -map('n', '', 'j', {noremap = true}) -map('n', '', 'k', {noremap = true}) -map('n', '', 'l', {noremap = true}) -map('n', '', 'h', {noremap = true}) --- terminal -map('t', '', '', {noremap = true}) --- NERDTree -map('n', 'nt', 'NERDTreeToggle', {noremap = true}) --- Telescope -map('n', '', 'Telescope git_files', {noremap = true}) - --- LSP TODO: make lua instead of vimscript --- --- Use completion-nvim in every buffer -vim.api.nvim_exec([[ - autocmd BufEnter * lua require'completion'.on_attach() -]], false) - --- Avoid showing message extra message when using completion --- - --- Use and to navigate through popup menu -vim.api.nvim_exec([[ - inoremap pumvisible() ? "\" : "\" - inoremap pumvisible() ? "\" : "\" -]], false) - --- use as trigger keys -vim.api.nvim_exec([[ - imap (completion_smart_tab) - imap (completion_smart_s_tab) -]], false) - --- code shortcuts -local opts = { noremap=true, silent=true } -map('n', 'gD', 'lua vim.lsp.buf.declaration()', opts) -map('n', 'gd', 'lua vim.lsp.buf.definition()', opts) -map('n', 'K', 'lua vim.lsp.buf.hover()', opts) --- map('n', '', 'lua vim.lsp.buf.signature_help()', opts) -map('n', 'D', 'lua vim.lsp.buf.type_definition()', opts) -map('n', 'rn', 'lua vim.lsp.buf.rename()', opts) -map('n', 'gr', 'lua vim.lsp.buf.references()', opts) -map('n', 'd', 'lua vim.lsp.diagnostic.show_line_diagnostics()', opts) -map('n', '[g', 'lua vim.lsp.diagnostic.goto_prev()', opts) -map('n', ']g', 'lua vim.lsp.diagnostic.goto_next()', opts) - --- autocommands - --- Highlight on yank -vim.cmd('au TextYankPost * lua vim.highlight.on_yank {on_visual = false}' )-- disabled in visual mode - --- Trim Whitespace -vim.api.nvim_exec([[ -fun! TrimWhitespace() - let l:save = winsaveview() - keeppatterns %s/\s\+$//e - call winrestview(l:save) -endfun -augroup AUTOCOMMANDGROUP - autocmd! - autocmd BufWritePre * :call TrimWhitespace() -augroup END -]], false) - --- language server configs --- LSP settings -local nvim_lsp = require('lspconfig') -local on_attach = function(_client, bufnr) - require'completion'.on_attach(_client) - vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc') - - local opts = { noremap=true, silent=true } - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gD', 'lua vim.lsp.buf.declaration()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gd', 'lua vim.lsp.buf.definition()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'K', 'lua vim.lsp.buf.hover()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gi', 'lua vim.lsp.buf.implementation()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', '', 'lua vim.lsp.buf.signature_help()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'D', 'lua vim.lsp.buf.type_definition()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'rn', 'lua vim.lsp.buf.rename()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gr', 'lua vim.lsp.buf.references()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'ga', 'lua vim.lsp.buf.code_action()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'e', 'lua vim.lsp.diagnostic.show_line_diagnostics()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', '[d', 'lua vim.lsp.diagnostic.goto_prev()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', ']d', 'lua vim.lsp.diagnostic.goto_next()', opts) - vim.api.nvim_buf_set_keymap(bufnr, 'n', 'q', 'lua vim.lsp.diagnostic.set_loclist()', opts) -end - --- Rust -vim.cmd([[let g:rustfmt_autosave = 1]]) -nvim_lsp['rust_analyzer'].setup { - on_attach = on_attach, - settings = { - ["rust-analyzer"] = { - cargo = { - allFeatures = true - }, - checkOnSave = { - command = "clippy", - extraArgs = "["--", "-W", "clippy::pedantic"]" - } - } - } -} - --- Python -require'lspconfig'.jedi_language_server.setup{} - --- Enable diagnostics -vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with( - vim.lsp.diagnostic.on_publish_diagnostics, { - virtual_text = true, - signs = true, - update_in_insert = true, - } -) - --- Show diagnostic popup on cursor hold -vim.cmd([[autocmd CursorHold * lua vim.lsp.diagnostic.show_line_diagnostics()]]) - --- Enable type inlay hints -vim.cmd([[autocmd CursorMoved,InsertLeave,BufEnter,BufWinEnter,TabEnter,BufWritePost * lua require'lsp_extensions'.inlay_hints{ prefix = '', highlight = "Comment", enabled = {"TypeHint", "ChainingHint", "ParameterHint"} }]]) - +require('plugins') -- Setup packer.nvim and install plugins +require('nvim_opts') -- Basic vim options +require('autocmd') -- Convenient Autocommands +require('lsp') +require('keybindings') diff --git a/lua/autocmd.lua b/lua/autocmd.lua new file mode 100644 index 0000000..f347b62 --- /dev/null +++ b/lua/autocmd.lua @@ -0,0 +1,16 @@ +-- Highlight on yank +vim.cmd('au TextYankPost * lua vim.highlight.on_yank {on_visual = false}' )-- disabled in visual mode + +-- Trim Whitespace +vim.api.nvim_exec([[ +fun! TrimWhitespace() + let l:save = winsaveview() + keeppatterns %s/\s\+$//e + call winrestview(l:save) +endfun +augroup AUTOCOMMANDGROUP + autocmd! + autocmd BufWritePre * :call TrimWhitespace() + autocmd BufEnter,BufWinEnter,TabEnter *.rs :lua require'lsp_extensions'.inlay_hints{} +augroup END +]], false) diff --git a/lua/keybindings.lua b/lua/keybindings.lua new file mode 100644 index 0000000..e9094a2 --- /dev/null +++ b/lua/keybindings.lua @@ -0,0 +1,81 @@ +local map = vim.api.nvim_set_keymap + +-- Avoid infinitely recursive definitions +options = { noremap = true } + +-- Copy/paste +map('n', 'y', '"+y', options) +map('v', 'y', '"+y', options) + +-- WINDOW MANAGEMENT + +-- Navigate windows +map('n', '', 'h', options) +map('n', '', 'j', options) +map('n', '', 'k', options) +map('n', '', 'l', options) + +-- Move windows TODO + +-- Terminal +map('t', '', '', options) -- Exit Terminal mode enter Normal + +-- FILE NAVIGATION +map('n', '', 'Telescope git_files', options) +map('n', '', 'Telescope find_files', options) +-- Grep for prompted str project wide +map('n', 'ps', "lua require('telescope.builtin').grep_string({ search = vim.fn.input(\"Grep For > \")})", options) +-- Telescope fuzzy search for buffers +map('n', 'pb', "lua require('telescope.builtin').buffers()", options) + +-- CODE NAVIGATOIN + +-- Quick Fix Lists +-- global -- using control +map('n', 'J', 'cnextzz', options) -- Go to next item in global qfixlist +map('n', 'K', 'cprevzz', options) -- Go to previous item in global qfixlist +-- Toggle the window if there are items in the qfixlist; allow recursive +map('n', 'Q', 'call ToggleQFList(1)', {}) -- see plugin/navigation.vim for ToggleQFList definition +-- local -- using leader +map('n', 'j', 'lnextzz', options) -- Go to next item in local qfixlist +map('n', 'k', 'lprevzz', options) -- Go to previous item in global qfixlist +-- Toggle the window if there are items in the qfixlist; allow recursive +map('n', 'q', 'call ToggleQFList(0)', {}) -- see plugin/navigation.vim for ToggleQFList definition + +-- git +map('n', 'gs', 'G', options) + +-- LSP +-- 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) + 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 + + -- Enable completion triggered by + 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()', options) + buf_set_keymap('n', 'gd', 'lua vim.lsp.buf.definition()', options) + buf_set_keymap('n', '', 'lua vim.lsp.buf.hover()', options) + buf_set_keymap('n', 'gi', 'lua vim.lsp.buf.implementation()', options) + buf_set_keymap('n', 's', 'lua vim.lsp.buf.signature_help()', options) + buf_set_keymap('n', 'rn', 'lua vim.lsp.buf.rename()', options) + buf_set_keymap('n', 'ga', 'lua vim.lsp.buf.code_action()', { noremap = true }) + buf_set_keymap('n', 'gr', 'lua vim.lsp.buf.references()', options) + buf_set_keymap('n', 'd', 'lua vim.lsp.diagnostic.show_line_diagnostics()', options) + -- buf_set_keymap('n', '[d', 'lua vim.lsp.diagnostic.goto_prev()', options) + -- buf_set_keymap('n', ']d', 'lua vim.lsp.diaoNostic.goto_next()', options) + buf_set_keymap('n', 'q', 'lua vim.diagnostic.set_qflist()', options) + buf_set_keymap('n', 'f', 'lua vim.lsp.buf.formatting()', options) + +end + +-- Code actions +map('n', 't', 'CargoTest', options) -- Run test under cursor + +return { on_attach = on_attach } diff --git a/lua/lsp.lua b/lua/lsp.lua new file mode 100644 index 0000000..b885621 --- /dev/null +++ b/lua/lsp.lua @@ -0,0 +1,22 @@ +local on_attach = require'keybindings'.on_attach +local capabilities = require'cmp_nvim_lsp'.update_capabilities(vim.lsp.protocol.make_client_capabilities()) +local cmp = require'nvim-cmp-cfg'.cmp + +-- SERVERS +-- rust_analyzer +vim.g.rustfmt_autosave = 1 +require'lspconfig'.rust_analyzer.setup{ + on_attach = on_attach, + capabilities = capabilities, + settings = { + ["rust-analyzer"] = { + procMacro = { + enable = true, + }, + checkOnSave = { + command = 'clippy', + extraArgs = "-W clippy::pedantic" + }, + } + } +} diff --git a/lua/nvim-cmp-cfg.lua b/lua/nvim-cmp-cfg.lua new file mode 100644 index 0000000..ff984a5 --- /dev/null +++ b/lua/nvim-cmp-cfg.lua @@ -0,0 +1,56 @@ +-- TODO: Improve docs +-- Setup nvim-cmp. +local cmp = require'cmp' + +-- Ensure vsnip is installed +require'cmp_vsnip' + +cmp.setup({ + snippet = { + expand = function(args) + vim.fn["vsnip#anonymous"](args.body) + end, + }, + mapping = { + [''] = cmp.mapping(cmp.mapping.complete(), { 'i', 'c' }), + [''] = cmp.mapping.confirm({ select = true }), + [''] = function(fallback) + if cmp.visible() then + cmp.select_next_item() + else + fallback() + end + end, + [''] = function(fallback) + if cmp.visible() then + cmp.select_prev_item() + else + fallback() + end + end, + }, + sources = cmp.config.sources({ + { name = 'nvim_lsp' }, + { name = 'vsnip' }, + }, { + { name = 'buffer' }, + }), +}) + +-- Use buffer source for `/` (if you enabled `native_menu`, this won't work anymore). +cmp.setup.cmdline('/', { + sources = { + { name = 'buffer' } + } +}) + +-- Use cmdline & path source for ':' (if you enabled `native_menu`, this won't work anymore). +cmp.setup.cmdline(':', { + sources = cmp.config.sources({ + { name = 'path' } + }, { + { name = 'cmdline' } + }) +}) + +return { cmp = cmp } diff --git a/lua/nvim_opts.lua b/lua/nvim_opts.lua new file mode 100644 index 0000000..35a6eec --- /dev/null +++ b/lua/nvim_opts.lua @@ -0,0 +1,42 @@ +local o = vim.o -- global +local g = vim.g -- global 2? +local wo = vim.wo -- window local +local bo = vim.bo -- buffer local + +g.mapleader = ' ' + +-- basic UI +o.background = 'dark' +o.termguicolors = true -- enable 24 bit colors in TUI +vim.cmd 'colorscheme gruvbox' +g.syntax = true +wo.number = true +wo.relativenumber = true +o.signcolumn = 'yes' +o.splitright = true +o.splitbelow = true +o.colorcolumn = '80' + +-- text +wo.wrap = false +wo.foldenable = false +o.mouse = 'a' -- enable mouse in all modes +o.tabstop = 4 -- Display width of a +o.softtabstop = 4 -- How large inserted tabs are +o.expandtab = false -- Insert instead of spaces +o.shiftwidth = 4 -- "Number of spaces used for each step of an (auto)indent" +o.scrolloff = 8 -- Start scrolling when 8 away from top/bottom + +-- search +o.hlsearch = false +o.incsearch = true -- Incremental highlighting while typing a search query +o.ignorecase = true +o.smartcase = true -- Match case if a capital letter is used + +-- temporary file configuration +o.swapfile = false +o.undofile = true +o.dir = '/tmp' + +-- Buffers +o.hidden = true -- Allow hidden buffers without saving diff --git a/lua/plugins.lua b/lua/plugins.lua new file mode 100644 index 0000000..41e4f2d --- /dev/null +++ b/lua/plugins.lua @@ -0,0 +1,45 @@ +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 + packer_bootstrap = fn.system({'git', 'clone', '--depth', '1', 'https://github.com/wbthomason/packer.nvim', install_path}) +end + +local plugins = require('packer').startup(function(use) + use 'wbthomason/packer.nvim' + use 'gruvbox-community/gruvbox' + + -- file management + use { + 'nvim-telescope/telescope.nvim', -- search and select tool + requires = { {'nvim-lua/plenary.nvim'} } + } + + -- git + use 'tpope/vim-fugitive' + + -- LSP + use 'neovim/nvim-lspconfig' -- Common lsp server configurations + use 'tjdevries/lsp_extensions.nvim' -- Provides type inlay hint support + use 'hrsh7th/cmp-nvim-lsp' -- Completion LSP integeration + use 'hrsh7th/cmp-buffer' + use 'hrsh7th/cmp-path' + use 'hrsh7th/cmp-cmdline' + use 'hrsh7th/nvim-cmp' -- Autocompletion + + -- Snippets (Required for nvim-cmp) + use 'hrsh7th/cmp-vsnip' + use 'hrsh7th/vim-vsnip' + + -- Language Specfic + use 'rust-lang/rust.vim' + + if packer_bootstrap then + require('packer').sync() + end +end) + +-- Required for rust.vim +-- TODO: Convert to lua +vim.cmd([[filetype plugin indent on]]) + +return plugins