diff --git a/dotfiles/neovim/init.lua b/dotfiles/neovim/init.lua
index 1c17e62..4838477 100644
--- a/dotfiles/neovim/init.lua
+++ b/dotfiles/neovim/init.lua
@@ -26,6 +26,8 @@ opt.splitright = true -- Put new windows right of current
 opt.wrap = false -- Disable line wrap
 opt.wildmode = {'list', 'longest'} -- Command-line completion mode
 
+opt.completeopt = {"menu", "menuone", "noselect"}
+
 -- Set theme
 require('github-theme').setup({theme_style = "light", dark_float = true})
 
diff --git a/dotfiles/neovim/lua/my/plugins/cmp.lua b/dotfiles/neovim/lua/my/plugins/cmp.lua
index 985d0dc..07d322e 100644
--- a/dotfiles/neovim/lua/my/plugins/cmp.lua
+++ b/dotfiles/neovim/lua/my/plugins/cmp.lua
@@ -1,19 +1,47 @@
 local M = {}
 
+local function has_words_before ()
+    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
+
 function M.setup()
     local cmp = require("cmp")
-
-    cmp.setup({
+    local lspkind = require('lspkind')
+    local options = {
+        formatting = {format = lspkind.cmp_format()},
         mapping = {
             ['<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-Space>'] = cmp.mapping(cmp.mapping.complete(), {'i', 'c'}),
             ['<C-y>'] = cmp.config.disable,
             ['<C-e>'] = cmp.mapping({i = cmp.mapping.abort(), c = cmp.mapping.close()}),
-            ['<CR>'] = cmp.mapping.confirm({select = true})
+            ['<CR>'] = cmp.mapping.confirm({select = true}),
+	    -- https://github.com/hrsh7th/nvim-cmp/wiki/Example-mappings
+            ['<C-Space>'] = cmp.mapping.confirm {behavior = cmp.ConfirmBehavior.Insert, select = true},
+            ['<Tab>'] = function(fallback)
+                if not cmp.select_next_item() then
+                    if vim.bo.buftype ~= 'prompt' and has_words_before() then
+                        cmp.complete()
+                    else
+                        fallback()
+                    end
+                end
+            end,
+            ['<S-Tab>'] = function(fallback)
+                if not cmp.select_prev_item() then
+                    if vim.bo.buftype ~= 'prompt' and has_words_before() then
+                        cmp.complete()
+                    else
+                        fallback()
+                    end
+                end
+            end,
         },
-        sources = cmp.config.sources({}, {{name = 'buffer'}})
-    })
+        sources = cmp.config.sources({{name = 'nvim_lsp'}}, {{name = 'buffer'}})
+    }
+
+    cmp.setup(options)
 
     -- Use buffer source for `/` (if you enabled `native_menu`, this won't work anymore).
     cmp.setup.cmdline('/', {sources = {{name = 'buffer'}}})
diff --git a/dotfiles/neovim/lua/my/plugins/init.lua b/dotfiles/neovim/lua/my/plugins/init.lua
index 90e6eb8..68655d4 100644
--- a/dotfiles/neovim/lua/my/plugins/init.lua
+++ b/dotfiles/neovim/lua/my/plugins/init.lua
@@ -4,12 +4,12 @@ function M.setup()
     -- Other unconfigured plugins
     require('nvim-autopairs').setup()
     require("startup").setup({theme = "dashboard"})
-    require('lualine').setup({theme = "github"})
 
     -- Plugins with their own configs:
     require("my.plugins.cmp").setup()
     require("my.plugins.lspconfig").setup()
     require("my.plugins.null-ls").setup()
+    require("my.plugins.lualine").setup()
     -- require("my.plugins.fzf-lua").setup()
     require("my.plugins.treesitter").setup()
     require("my.plugins.comment").setup()
diff --git a/dotfiles/neovim/lua/my/plugins/lspconfig.lua b/dotfiles/neovim/lua/my/plugins/lspconfig.lua
index ed858d4..51183fc 100644
--- a/dotfiles/neovim/lua/my/plugins/lspconfig.lua
+++ b/dotfiles/neovim/lua/my/plugins/lspconfig.lua
@@ -31,7 +31,7 @@ local function on_attach(client, bufnr)
     -- Code actions
     map(bufnr, 'n', '<space>D', '<cmd>lua vim.lsp.buf.type_definition()<CR>')
     map(bufnr, 'n', '<space>rn', '<cmd>lua vim.lsp.buf.rename()<CR>')
-    map(bufnr, 'n', '<space>ca', '<cmd>lua vim.lsp.buf.code_action()<CR>')
+    -- map(bufnr, 'n', '<space>ca', '<cmd>lua vim.lsp.buf.code_action()<CR>')
     map(bufnr, 'n', 'gr', '<cmd>lua vim.lsp.buf.references()<CR>')
     map(bufnr, 'n', '<space>f', '<cmd>lua vim.lsp.buf.formatting()<CR>')
 end
@@ -106,7 +106,7 @@ function M.setup()
     local autoFormatOn = {lua = 200, purs = 1000, nix = 200, ts = 200, js = 200, json = 200, scss = 200, tsx = 200, jsx = 200}
 
     -- Auto format
-    for extension, timeout in pairs(autoFormatOn) do
+    for extension, _ in pairs(autoFormatOn) do
         -- I wonder if this could be done in a single glob pattern
         cmd("autocmd BufWritePre *." .. extension .. " lua vim.lsp.buf.formatting_sync()")
     end
diff --git a/dotfiles/neovim/lua/my/plugins/lualine.lua b/dotfiles/neovim/lua/my/plugins/lualine.lua
new file mode 100644
index 0000000..950ed80
--- /dev/null
+++ b/dotfiles/neovim/lua/my/plugins/lualine.lua
@@ -0,0 +1,12 @@
+local M = {}
+
+function M.setup()
+    require('lualine').setup({
+        theme = "github",
+
+        -- Integration with other plugins
+        extensions = {"nvim-tree"}
+    })
+end
+
+return M
diff --git a/dotfiles/neovim/lua/my/plugins/telescope.lua b/dotfiles/neovim/lua/my/plugins/telescope.lua
index 6550fe9..aa48844 100644
--- a/dotfiles/neovim/lua/my/plugins/telescope.lua
+++ b/dotfiles/neovim/lua/my/plugins/telescope.lua
@@ -13,6 +13,7 @@ local bindings = {
         -- See diagnostics with space + d
         lsp_document_diagnostics = "<space>d",
         lsp_workspace_diagnostics = "<space>wd",
+        lsp_code_actions = "<space>ca",
 
         -- Open a list with all the pickers
         builtin = "<space>t",
diff --git a/modules/applications/neovim.nix b/modules/applications/neovim.nix
index 70a6a20..dd7d8f3 100644
--- a/modules/applications/neovim.nix
+++ b/modules/applications/neovim.nix
@@ -55,6 +55,8 @@ in
         vimtex # latex plugin
         null-ls-nvim # generic language server
         telescope-file-browser-nvim # file creation/deletion using telescope
+        lspkind-nvim # show icons in lsp completion menus
+        symbols-outline-nvim # tree view for symbols in document
 
         # Cmp related stuff. See https://github.com/hrsh7th/nvim-cmp
         cmp-nvim-lsp