diff --git a/config/nvim/.config/nvim/init.lua b/config/nvim/.config/nvim/init.lua new file mode 100644 index 0000000..5ebfd7d --- /dev/null +++ b/config/nvim/.config/nvim/init.lua @@ -0,0 +1,8 @@ +-- init.lua -- + +require('core.options') +require('core.plugins') +require('core.keymaps') + +require('plugin-config') + diff --git a/config/nvim/.config/nvim/lua/.luarc.json b/config/nvim/.config/nvim/lua/.luarc.json new file mode 100644 index 0000000..0942186 --- /dev/null +++ b/config/nvim/.config/nvim/lua/.luarc.json @@ -0,0 +1,34 @@ +{ + "$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json", + "Lua.workspace.library": [ + "/Users/james/.config/nvim", + "/Users/james/.local/share/nvim/site", + "/Users/james/.local/share/nvim/site/pack/packer/start/cmp-nvim-lsp", + "/Users/james/.local/share/nvim/site/pack/packer/start/cmp_luasnip", + "/Users/james/.local/share/nvim/site/pack/packer/start/fidget.nvim", + "/Users/james/.local/share/nvim/site/pack/packer/start/fzf", + "/Users/james/.local/share/nvim/site/pack/packer/start/fzf.vim", + "/Users/james/.local/share/nvim/site/pack/packer/start/jellybeans.vim", + "/Users/james/.local/share/nvim/site/pack/packer/start/LuaSnip", + "/Users/james/.local/share/nvim/site/pack/packer/start/mason-lspconfig.nvim", + "/Users/james/.local/share/nvim/site/pack/packer/start/mason.nvim", + "/Users/james/.local/share/nvim/site/pack/packer/start/nvim-cmp", + "/Users/james/.local/share/nvim/site/pack/packer/start/nvim-lspconfig", + "/Users/james/.local/share/nvim/site/pack/packer/start/nvim-treesitter", + "/Users/james/.local/share/nvim/site/pack/packer/start/packer.nvim", + "/Users/james/.local/share/nvim/site/pack/packer/start/vim-commentary", + "/Users/james/.local/share/nvim/site/pack/packer/start/vim-eunuch", + "/Users/james/.local/share/nvim/site/pack/packer/start/vim-fugitive", + "/Users/james/.local/share/nvim/site/pack/packer/start/vim-gitgutter", + "/Users/james/.local/share/nvim/site/pack/packer/start/vim-repeat", + "/Users/james/.local/share/nvim/site/pack/packer/start/vim-rhubarb", + "/Users/james/.local/share/nvim/site/pack/packer/start/vim-rsi", + "/Users/james/.local/share/nvim/site/pack/packer/start/vim-surround", + "/Users/james/.local/share/nvim/site/pack/packer/start/vim-unimpaired", + "/opt/homebrew/Cellar/neovim/0.8.1/share/nvim/runtime", + "/opt/homebrew/Cellar/neovim/0.8.1/lib/nvim", + "/Users/james/.local/share/nvim/site/pack/packer/start/cmp-nvim-lsp/after", + "/Users/james/.local/share/nvim/site/pack/packer/start/cmp_luasnip/after", + "${3rd}/luassert/library" + ] +} diff --git a/config/nvim/.config/nvim/lua/core/keymaps.lua b/config/nvim/.config/nvim/lua/core/keymaps.lua new file mode 100644 index 0000000..c74ef7b --- /dev/null +++ b/config/nvim/.config/nvim/lua/core/keymaps.lua @@ -0,0 +1,30 @@ +-- +-- keymaps +-- + +vim.g.mapleader = ' ' + +-- paste and search +vim.keymap.set('n', '', ':noh :let @/ = ""') +vim.keymap.set('n', 'i', ':set invpaste') + +-- dates +vim.keymap.set('n', 'ts', '"=strftime("%F %T%z")') +vim.keymap.set('n', 'dt', ':r !date') + +-- rc files +vim.keymap.set('n', 'rc', ':vsplit $MYVIMRC') +vim.keymap.set('n', 'so', ':source $MYVIMRC') +vim.keymap.set('n', 'rcl', ':vsplit ~/.config/nvim/lua/') + +-- windows +vim.keymap.set('n', 'cl', ':close') + +-- formatting tools +vim.keymap.set('n', '=j', ':%!python -m json.tool') + +-- vim-plug +vim.keymap.set('n', 'ps', ':source $MYVIMRC :PackerSync') +vim.keymap.set('n', 'pi', ':source $MYVIMRC :PackerInstall') +vim.keymap.set('n', 'pu', ':source $MYVIMRC :PackerUpdate') +vim.keymap.set('n', 'pc', ':source $MYVIMRC :PackerClean') diff --git a/config/nvim/.config/nvim/lua/core/options.lua b/config/nvim/.config/nvim/lua/core/options.lua new file mode 100644 index 0000000..e8271df --- /dev/null +++ b/config/nvim/.config/nvim/lua/core/options.lua @@ -0,0 +1,54 @@ +-- +-- general settings +-- + +-- encoding/format +vim.opt.encoding = 'utf-8' +vim.opt.fileformats = 'unix,dos,mac' + +-- status bar +vim.opt.wildmenu = true +vim.opt.showcmd = true +vim.opt.showmatch = true +vim.opt.laststatus = 2 + +-- search +vim.opt.hlsearch = true +vim.opt.incsearch = true +vim.opt.ignorecase = true +vim.opt.smartcase = true + +-- indent +vim.opt.autoindent = true +vim.opt.expandtab = true +vim.opt.shiftwidth = 2 +vim.opt.tabstop = 2 +vim.opt.softtabstop = 2 + +-- buffer behaviour +vim.opt.autoread = true +vim.opt.autowrite = true +vim.opt.confirm = true + +-- cursor +vim.opt.virtualedit = 'block' +vim.opt.backspace = 'indent,eol,start' +vim.opt.scrolloff = 2 +vim.opt.sidescrolloff = 4 + +-- window behaviour (ltr) +vim.opt.splitbelow = true +vim.opt.splitright = true + +-- display +vim.opt.background = "dark" +vim.opt.termguicolors = true +vim.opt.number = true +vim.opt.wrap = true +vim.opt.listchars = {eol = '↲', tab = '▸ ', trail = '·'} + +-- vim cmds +vim.cmd [[ + syntax enable + filetype plugin indent on +]] diff --git a/config/nvim/.config/nvim/lua/core/plugins.lua b/config/nvim/.config/nvim/lua/core/plugins.lua new file mode 100644 index 0000000..7484ea3 --- /dev/null +++ b/config/nvim/.config/nvim/lua/core/plugins.lua @@ -0,0 +1,97 @@ +-- +-- plugins +-- + +local install_path = vim.fn.stdpath 'data' .. '/site/pack/packer/start/packer.nvim' +if vim.fn.empty(vim.fn.glob(install_path)) > 0 then + vim.fn.execute('!git clone https://github.com/wbthomason/packer.nvim ' .. install_path) + vim.cmd [[packadd packer.nvim]] +end + +require('packer').startup(function(use) + use 'wbthomason/packer.nvim' + use { -- LSP Configuration & Plugins + 'neovim/nvim-lspconfig', + requires = { + 'williamboman/mason.nvim', + 'williamboman/mason-lspconfig.nvim', + 'j-hui/fidget.nvim', + }, + } + use { -- Autocompletion + 'hrsh7th/nvim-cmp', + requires = { 'hrsh7th/cmp-nvim-lsp', 'L3MON4D3/LuaSnip', 'saadparwaiz1/cmp_luasnip' }, + } + use { -- Highlight, edit, and navigate code + 'nvim-treesitter/nvim-treesitter', + run = function() + pcall(require('nvim-treesitter.install').update { with_sync = true }) + end, + } + + -- normal mode keybinds + use 'tpope/vim-commentary' + use 'tpope/vim-surround' + use 'tpope/vim-unimpaired' + -- command mode keybinds + use 'tpope/vim-rsi' + use 'tpope/vim-eunuch' + use 'tpope/vim-repeat' + + -- git + use 'tpope/vim-fugitive' + use 'tpope/vim-rhubarb' + use 'airblade/vim-gitgutter' + + use { 'junegunn/fzf', run = ":call fzf#install()" } + use { 'junegunn/fzf.vim' } + + -- colorschemes + use 'nanotech/jellybeans.vim' + use({ + 'rose-pine/neovim', + as = 'rose-pine', + config = function() + vim.cmd('colorscheme rose-pine') + end + }) +end) + +-- vim.cmd [[ +-- let autoload_plug_path = stdpath('data') . '/site/autoload/plug.vim' +-- if !filereadable(autoload_plug_path) +-- silent execute '!curl -fLo ' . autoload_plug_path . ' --create-dirs +-- \ "https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim"' +-- autocmd VimEnter * PlugInstall --sync | source $MYVIMRC +-- endif +-- unlet autoload_plug_path +-- ]] +-- local Plug = vim.fn['plug#'] +-- vim.call('plug#begin', '~/.config/nvim/plugged') +-- -- plug +-- Plug 'junegunn/vim-plug' + +-- -- normal mode keybinds +-- Plug 'tpope/vim-commentary' +-- Plug 'tpope/vim-surround' +-- Plug 'tpope/vim-unimpaired' +-- -- command mode keybinds +-- Plug 'tpope/vim-rsi' +-- Plug 'tpope/vim-eunuch' +-- Plug 'tpope/vim-repeat' + +-- -- external tools +-- -- git +-- Plug 'tpope/vim-fugitive' +-- Plug 'tpope/vim-rhubarb' +-- Plug 'tpope/vim-dispatch' +-- Plug 'airblade/vim-gitgutter' + +-- -- fzf +-- Plug 'junegunn/fzf' +-- Plug 'junegunn/fzf.vim' + +-- -- colors +-- Plug 'flazz/vim-colorschemes' +-- vim.call('plug#end') + diff --git a/config/nvim/.config/nvim/lua/plugin-config/cmp.lua b/config/nvim/.config/nvim/lua/plugin-config/cmp.lua new file mode 100644 index 0000000..1a4b662 --- /dev/null +++ b/config/nvim/.config/nvim/lua/plugin-config/cmp.lua @@ -0,0 +1,42 @@ +-- nvim-cmp setup +local cmp = require 'cmp' +local luasnip = require 'luasnip' + +cmp.setup { + snippet = { + expand = function(args) + luasnip.lsp_expand(args.body) + end, + }, + mapping = cmp.mapping.preset.insert { + [''] = cmp.mapping.scroll_docs(-4), + [''] = cmp.mapping.scroll_docs(4), + [''] = cmp.mapping.complete(), + [''] = cmp.mapping.confirm { + behavior = cmp.ConfirmBehavior.Replace, + select = true, + }, + [''] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item() + elseif luasnip.expand_or_jumpable() then + luasnip.expand_or_jump() + else + fallback() + end + end, { 'i', 's' }), + [''] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + elseif luasnip.jumpable(-1) then + luasnip.jump(-1) + else + fallback() + end + end, { 'i', 's' }), + }, + sources = { + { name = 'nvim_lsp' }, + { name = 'luasnip' }, + }, +} diff --git a/config/nvim/.config/nvim/lua/plugin-config/init.lua b/config/nvim/.config/nvim/lua/plugin-config/init.lua new file mode 100644 index 0000000..23689e6 --- /dev/null +++ b/config/nvim/.config/nvim/lua/plugin-config/init.lua @@ -0,0 +1,7 @@ +require('plugin-config.nvim-treesitter') +require('plugin-config.lsp') +require('plugin-config.cmp') + +-- plugin keybinds +require('plugin-config.keybinds.vim-fugitive') +require('plugin-config.keybinds.fzf') diff --git a/config/nvim/.config/nvim/lua/plugin-config/keybinds/fzf.lua b/config/nvim/.config/nvim/lua/plugin-config/keybinds/fzf.lua new file mode 100644 index 0000000..e976267 --- /dev/null +++ b/config/nvim/.config/nvim/lua/plugin-config/keybinds/fzf.lua @@ -0,0 +1,8 @@ +-- fzf +vim.keymap.set('n', 'f', ':GitFiles') +vim.keymap.set('n', 'F', ':Files') +vim.keymap.set('n', 'c', ':Commands') +vim.keymap.set('n', 'b', ':Buffers') +vim.keymap.set('n', 'h', ':Helptags') +vim.keymap.set('n', 'm', ':Maps') +vim.keymap.set('n', 'rg', ':Rg') diff --git a/config/nvim/.config/nvim/lua/plugin-config/keybinds/vim-fugitive.lua b/config/nvim/.config/nvim/lua/plugin-config/keybinds/vim-fugitive.lua new file mode 100644 index 0000000..27df195 --- /dev/null +++ b/config/nvim/.config/nvim/lua/plugin-config/keybinds/vim-fugitive.lua @@ -0,0 +1,9 @@ +-- vim-fugitive +vim.keymap.set('n', 'gw' ,':Gwrite') +vim.keymap.set('n', 'gl' ,':Glog') +vim.keymap.set('n', 'gs' ,':Git') +vim.keymap.set('n', 'gd' ,':Gdiffsplit') +vim.keymap.set('n', 'gp' ,':Gpush') +vim.keymap.set('n', 'ga' ,':Git add %') +vim.keymap.set('n', 'ga.' ,':Git add .') +vim.keymap.set('n', 'gc' ,':Git commit') diff --git a/config/nvim/.config/nvim/lua/plugin-config/lsp.lua b/config/nvim/.config/nvim/lua/plugin-config/lsp.lua new file mode 100644 index 0000000..983714f --- /dev/null +++ b/config/nvim/.config/nvim/lua/plugin-config/lsp.lua @@ -0,0 +1,109 @@ +-- Diagnostic keymaps +vim.keymap.set('n', '[d', vim.diagnostic.goto_prev) +vim.keymap.set('n', ']d', vim.diagnostic.goto_next) +vim.keymap.set('n', 'e', vim.diagnostic.open_float) +vim.keymap.set('n', 'q', vim.diagnostic.setloclist) + +-- LSP settings. +-- This function gets run when an LSP connects to a particular buffer. +local on_attach = function(_, bufnr) + -- NOTE: Remember that lua is a real programming language, and as such it is possible + -- to define small helper and utility functions so you don't have to repeat yourself + -- many times. + -- + -- In this case, we create a function that lets us more easily define mappings specific + -- for LSP related items. It sets the mode, buffer and description for us each time. + local nmap = function(keys, func, desc) + if desc then + desc = 'LSP: ' .. desc + end + + vim.keymap.set('n', keys, func, { buffer = bufnr, desc = desc }) + end + + nmap('rn', vim.lsp.buf.rename, '[R]e[n]ame') + nmap('ca', vim.lsp.buf.code_action, '[C]ode [A]ction') + + nmap('gd', vim.lsp.buf.definition, '[G]oto [D]efinition') + -- nmap('gr', require('telescope.builtin').lsp_references, '[G]oto [R]eferences') + nmap('gI', vim.lsp.buf.implementation, '[G]oto [I]mplementation') + nmap('D', vim.lsp.buf.type_definition, 'Type [D]efinition') + -- nmap('ds', require('telescope.builtin').lsp_document_symbols, '[D]ocument [S]ymbols') + -- nmap('ws', require('telescope.builtin').lsp_dynamic_workspace_symbols, '[W]orkspace [S]ymbols') + + -- See `:help K` for why this keymap + nmap('K', vim.lsp.buf.hover, 'Hover Documentation') + nmap('', vim.lsp.buf.signature_help, 'Signature Documentation') + + -- Lesser used LSP functionality + nmap('gD', vim.lsp.buf.declaration, '[G]oto [D]eclaration') + nmap('wa', vim.lsp.buf.add_workspace_folder, '[W]orkspace [A]dd Folder') + nmap('wr', vim.lsp.buf.remove_workspace_folder, '[W]orkspace [R]emove Folder') + nmap('wl', function() + print(vim.inspect(vim.lsp.buf.list_workspace_folders())) + end, '[W]orkspace [L]ist Folders') + + -- Create a command `:Format` local to the LSP buffer + vim.api.nvim_buf_create_user_command(bufnr, 'Format', function(_) + if vim.lsp.buf.format then + vim.lsp.buf.format() + elseif vim.lsp.buf.formatting then + vim.lsp.buf.formatting() + end + end, { desc = 'Format current buffer with LSP' }) +end + +-- Setup mason so it can manage external tooling +require('mason').setup() + +-- Enable the following language servers +-- Feel free to add/remove any LSPs that you want here. They will automatically be installed +local servers = { 'clangd', 'rust_analyzer', 'pyright', 'tsserver', 'sumneko_lua', 'gopls' } + +-- Ensure the servers above are installed +require('mason-lspconfig').setup { + ensure_installed = servers, +} + +-- nvim-cmp supports additional completion capabilities +local capabilities = vim.lsp.protocol.make_client_capabilities() +capabilities = require('cmp_nvim_lsp').default_capabilities(capabilities) + +for _, lsp in ipairs(servers) do + require('lspconfig')[lsp].setup { + on_attach = on_attach, + capabilities = capabilities, + } +end + +-- Turn on lsp status information +require('fidget').setup() + +-- Example custom configuration for lua +-- +-- Make runtime files discoverable to the server +local runtime_path = vim.split(package.path, ';') +table.insert(runtime_path, 'lua/?.lua') +table.insert(runtime_path, 'lua/?/init.lua') + +require('lspconfig').sumneko_lua.setup { + on_attach = on_attach, + capabilities = capabilities, + settings = { + Lua = { + runtime = { + -- Tell the language server which version of Lua you're using (most likely LuaJIT) + version = 'LuaJIT', + -- Setup your lua path + path = runtime_path, + }, + diagnostics = { + globals = { 'vim' }, + }, + workspace = { library = vim.api.nvim_get_runtime_file('', true) }, + -- Do not send telemetry data containing a randomized but unique identifier + telemetry = { enable = false }, + }, + }, +} + diff --git a/config/nvim/.config/nvim/lua/plugin-config/nvim-treesitter.lua b/config/nvim/.config/nvim/lua/plugin-config/nvim-treesitter.lua new file mode 100644 index 0000000..2e338e2 --- /dev/null +++ b/config/nvim/.config/nvim/lua/plugin-config/nvim-treesitter.lua @@ -0,0 +1,62 @@ +-- [[ Configure Treesitter ]] +-- See `:help nvim-treesitter` +require('nvim-treesitter.configs').setup { + -- Add languages to be installed here that you want installed for treesitter + ensure_installed = { 'c', 'cpp', 'go', 'lua', 'python', 'rust', 'typescript', 'help' }, + + highlight = { enable = true }, + indent = { enable = true }, + incremental_selection = { + enable = true, + keymaps = { + init_selection = '', + node_incremental = '', + scope_incremental = '', + node_decremental = '', + }, + }, + textobjects = { + select = { + enable = true, + lookahead = true, -- Automatically jump forward to textobj, similar to targets.vim + keymaps = { + -- You can use the capture groups defined in textobjects.scm + ['aa'] = '@parameter.outer', + ['ia'] = '@parameter.inner', + ['af'] = '@function.outer', + ['if'] = '@function.inner', + ['ac'] = '@class.outer', + ['ic'] = '@class.inner', + }, + }, + move = { + enable = true, + set_jumps = true, -- whether to set jumps in the jumplist + goto_next_start = { + [']m'] = '@function.outer', + [']]'] = '@class.outer', + }, + goto_next_end = { + [']M'] = '@function.outer', + [']['] = '@class.outer', + }, + goto_previous_start = { + ['[m'] = '@function.outer', + ['[['] = '@class.outer', + }, + goto_previous_end = { + ['[M'] = '@function.outer', + ['[]'] = '@class.outer', + }, + }, + swap = { + enable = true, + swap_next = { + ['a'] = '@parameter.inner', + }, + swap_previous = { + ['A'] = '@parameter.inner', + }, + }, + }, +}