--- /dev/null
+--
+-- “This is the editor of a Real Coder.
+-- Not as clumsy as a full blown IDE.
+-- An elegant editor for a more civilized age.”
+-- ― Bernie Innocenti, https://codewiz.org
+--
+
+-- Set this to replace GitHub default URLs
+-- local github_url = 'https://github.com/'
+local github_url = 'git@github.com:'
+
+-- Bootstrap Packer if not already installed
+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
+ local packer_url = github_url .. "wbthomason/packer.nvim"
+ print("Bootstrapping packer from ", packer_url)
+ packer_bootstrap = fn.system({'git', 'clone', '--depth', '1', packer_url, install_path})
+end
+
+require('packer').startup({function(use)
+ use 'wbthomason/packer.nvim'
+ use { 'nvim-treesitter/nvim-treesitter',
+ run = function() require('nvim-treesitter.install').update({ with_sync = true }) end, }
+ use { 'nvim-telescope/telescope.nvim', requires = { {'nvim-lua/plenary.nvim'} } }
+ use { 'nvim-lualine/lualine.nvim', requires = { 'kyazdani42/nvim-web-devicons', opt = true } }
+ use { 'kyazdani42/nvim-tree.lua', requires = { 'kyazdani42/nvim-web-devicons', }, tag = 'nightly' }
+ use 'dstein64/nvim-scrollview'
+
+ use 'neovim/nvim-lspconfig'
+ use 'hrsh7th/cmp-nvim-lsp'
+ use 'hrsh7th/cmp-buffer'
+ use 'hrsh7th/cmp-path'
+ use 'hrsh7th/cmp-cmdline'
+ use 'hrsh7th/nvim-cmp'
+ use 'hrsh7th/cmp-vsnip'
+ use 'hrsh7th/vim-vsnip'
+ -- use 'hrsh7th/cmp-nvim-lsp-signature-help'
+ use "ray-x/lsp_signature.nvim"
+
+ if packer_bootstrap then
+ -- FIXME: this runs asynchronously, causing the rest of the
+ -- lua script to fail on first run
+ require('packer').sync()
+ end
+end,
+config = {
+ git = { default_url_format = github_url .. '%s.git' }
+}})
+
+-- nvim-treesitter --
+
+if github_url ~= nil then
+ -- Replace GitHub url for all treesitter plugins
+ for _, config in pairs(require("nvim-treesitter.parsers").get_parser_configs()) do
+ config.install_info.url = config.install_info.url:gsub("https://github.com/", github_url)
+ end
+end
+
+require("nvim-treesitter.install").prefer_git = true
+require("nvim-treesitter.configs").setup {
+ highlight = {
+ enable = true,
+ },
+}
+
+local opts = { noremap=true, silent=true }
+local map = vim.api.nvim_set_keymap
+
+require("telescope").setup()
+map('n', '<C-p>', '<cmd>Telescope git_files<cr>', opts)
+map('n', 'ff', '<cmd>Telescope find_files<cr>', opts)
+map('n', 'fg', '<cmd>Telescope live_grep<cr>', opts)
+map('n', 'fb', '<cmd>Telescope buffers<cr>', opts)
+map('n', 'fh', '<cmd>Telescope help_tags<cr>', opts)
+
+require("nvim-tree").setup()
+map('n', 'o', ':NvimTreeFocus<CR>', opts)
+map('n', '<S-o>', ':NvimTreeClose<CR>', opts)
+map('n', '<C-o>', ':NvimTreeFindFile<CR>', opts)
+
+require('lualine').setup {
+ options = {
+ theme = 'codedark',
+ section_separators = { left = '', right = '' },
+ component_separators = { left = '', right = '' },
+ -- section_separators = '', component_separators = '',
+ show_filename_only = false,
+ globalstatus = false,
+ },
+ sections = {
+ lualine_a = {
+ { 'mode', fmt = function(str) return str:sub(1,1) end }
+ },
+ lualine_b = {
+ { 'branch', fmt = function(branch) return branch == 'master' and '' or branch end },
+ },
+ lualine_c = {
+ { 'filename', path = 1, },
+ },
+ lualine_x = {
+ { 'filetype', icon_only = true, },
+ },
+ lualine_y = {},
+ },
+}
+
+-- nvim-cmp --
+
+local kind_icons = {
+ Text = "",
+ Method = "",
+ Function = "",
+ Constructor = "",
+ Field = "",
+ Variable = "",
+ Class = "ﴯ",
+ Interface = "",
+ Module = "",
+ Property = "ﰠ",
+ Unit = "",
+ Value = "",
+ Enum = "",
+ Keyword = "",
+ Snippet = "",
+ Color = "",
+ File = "",
+ Reference = "",
+ Folder = "",
+ EnumMember = "",
+ Constant = "",
+ Struct = "",
+ Event = "",
+ Operator = "",
+ TypeParameter = ""
+}
+
+local has_words_before = function()
+ local line, col = unpack(vim.api.nvim_win_get_cursor(0))
+ return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil
+end
+
+local feedkey = function(key, mode)
+ vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true)
+end
+
+local cmp = require'cmp'
+cmp.setup({
+ -- view = { entries = "native" },
+ formatting = {
+ fields = {
+ "kind",
+ "abbr",
+ "menu",
+ },
+ format = function(entry, vim_item)
+ vim_item.kind = kind_icons[vim_item.kind]
+ local max_width = 25
+ if vim_item.menu ~= nil and string.len(vim_item.menu) > max_width then
+ vim_item.menu = string.sub(vim_item.menu, 1, max_width - 1) .. "…"
+ end
+ return vim_item
+ end,
+ },
+ snippet = {
+ -- REQUIRED - you must specify a snippet engine
+ expand = function(args)
+ vim.fn["vsnip#anonymous"](args.body) -- For `vsnip` users.
+ end,
+ },
+ mapping = cmp.mapping.preset.insert({
+ ['<C-b>'] = cmp.mapping(cmp.mapping.scroll_docs(-4), { 'i', 'c' }),
+ ['<C-f>'] = cmp.mapping(cmp.mapping.scroll_docs(4), { 'i', 'c' }),
+ ['<C-Space>'] = cmp.mapping(cmp.mapping.complete(), { 'i', 'c' }),
+ ['<C-y>'] = cmp.config.disable, -- Specify `cmp.config.disable` if you want to remove the default `<C-y>` mapping.
+ ['<C-e>'] = cmp.mapping({
+ i = cmp.mapping.abort(),
+ c = cmp.mapping.close(),
+ }),
+ ['<CR>'] = cmp.mapping.confirm({ select = true }),
+
+ ["<Tab>"] = cmp.mapping(function(fallback)
+ if cmp.visible() then
+ cmp.select_next_item()
+ elseif vim.fn["vsnip#available"](1) == 1 then
+ feedkey("<Plug>(vsnip-expand-or-jump)", "")
+ elseif has_words_before() then
+ cmp.complete()
+ else
+ fallback() -- Sends a already mapped key. In this case, it's probably `<Tab>`.
+ end
+ end, { "i", "s" }),
+
+ ["<S-Tab>"] = cmp.mapping(function()
+ if cmp.visible() then
+ cmp.select_prev_item()
+ elseif vim.fn["vsnip#jumpable"](-1) == 1 then
+ feedkey("<Plug>(vsnip-jump-prev)", "")
+ end
+ end, { "i", "s" }),
+ }),
+ sources = cmp.config.sources({
+ { name = 'nvim_lsp' },
+ -- { name = 'nvim_lsp_signature_help', },
+ }, {
+ { name = 'vsnip' },
+ -- { name = 'buffer' },
+ })
+})
+
+-- cmp.setup.cmdline('/', {
+-- mapping = cmp.mapping.preset.cmdline(),
+-- completion = {
+-- keyword_length = 2,
+-- },
+-- sources = {
+-- { name = 'buffer' }
+-- }
+--})
+
+cmp.setup.cmdline(':', {
+ mapping = cmp.mapping.preset.cmdline(),
+ completion = {
+ keyword_length = 2,
+ },
+ sources = cmp.config.sources({
+ { name = 'path' }
+ }, {
+ { name = 'cmdline' }
+ })
+})
+
+
+local capabilities = vim.lsp.protocol.make_client_capabilities()
+capabilities = require('cmp_nvim_lsp').update_capabilities(capabilities)
+
+-- Disable snippets support for rust-analyzer because it spams the completion
+capabilities.textDocument.completion.completionItem.snippetSupport = false
+-- print(vim.inspect(capabilities))
+
+-- lsp-config --
+
+-- vim.lsp.set_log_level("debug")
+vim.diagnostic.config({
+ underline = true,
+ virtual_text = false,
+ update_in_insert = false,
+ float = {
+ focusable = false,
+ style = 'minimal',
+ border = 'rounded',
+ source = 'always',
+ header = '',
+ prefix = '',
+ }
+})
+
+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
+
+ buf_set_option("formatexpr", "v:lua.vim.lsp.formatexpr()")
+ buf_set_option("omnifunc", "v:lua.vim.lsp.omnifunc")
+ buf_set_option("tagfunc", "v:lua.vim.lsp.tagfunc")
+
+ vim.opt.completeopt = {"menu", "menuone", "noinsert"}
+
+ require "lsp_signature".on_attach({
+ hi_parameter = "IncSearch"
+ })
+
+ local opts = { noremap=true, silent=true }
+ -- See `:help vim.lsp.*` for documentation on any of the below functions
+ buf_set_keymap('n', 'gD', '<Cmd>lua vim.lsp.buf.declaration()<CR>', opts)
+ buf_set_keymap('n', '<C-]>', '<Cmd>lua vim.lsp.buf.declaration()<CR>', opts)
+ buf_set_keymap('n', 'gd', '<Cmd>lua vim.lsp.buf.definition()<CR>', opts)
+ buf_set_keymap('n', 'K', '<Cmd>lua vim.lsp.buf.hover()<CR>', opts)
+ buf_set_keymap('n', 'gi', '<cmd>lua vim.lsp.buf.implementation()<CR>', opts)
+ buf_set_keymap('n', '<C-k>', '<cmd>lua vim.lsp.buf.signature_help()<CR>', opts)
+ buf_set_keymap('n', '<space>wa', '<cmd>lua vim.lsp.buf.add_workspace_folder()<CR>', opts)
+ buf_set_keymap('n', '<space>wr', '<cmd>lua vim.lsp.buf.remove_workspace_folder()<CR>', opts)
+ buf_set_keymap('n', '<space>wl', '<cmd>lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))<CR>', opts)
+ buf_set_keymap('n', '<space>D', '<cmd>lua vim.lsp.buf.type_definition()<CR>', opts)
+ buf_set_keymap('n', '<space>rn', '<cmd>lua vim.lsp.buf.rename()<CR>', opts)
+ buf_set_keymap('n', '<space>ca', '<cmd>lua vim.lsp.buf.code_action()<CR>', opts)
+ buf_set_keymap('n', 'gr', '<cmd>lua vim.lsp.buf.references()<CR>', opts)
+
+ buf_set_keymap('n', '<space>e', '<cmd>lua vim.diagnostic.open_float()<CR>', opts)
+ buf_set_keymap('n', '<space>q', '<cmd>lua vim.diagnostic.setloclist()<CR>', opts)
+ buf_set_keymap('n', '[d', '<cmd>lua vim.diagnostic.goto_prev()<CR>', opts)
+ buf_set_keymap('n', ']d', '<cmd>lua vim.diagnostic.goto_next()<CR>', opts)
+
+ buf_set_keymap('n', "=", "<cmd>lua vim.lsp.buf.formatting()<CR>", opts)
+ buf_set_keymap('v', "=", "<cmd>lua vim.lsp.buf.formatting()<CR>", opts)
+ buf_set_keymap('n', "gq", "<cmd>lua vim.lsp.buf.formatting()<CR>", opts)
+ buf_set_keymap('v', "gq", "<cmd>lua vim.lsp.buf.formatting()<CR>", opts)
+end
+
+local lspconfig = require'lspconfig';
+lspconfig.rust_analyzer.setup{
+ on_attach = on_attach,
+ capabilities = capabilities,
+}
+lspconfig.tsserver.setup{
+ on_attach = on_attach,
+ capabilities = capabilities,
+}
+lspconfig.clangd.setup{
+ on_attach = on_attach,
+ capabilities = capabilities,
+ -- cmd = { vim.loop.os_homedir() .. "clangd", "--background-index" },
+ cmd = { "clangd", "--background-index" },
+ root_dir = lspconfig.util.root_pattern("compile_commands.json", "compile_flags.txt"),
+}
+lspconfig.pylsp.setup{
+ on_attach = on_attach,
+ capabilities = capabilities,
+ settings = {
+ pylsp = {
+ configurationSources = {"pylint"},
+ plugins = {
+ autopep8 = { enabled = true },
+ mypy = { enabled = true },
+ pylint = { enabled = true },
+ flake8 = { enabled = false },
+ pycodestyle = { enabled = false },
+ pyflakes = { enabled = false },
+ }
+ }
+ }
+}
+
+-- Alt-key window navication and more
+map('t', '<A-h>', '<C-\\><C-n>h', opts)
+map('t', '<A-j>', '<C-\\><C-n>j', opts)
+map('t', '<A-k>', '<C-\\><C-n>k', opts)
+map('t', '<A-l>', '<C-\\><C-n>l', opts)
+map('i', '<A-h>', '<C-\\><C-n>h', opts)
+map('i', '<A-j>', '<C-\\><C-n>j', opts)
+map('i', '<A-k>', '<C-\\><C-n>k', opts)
+map('i', '<A-l>', '<C-\\><C-n>l', opts)
+map('n', '<A-h>', '<C-w>h', opts)
+map('n', '<A-j>', '<C-w>j', opts)
+map('n', '<A-k>', '<C-w>k', opts)
+map('n', '<A-l>', '<C-w>l', opts)
+